2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
32 #include "alListener.h"
36 #include "alAuxEffectSlot.h"
46 #include "backends/base.h"
47 #include "midi/base.h"
50 /************************************************
52 ************************************************/
55 ALCbackendFactory
* (*getFactory
)(void);
56 ALCboolean (*Init
)(BackendFuncs
*);
58 void (*Probe
)(enum DevProbe
);
62 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
63 static struct BackendInfo BackendList
[] = {
64 #ifdef HAVE_PULSEAUDIO
65 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
68 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
71 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
74 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
77 { "solaris", NULL
, alc_solaris_init
, alc_solaris_deinit
, alc_solaris_probe
, EmptyFuncs
},
80 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
83 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
86 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
89 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
92 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
95 { "port", NULL
, alc_pa_init
, alc_pa_deinit
, alc_pa_probe
, EmptyFuncs
},
98 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
101 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
103 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
106 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
110 static struct BackendInfo PlaybackBackend
;
111 static struct BackendInfo CaptureBackend
;
114 /************************************************
115 * Functions, enums, and errors
116 ************************************************/
117 typedef struct ALCfunction
{
118 const ALCchar
*funcName
;
122 typedef struct ALCenums
{
123 const ALCchar
*enumName
;
127 #define DECL(x) { #x, (ALCvoid*)(x) }
128 static const ALCfunction alcFunctions
[] = {
129 DECL(alcCreateContext
),
130 DECL(alcMakeContextCurrent
),
131 DECL(alcProcessContext
),
132 DECL(alcSuspendContext
),
133 DECL(alcDestroyContext
),
134 DECL(alcGetCurrentContext
),
135 DECL(alcGetContextsDevice
),
137 DECL(alcCloseDevice
),
139 DECL(alcIsExtensionPresent
),
140 DECL(alcGetProcAddress
),
141 DECL(alcGetEnumValue
),
143 DECL(alcGetIntegerv
),
144 DECL(alcCaptureOpenDevice
),
145 DECL(alcCaptureCloseDevice
),
146 DECL(alcCaptureStart
),
147 DECL(alcCaptureStop
),
148 DECL(alcCaptureSamples
),
150 DECL(alcSetThreadContext
),
151 DECL(alcGetThreadContext
),
153 DECL(alcLoopbackOpenDeviceSOFT
),
154 DECL(alcIsRenderFormatSupportedSOFT
),
155 DECL(alcRenderSamplesSOFT
),
157 DECL(alcDevicePauseSOFT
),
158 DECL(alcDeviceResumeSOFT
),
160 DECL(alcGetInteger64vSOFT
),
175 DECL(alIsExtensionPresent
),
176 DECL(alGetProcAddress
),
177 DECL(alGetEnumValue
),
184 DECL(alGetListenerf
),
185 DECL(alGetListener3f
),
186 DECL(alGetListenerfv
),
187 DECL(alGetListeneri
),
188 DECL(alGetListener3i
),
189 DECL(alGetListeneriv
),
191 DECL(alDeleteSources
),
207 DECL(alSourceRewindv
),
208 DECL(alSourcePausev
),
211 DECL(alSourceRewind
),
213 DECL(alSourceQueueBuffers
),
214 DECL(alSourceUnqueueBuffers
),
216 DECL(alDeleteBuffers
),
231 DECL(alDopplerFactor
),
232 DECL(alDopplerVelocity
),
233 DECL(alSpeedOfSound
),
234 DECL(alDistanceModel
),
237 DECL(alDeleteFilters
),
248 DECL(alDeleteEffects
),
258 DECL(alGenAuxiliaryEffectSlots
),
259 DECL(alDeleteAuxiliaryEffectSlots
),
260 DECL(alIsAuxiliaryEffectSlot
),
261 DECL(alAuxiliaryEffectSloti
),
262 DECL(alAuxiliaryEffectSlotiv
),
263 DECL(alAuxiliaryEffectSlotf
),
264 DECL(alAuxiliaryEffectSlotfv
),
265 DECL(alGetAuxiliaryEffectSloti
),
266 DECL(alGetAuxiliaryEffectSlotiv
),
267 DECL(alGetAuxiliaryEffectSlotf
),
268 DECL(alGetAuxiliaryEffectSlotfv
),
270 DECL(alBufferSubDataSOFT
),
272 DECL(alBufferSamplesSOFT
),
273 DECL(alBufferSubSamplesSOFT
),
274 DECL(alGetBufferSamplesSOFT
),
275 DECL(alIsBufferFormatSupportedSOFT
),
277 DECL(alDeferUpdatesSOFT
),
278 DECL(alProcessUpdatesSOFT
),
281 DECL(alSource3dSOFT
),
282 DECL(alSourcedvSOFT
),
283 DECL(alGetSourcedSOFT
),
284 DECL(alGetSource3dSOFT
),
285 DECL(alGetSourcedvSOFT
),
286 DECL(alSourcei64SOFT
),
287 DECL(alSource3i64SOFT
),
288 DECL(alSourcei64vSOFT
),
289 DECL(alGetSourcei64SOFT
),
290 DECL(alGetSource3i64SOFT
),
291 DECL(alGetSourcei64vSOFT
),
293 DECL(alGenSoundfontsSOFT
),
294 DECL(alDeleteSoundfontsSOFT
),
295 DECL(alIsSoundfontSOFT
),
296 DECL(alGetSoundfontivSOFT
),
297 DECL(alSoundfontPresetsSOFT
),
298 DECL(alGenPresetsSOFT
),
299 DECL(alDeletePresetsSOFT
),
300 DECL(alIsPresetSOFT
),
302 DECL(alPresetivSOFT
),
303 DECL(alGetPresetivSOFT
),
304 DECL(alPresetFontsoundsSOFT
),
305 DECL(alGenFontsoundsSOFT
),
306 DECL(alDeleteFontsoundsSOFT
),
307 DECL(alIsFontsoundSOFT
),
308 DECL(alFontsoundiSOFT
),
309 DECL(alFontsound2iSOFT
),
310 DECL(alFontsoundivSOFT
),
311 DECL(alGetFontsoundivSOFT
),
312 DECL(alFontsoundModulatoriSOFT
),
313 DECL(alGetFontsoundModulatorivSOFT
),
314 DECL(alMidiSoundfontSOFT
),
315 DECL(alMidiSoundfontvSOFT
),
316 DECL(alMidiEventSOFT
),
317 DECL(alMidiSysExSOFT
),
318 DECL(alMidiPlaySOFT
),
319 DECL(alMidiPauseSOFT
),
320 DECL(alMidiStopSOFT
),
321 DECL(alMidiResetSOFT
),
322 DECL(alMidiGainSOFT
),
323 DECL(alGetInteger64SOFT
),
324 DECL(alGetInteger64vSOFT
),
325 DECL(alLoadSoundfontSOFT
),
331 #define DECL(x) { #x, (x) }
332 static const ALCenums enumeration
[] = {
337 DECL(ALC_MAJOR_VERSION
),
338 DECL(ALC_MINOR_VERSION
),
339 DECL(ALC_ATTRIBUTES_SIZE
),
340 DECL(ALC_ALL_ATTRIBUTES
),
341 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
342 DECL(ALC_DEVICE_SPECIFIER
),
343 DECL(ALC_ALL_DEVICES_SPECIFIER
),
344 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
345 DECL(ALC_EXTENSIONS
),
349 DECL(ALC_MONO_SOURCES
),
350 DECL(ALC_STEREO_SOURCES
),
351 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
352 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
353 DECL(ALC_CAPTURE_SAMPLES
),
356 DECL(ALC_EFX_MAJOR_VERSION
),
357 DECL(ALC_EFX_MINOR_VERSION
),
358 DECL(ALC_MAX_AUXILIARY_SENDS
),
360 DECL(ALC_FORMAT_CHANNELS_SOFT
),
361 DECL(ALC_FORMAT_TYPE_SOFT
),
364 DECL(ALC_STEREO_SOFT
),
366 DECL(ALC_5POINT1_SOFT
),
367 DECL(ALC_6POINT1_SOFT
),
368 DECL(ALC_7POINT1_SOFT
),
371 DECL(ALC_UNSIGNED_BYTE_SOFT
),
372 DECL(ALC_SHORT_SOFT
),
373 DECL(ALC_UNSIGNED_SHORT_SOFT
),
375 DECL(ALC_UNSIGNED_INT_SOFT
),
376 DECL(ALC_FLOAT_SOFT
),
379 DECL(ALC_INVALID_DEVICE
),
380 DECL(ALC_INVALID_CONTEXT
),
381 DECL(ALC_INVALID_ENUM
),
382 DECL(ALC_INVALID_VALUE
),
383 DECL(ALC_OUT_OF_MEMORY
),
391 DECL(AL_SOURCE_RELATIVE
),
392 DECL(AL_CONE_INNER_ANGLE
),
393 DECL(AL_CONE_OUTER_ANGLE
),
403 DECL(AL_ORIENTATION
),
404 DECL(AL_REFERENCE_DISTANCE
),
405 DECL(AL_ROLLOFF_FACTOR
),
406 DECL(AL_CONE_OUTER_GAIN
),
407 DECL(AL_MAX_DISTANCE
),
409 DECL(AL_SAMPLE_OFFSET
),
410 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
411 DECL(AL_BYTE_OFFSET
),
412 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
413 DECL(AL_SOURCE_TYPE
),
416 DECL(AL_UNDETERMINED
),
417 DECL(AL_METERS_PER_UNIT
),
418 DECL(AL_DIRECT_CHANNELS_SOFT
),
420 DECL(AL_DIRECT_FILTER
),
421 DECL(AL_AUXILIARY_SEND_FILTER
),
422 DECL(AL_AIR_ABSORPTION_FACTOR
),
423 DECL(AL_ROOM_ROLLOFF_FACTOR
),
424 DECL(AL_CONE_OUTER_GAINHF
),
425 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
426 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
427 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
429 DECL(AL_SOURCE_STATE
),
435 DECL(AL_BUFFERS_QUEUED
),
436 DECL(AL_BUFFERS_PROCESSED
),
438 DECL(AL_FORMAT_MONO8
),
439 DECL(AL_FORMAT_MONO16
),
440 DECL(AL_FORMAT_MONO_FLOAT32
),
441 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
442 DECL(AL_FORMAT_STEREO8
),
443 DECL(AL_FORMAT_STEREO16
),
444 DECL(AL_FORMAT_STEREO_FLOAT32
),
445 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
446 DECL(AL_FORMAT_MONO_IMA4
),
447 DECL(AL_FORMAT_STEREO_IMA4
),
448 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
449 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
450 DECL(AL_FORMAT_QUAD8_LOKI
),
451 DECL(AL_FORMAT_QUAD16_LOKI
),
452 DECL(AL_FORMAT_QUAD8
),
453 DECL(AL_FORMAT_QUAD16
),
454 DECL(AL_FORMAT_QUAD32
),
455 DECL(AL_FORMAT_51CHN8
),
456 DECL(AL_FORMAT_51CHN16
),
457 DECL(AL_FORMAT_51CHN32
),
458 DECL(AL_FORMAT_61CHN8
),
459 DECL(AL_FORMAT_61CHN16
),
460 DECL(AL_FORMAT_61CHN32
),
461 DECL(AL_FORMAT_71CHN8
),
462 DECL(AL_FORMAT_71CHN16
),
463 DECL(AL_FORMAT_71CHN32
),
464 DECL(AL_FORMAT_REAR8
),
465 DECL(AL_FORMAT_REAR16
),
466 DECL(AL_FORMAT_REAR32
),
467 DECL(AL_FORMAT_MONO_MULAW
),
468 DECL(AL_FORMAT_MONO_MULAW_EXT
),
469 DECL(AL_FORMAT_STEREO_MULAW
),
470 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
471 DECL(AL_FORMAT_QUAD_MULAW
),
472 DECL(AL_FORMAT_51CHN_MULAW
),
473 DECL(AL_FORMAT_61CHN_MULAW
),
474 DECL(AL_FORMAT_71CHN_MULAW
),
475 DECL(AL_FORMAT_REAR_MULAW
),
476 DECL(AL_FORMAT_MONO_ALAW_EXT
),
477 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
480 DECL(AL_MONO16_SOFT
),
481 DECL(AL_MONO32F_SOFT
),
482 DECL(AL_STEREO8_SOFT
),
483 DECL(AL_STEREO16_SOFT
),
484 DECL(AL_STEREO32F_SOFT
),
486 DECL(AL_QUAD16_SOFT
),
487 DECL(AL_QUAD32F_SOFT
),
489 DECL(AL_REAR16_SOFT
),
490 DECL(AL_REAR32F_SOFT
),
491 DECL(AL_5POINT1_8_SOFT
),
492 DECL(AL_5POINT1_16_SOFT
),
493 DECL(AL_5POINT1_32F_SOFT
),
494 DECL(AL_6POINT1_8_SOFT
),
495 DECL(AL_6POINT1_16_SOFT
),
496 DECL(AL_6POINT1_32F_SOFT
),
497 DECL(AL_7POINT1_8_SOFT
),
498 DECL(AL_7POINT1_16_SOFT
),
499 DECL(AL_7POINT1_32F_SOFT
),
502 DECL(AL_STEREO_SOFT
),
505 DECL(AL_5POINT1_SOFT
),
506 DECL(AL_6POINT1_SOFT
),
507 DECL(AL_7POINT1_SOFT
),
510 DECL(AL_UNSIGNED_BYTE_SOFT
),
512 DECL(AL_UNSIGNED_SHORT_SOFT
),
514 DECL(AL_UNSIGNED_INT_SOFT
),
516 DECL(AL_DOUBLE_SOFT
),
518 DECL(AL_UNSIGNED_BYTE3_SOFT
),
524 DECL(AL_INTERNAL_FORMAT_SOFT
),
525 DECL(AL_BYTE_LENGTH_SOFT
),
526 DECL(AL_SAMPLE_LENGTH_SOFT
),
527 DECL(AL_SEC_LENGTH_SOFT
),
528 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
529 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
536 DECL(AL_INVALID_NAME
),
537 DECL(AL_INVALID_ENUM
),
538 DECL(AL_INVALID_VALUE
),
539 DECL(AL_INVALID_OPERATION
),
540 DECL(AL_OUT_OF_MEMORY
),
547 DECL(AL_DOPPLER_FACTOR
),
548 DECL(AL_DOPPLER_VELOCITY
),
549 DECL(AL_DISTANCE_MODEL
),
550 DECL(AL_SPEED_OF_SOUND
),
551 DECL(AL_SOURCE_DISTANCE_MODEL
),
552 DECL(AL_DEFERRED_UPDATES_SOFT
),
554 DECL(AL_INVERSE_DISTANCE
),
555 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
556 DECL(AL_LINEAR_DISTANCE
),
557 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
558 DECL(AL_EXPONENT_DISTANCE
),
559 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
561 DECL(AL_FILTER_TYPE
),
562 DECL(AL_FILTER_NULL
),
563 DECL(AL_FILTER_LOWPASS
),
564 DECL(AL_FILTER_HIGHPASS
),
565 DECL(AL_FILTER_BANDPASS
),
567 DECL(AL_LOWPASS_GAIN
),
568 DECL(AL_LOWPASS_GAINHF
),
570 DECL(AL_HIGHPASS_GAIN
),
571 DECL(AL_HIGHPASS_GAINLF
),
573 DECL(AL_BANDPASS_GAIN
),
574 DECL(AL_BANDPASS_GAINHF
),
575 DECL(AL_BANDPASS_GAINLF
),
577 DECL(AL_EFFECT_TYPE
),
578 DECL(AL_EFFECT_NULL
),
579 DECL(AL_EFFECT_REVERB
),
580 DECL(AL_EFFECT_EAXREVERB
),
581 DECL(AL_EFFECT_CHORUS
),
582 DECL(AL_EFFECT_DISTORTION
),
583 DECL(AL_EFFECT_ECHO
),
584 DECL(AL_EFFECT_FLANGER
),
586 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
587 DECL(AL_EFFECT_VOCAL_MORPHER
),
588 DECL(AL_EFFECT_PITCH_SHIFTER
),
590 DECL(AL_EFFECT_RING_MODULATOR
),
592 DECL(AL_EFFECT_AUTOWAH
),
594 DECL(AL_EFFECT_COMPRESSOR
),
595 DECL(AL_EFFECT_EQUALIZER
),
596 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
597 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
599 DECL(AL_EAXREVERB_DENSITY
),
600 DECL(AL_EAXREVERB_DIFFUSION
),
601 DECL(AL_EAXREVERB_GAIN
),
602 DECL(AL_EAXREVERB_GAINHF
),
603 DECL(AL_EAXREVERB_GAINLF
),
604 DECL(AL_EAXREVERB_DECAY_TIME
),
605 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
606 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
607 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
608 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
609 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
610 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
611 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
612 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
613 DECL(AL_EAXREVERB_ECHO_TIME
),
614 DECL(AL_EAXREVERB_ECHO_DEPTH
),
615 DECL(AL_EAXREVERB_MODULATION_TIME
),
616 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
617 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
618 DECL(AL_EAXREVERB_HFREFERENCE
),
619 DECL(AL_EAXREVERB_LFREFERENCE
),
620 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
621 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
623 DECL(AL_REVERB_DENSITY
),
624 DECL(AL_REVERB_DIFFUSION
),
625 DECL(AL_REVERB_GAIN
),
626 DECL(AL_REVERB_GAINHF
),
627 DECL(AL_REVERB_DECAY_TIME
),
628 DECL(AL_REVERB_DECAY_HFRATIO
),
629 DECL(AL_REVERB_REFLECTIONS_GAIN
),
630 DECL(AL_REVERB_REFLECTIONS_DELAY
),
631 DECL(AL_REVERB_LATE_REVERB_GAIN
),
632 DECL(AL_REVERB_LATE_REVERB_DELAY
),
633 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
634 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
635 DECL(AL_REVERB_DECAY_HFLIMIT
),
637 DECL(AL_CHORUS_WAVEFORM
),
638 DECL(AL_CHORUS_PHASE
),
639 DECL(AL_CHORUS_RATE
),
640 DECL(AL_CHORUS_DEPTH
),
641 DECL(AL_CHORUS_FEEDBACK
),
642 DECL(AL_CHORUS_DELAY
),
644 DECL(AL_DISTORTION_EDGE
),
645 DECL(AL_DISTORTION_GAIN
),
646 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
647 DECL(AL_DISTORTION_EQCENTER
),
648 DECL(AL_DISTORTION_EQBANDWIDTH
),
651 DECL(AL_ECHO_LRDELAY
),
652 DECL(AL_ECHO_DAMPING
),
653 DECL(AL_ECHO_FEEDBACK
),
654 DECL(AL_ECHO_SPREAD
),
656 DECL(AL_FLANGER_WAVEFORM
),
657 DECL(AL_FLANGER_PHASE
),
658 DECL(AL_FLANGER_RATE
),
659 DECL(AL_FLANGER_DEPTH
),
660 DECL(AL_FLANGER_FEEDBACK
),
661 DECL(AL_FLANGER_DELAY
),
663 DECL(AL_RING_MODULATOR_FREQUENCY
),
664 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
665 DECL(AL_RING_MODULATOR_WAVEFORM
),
668 DECL(AL_AUTOWAH_ATTACK_TIME
),
669 DECL(AL_AUTOWAH_PEAK_GAIN
),
670 DECL(AL_AUTOWAH_RELEASE_TIME
),
671 DECL(AL_AUTOWAH_RESONANCE
),
674 DECL(AL_COMPRESSOR_ONOFF
),
676 DECL(AL_EQUALIZER_LOW_GAIN
),
677 DECL(AL_EQUALIZER_LOW_CUTOFF
),
678 DECL(AL_EQUALIZER_MID1_GAIN
),
679 DECL(AL_EQUALIZER_MID1_CENTER
),
680 DECL(AL_EQUALIZER_MID1_WIDTH
),
681 DECL(AL_EQUALIZER_MID2_GAIN
),
682 DECL(AL_EQUALIZER_MID2_CENTER
),
683 DECL(AL_EQUALIZER_MID2_WIDTH
),
684 DECL(AL_EQUALIZER_HIGH_GAIN
),
685 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
687 DECL(AL_DEDICATED_GAIN
),
693 static const ALCchar alcNoError
[] = "No Error";
694 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
695 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
696 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
697 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
698 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
701 /************************************************
703 ************************************************/
705 /* Enumerated device names */
706 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
708 static al_string alcAllDevicesList
;
709 static al_string alcCaptureDeviceList
;
711 /* Default is always the first in the list */
712 static ALCchar
*alcDefaultAllDevicesSpecifier
;
713 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
715 /* Default context extensions */
716 static const ALchar alExtList
[] =
717 "AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 "
718 "AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW "
719 "AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model "
720 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_buffer_samples "
721 "AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates AL_SOFT_direct_channels "
722 "AL_SOFT_loop_points AL_SOFT_MSADPCM AL_SOFT_source_latency "
723 "AL_SOFT_source_length";
725 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
727 /* Thread-local current context */
728 static altss_t LocalContext
;
729 /* Process-wide current context */
730 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
732 /* Mixing thread piority level */
737 enum LogLevel LogLevel
= LogWarning
;
739 enum LogLevel LogLevel
= LogError
;
742 /* Flag to trap ALC device errors */
743 static ALCboolean TrapALCError
= ALC_FALSE
;
745 /* One-time configuration init control */
746 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
748 /* Default effect that applies to sources that don't have an effect on send 0 */
749 static ALeffect DefaultEffect
;
752 /************************************************
754 ************************************************/
755 static const ALCchar alcNoDeviceExtList
[] =
756 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
757 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
758 static const ALCchar alcExtensionList
[] =
759 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
760 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
761 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
762 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
763 static const ALCint alcMajorVersion
= 1;
764 static const ALCint alcMinorVersion
= 1;
766 static const ALCint alcEFXMajorVersion
= 1;
767 static const ALCint alcEFXMinorVersion
= 0;
770 /************************************************
772 ************************************************/
773 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
775 static almtx_t ListLock
;
776 static inline void LockLists(void)
778 int lockret
= almtx_lock(&ListLock
);
779 assert(lockret
== althrd_success
);
781 static inline void UnlockLists(void)
783 int unlockret
= almtx_unlock(&ListLock
);
784 assert(unlockret
== althrd_success
);
787 /************************************************
788 * Library initialization
789 ************************************************/
791 static void alc_init(void);
792 static void alc_deinit(void);
793 static void alc_deinit_safe(void);
795 #ifndef AL_LIBTYPE_STATIC
796 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
800 case DLL_PROCESS_ATTACH
:
801 /* Pin the DLL so we won't get unloaded until the process terminates */
802 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
803 (WCHAR
*)hModule
, &hModule
);
807 case DLL_THREAD_DETACH
:
810 case DLL_PROCESS_DETACH
:
819 #elif defined(_MSC_VER)
820 #pragma section(".CRT$XCU",read)
821 static void alc_constructor(void);
822 static void alc_destructor(void);
823 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
825 static void alc_constructor(void)
827 atexit(alc_destructor
);
831 static void alc_destructor(void)
835 #elif defined(HAVE_GCC_DESTRUCTOR)
836 static void alc_init(void) __attribute__((constructor
));
837 static void alc_deinit(void) __attribute__((destructor
));
839 #error "No static initialization available on this platform!"
842 #elif defined(HAVE_GCC_DESTRUCTOR)
844 static void alc_init(void) __attribute__((constructor
));
845 static void alc_deinit(void) __attribute__((destructor
));
848 #error "No global initialization available on this platform!"
851 static void ReleaseThreadCtx(void *ptr
);
852 static void alc_init(void)
859 AL_STRING_INIT(alcAllDevicesList
);
860 AL_STRING_INIT(alcCaptureDeviceList
);
862 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
863 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
866 str
= getenv("__ALSOFT_REVERSE_Z");
867 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
870 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
871 assert(ret
== althrd_success
);
873 ret
= almtx_init(&ListLock
, almtx_recursive
);
874 assert(ret
== althrd_success
);
879 static void alc_initconfig(void)
881 const char *devs
, *str
;
886 str
= getenv("ALSOFT_LOGLEVEL");
889 long lvl
= strtol(str
, NULL
, 0);
890 if(lvl
>= NoLog
&& lvl
<= LogRef
)
894 str
= getenv("ALSOFT_LOGFILE");
897 FILE *logfile
= al_fopen(str
, "wt");
898 if(logfile
) LogFile
= logfile
;
899 else ERR("Failed to open log file '%s'\n", str
);
904 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
905 for(i
= 1;BackendList
[i
].name
;i
++)
906 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
907 TRACE("Supported backends: %s\n", buf
);
912 #if defined(HAVE_SSE4_1)
913 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE4_1
;
914 #elif defined(HAVE_SSE2)
915 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
916 #elif defined(HAVE_SSE)
917 capfilter
|= CPU_CAP_SSE
;
920 capfilter
|= CPU_CAP_NEON
;
922 if(ConfigValueStr(NULL
, "disable-cpu-exts", &str
))
924 if(strcasecmp(str
, "all") == 0)
929 const char *next
= str
;
933 while(isspace(str
[0]))
935 next
= strchr(str
, ',');
937 if(!str
[0] || str
[0] == ',')
940 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
941 while(len
> 0 && isspace(str
[len
-1]))
943 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
944 capfilter
&= ~CPU_CAP_SSE
;
945 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
946 capfilter
&= ~CPU_CAP_SSE2
;
947 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
948 capfilter
&= ~CPU_CAP_SSE4_1
;
949 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
950 capfilter
&= ~CPU_CAP_NEON
;
952 WARN("Invalid CPU extension \"%s\"\n", str
);
956 FillCPUCaps(capfilter
);
963 ConfigValueInt(NULL
, "rt-prio", &RTPrioLevel
);
965 if(ConfigValueStr(NULL
, "resampler", &str
))
967 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
968 DefaultResampler
= PointResampler
;
969 else if(strcasecmp(str
, "linear") == 0)
970 DefaultResampler
= LinearResampler
;
971 else if(strcasecmp(str
, "cubic") == 0)
972 DefaultResampler
= CubicResampler
;
977 n
= strtol(str
, &end
, 0);
978 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== CubicResampler
))
979 DefaultResampler
= n
;
981 WARN("Invalid resampler: %s\n", str
);
985 str
= getenv("ALSOFT_TRAP_ERROR");
986 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
988 TrapALError
= AL_TRUE
;
989 TrapALCError
= AL_TRUE
;
993 str
= getenv("ALSOFT_TRAP_AL_ERROR");
994 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
995 TrapALError
= AL_TRUE
;
996 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
998 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
999 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1000 TrapALCError
= ALC_TRUE
;
1001 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
1004 if(ConfigValueFloat("reverb", "boost", &valf
))
1005 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1007 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
1009 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1010 ConfigValueStr(NULL
, "drivers", &devs
))
1014 const char *next
= devs
;
1015 int endlist
, delitem
;
1020 while(isspace(devs
[0]))
1022 next
= strchr(devs
, ',');
1024 delitem
= (devs
[0] == '-');
1025 if(devs
[0] == '-') devs
++;
1027 if(!devs
[0] || devs
[0] == ',')
1034 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1035 while(len
> 0 && isspace(devs
[len
-1]))
1037 for(n
= i
;BackendList
[n
].name
;n
++)
1039 if(len
== strlen(BackendList
[n
].name
) &&
1040 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1045 BackendList
[n
] = BackendList
[n
+1];
1047 } while(BackendList
[n
].name
);
1051 struct BackendInfo Bkp
= BackendList
[n
];
1054 BackendList
[n
] = BackendList
[n
-1];
1057 BackendList
[n
] = Bkp
;
1068 BackendList
[i
].name
= NULL
;
1069 BackendList
[i
].getFactory
= NULL
;
1070 BackendList
[i
].Init
= NULL
;
1071 BackendList
[i
].Deinit
= NULL
;
1072 BackendList
[i
].Probe
= NULL
;
1076 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1078 if(BackendList
[i
].getFactory
)
1080 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1081 if(!V0(factory
,init
)())
1083 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1087 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1088 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1090 PlaybackBackend
= BackendList
[i
];
1091 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1093 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1095 CaptureBackend
= BackendList
[i
];
1096 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1102 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1104 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1108 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1109 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1111 PlaybackBackend
= BackendList
[i
];
1112 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1114 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1116 CaptureBackend
= BackendList
[i
];
1117 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1121 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1125 if(ConfigValueStr(NULL
, "excludefx", &str
))
1128 const char *next
= str
;
1132 next
= strchr(str
, ',');
1134 if(!str
[0] || next
== str
)
1137 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1138 for(n
= 0;EffectList
[n
].name
;n
++)
1140 if(len
== strlen(EffectList
[n
].name
) &&
1141 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1142 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1147 InitEffectFactoryMap();
1149 InitEffect(&DefaultEffect
);
1150 str
= getenv("ALSOFT_DEFAULT_REVERB");
1151 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1152 LoadReverbPreset(str
, &DefaultEffect
);
1154 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1157 /************************************************
1158 * Library deinitialization
1159 ************************************************/
1160 static void alc_cleanup(void)
1164 AL_STRING_DEINIT(alcAllDevicesList
);
1165 AL_STRING_DEINIT(alcCaptureDeviceList
);
1167 free(alcDefaultAllDevicesSpecifier
);
1168 alcDefaultAllDevicesSpecifier
= NULL
;
1169 free(alcCaptureDefaultDeviceSpecifier
);
1170 alcCaptureDefaultDeviceSpecifier
= NULL
;
1172 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1177 } while((dev
=dev
->next
) != NULL
);
1178 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1181 DeinitEffectFactoryMap();
1184 static void alc_deinit_safe(void)
1192 almtx_destroy(&ListLock
);
1193 altss_delete(LocalContext
);
1195 if(LogFile
!= stderr
)
1200 static void alc_deinit(void)
1206 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1207 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1209 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1211 if(!BackendList
[i
].getFactory
)
1212 BackendList
[i
].Deinit();
1215 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1216 V0(factory
,deinit
)();
1220 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1221 V0(factory
,deinit
)();
1228 /************************************************
1229 * Device enumeration
1230 ************************************************/
1231 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1236 al_string_clear(list
);
1238 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1240 if(!PlaybackBackend
.getFactory
)
1241 PlaybackBackend
.Probe(type
);
1244 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1245 V(factory
,probe
)(type
);
1248 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1250 if(!CaptureBackend
.getFactory
)
1251 CaptureBackend
.Probe(type
);
1254 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1255 V(factory
,probe
)(type
);
1260 static void ProbeAllDevicesList(void)
1261 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1262 static void ProbeCaptureDeviceList(void)
1263 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1265 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1267 size_t len
= strlen(name
);
1269 al_string_append_range(devnames
, name
, name
+len
+1);
1271 void AppendAllDevicesList(const ALCchar
*name
)
1272 { AppendDevice(name
, &alcAllDevicesList
); }
1273 void AppendCaptureDeviceList(const ALCchar
*name
)
1274 { AppendDevice(name
, &alcCaptureDeviceList
); }
1277 /************************************************
1278 * Device format information
1279 ************************************************/
1280 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1284 case DevFmtByte
: return "Signed Byte";
1285 case DevFmtUByte
: return "Unsigned Byte";
1286 case DevFmtShort
: return "Signed Short";
1287 case DevFmtUShort
: return "Unsigned Short";
1288 case DevFmtInt
: return "Signed Int";
1289 case DevFmtUInt
: return "Unsigned Int";
1290 case DevFmtFloat
: return "Float";
1292 return "(unknown type)";
1294 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1298 case DevFmtMono
: return "Mono";
1299 case DevFmtStereo
: return "Stereo";
1300 case DevFmtQuad
: return "Quadraphonic";
1301 case DevFmtX51
: return "5.1 Surround";
1302 case DevFmtX51Side
: return "5.1 Side";
1303 case DevFmtX61
: return "6.1 Surround";
1304 case DevFmtX71
: return "7.1 Surround";
1306 return "(unknown channels)";
1309 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1310 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1314 case DevFmtByte
: return sizeof(ALbyte
);
1315 case DevFmtUByte
: return sizeof(ALubyte
);
1316 case DevFmtShort
: return sizeof(ALshort
);
1317 case DevFmtUShort
: return sizeof(ALushort
);
1318 case DevFmtInt
: return sizeof(ALint
);
1319 case DevFmtUInt
: return sizeof(ALuint
);
1320 case DevFmtFloat
: return sizeof(ALfloat
);
1324 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1328 case DevFmtMono
: return 1;
1329 case DevFmtStereo
: return 2;
1330 case DevFmtQuad
: return 4;
1331 case DevFmtX51
: return 6;
1332 case DevFmtX51Side
: return 6;
1333 case DevFmtX61
: return 7;
1334 case DevFmtX71
: return 8;
1339 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1340 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1342 static const struct {
1344 enum DevFmtChannels channels
;
1345 enum DevFmtType type
;
1347 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1348 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1349 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1351 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1352 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1353 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1355 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1356 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1357 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1359 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1360 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1361 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1363 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1364 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1365 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1367 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1368 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1369 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1373 for(i
= 0;i
< COUNTOF(list
);i
++)
1375 if(list
[i
].format
== format
)
1377 *chans
= list
[i
].channels
;
1378 *type
= list
[i
].type
;
1386 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1391 case ALC_UNSIGNED_BYTE_SOFT
:
1392 case ALC_SHORT_SOFT
:
1393 case ALC_UNSIGNED_SHORT_SOFT
:
1395 case ALC_UNSIGNED_INT_SOFT
:
1396 case ALC_FLOAT_SOFT
:
1402 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1407 case ALC_STEREO_SOFT
:
1409 case ALC_5POINT1_SOFT
:
1410 case ALC_6POINT1_SOFT
:
1411 case ALC_7POINT1_SOFT
:
1418 /************************************************
1419 * Miscellaneous ALC helpers
1420 ************************************************/
1421 extern inline void LockContext(ALCcontext
*context
);
1422 extern inline void UnlockContext(ALCcontext
*context
);
1424 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1426 return V0(device
->Backend
,getLatency
)();
1429 void ALCdevice_Lock(ALCdevice
*device
)
1431 V0(device
->Backend
,lock
)();
1434 void ALCdevice_Unlock(ALCdevice
*device
)
1436 V0(device
->Backend
,unlock
)();
1440 /* SetDefaultWFXChannelOrder
1442 * Sets the default channel order used by WaveFormatEx.
1444 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1448 for(i
= 0;i
< MaxChannels
;i
++)
1449 device
->ChannelName
[i
] = InvalidChannel
;
1451 switch(device
->FmtChans
)
1453 case DevFmtMono
: device
->ChannelName
[0] = FrontCenter
;
1455 case DevFmtStereo
: device
->ChannelName
[0] = FrontLeft
;
1456 device
->ChannelName
[1] = FrontRight
;
1458 case DevFmtQuad
: device
->ChannelName
[0] = FrontLeft
;
1459 device
->ChannelName
[1] = FrontRight
;
1460 device
->ChannelName
[2] = BackLeft
;
1461 device
->ChannelName
[3] = BackRight
;
1463 case DevFmtX51
: device
->ChannelName
[0] = FrontLeft
;
1464 device
->ChannelName
[1] = FrontRight
;
1465 device
->ChannelName
[2] = FrontCenter
;
1466 device
->ChannelName
[3] = LFE
;
1467 device
->ChannelName
[4] = BackLeft
;
1468 device
->ChannelName
[5] = BackRight
;
1470 case DevFmtX51Side
: device
->ChannelName
[0] = FrontLeft
;
1471 device
->ChannelName
[1] = FrontRight
;
1472 device
->ChannelName
[2] = FrontCenter
;
1473 device
->ChannelName
[3] = LFE
;
1474 device
->ChannelName
[4] = SideLeft
;
1475 device
->ChannelName
[5] = SideRight
;
1477 case DevFmtX61
: device
->ChannelName
[0] = FrontLeft
;
1478 device
->ChannelName
[1] = FrontRight
;
1479 device
->ChannelName
[2] = FrontCenter
;
1480 device
->ChannelName
[3] = LFE
;
1481 device
->ChannelName
[4] = BackCenter
;
1482 device
->ChannelName
[5] = SideLeft
;
1483 device
->ChannelName
[6] = SideRight
;
1485 case DevFmtX71
: device
->ChannelName
[0] = FrontLeft
;
1486 device
->ChannelName
[1] = FrontRight
;
1487 device
->ChannelName
[2] = FrontCenter
;
1488 device
->ChannelName
[3] = LFE
;
1489 device
->ChannelName
[4] = BackLeft
;
1490 device
->ChannelName
[5] = BackRight
;
1491 device
->ChannelName
[6] = SideLeft
;
1492 device
->ChannelName
[7] = SideRight
;
1497 /* SetDefaultChannelOrder
1499 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1501 void SetDefaultChannelOrder(ALCdevice
*device
)
1505 for(i
= 0;i
< MaxChannels
;i
++)
1506 device
->ChannelName
[i
] = InvalidChannel
;
1508 switch(device
->FmtChans
)
1510 case DevFmtX51
: device
->ChannelName
[0] = FrontLeft
;
1511 device
->ChannelName
[1] = FrontRight
;
1512 device
->ChannelName
[2] = BackLeft
;
1513 device
->ChannelName
[3] = BackRight
;
1514 device
->ChannelName
[4] = FrontCenter
;
1515 device
->ChannelName
[5] = LFE
;
1517 case DevFmtX71
: device
->ChannelName
[0] = FrontLeft
;
1518 device
->ChannelName
[1] = FrontRight
;
1519 device
->ChannelName
[2] = BackLeft
;
1520 device
->ChannelName
[3] = BackRight
;
1521 device
->ChannelName
[4] = FrontCenter
;
1522 device
->ChannelName
[5] = LFE
;
1523 device
->ChannelName
[6] = SideLeft
;
1524 device
->ChannelName
[7] = SideRight
;
1527 /* Same as WFX order */
1533 SetDefaultWFXChannelOrder(device
);
1541 * Stores the latest ALC device error
1543 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1548 /* DebugBreak() will cause an exception if there is no debugger */
1549 if(IsDebuggerPresent())
1551 #elif defined(SIGTRAP)
1557 ATOMIC_STORE(&device
->LastError
, errorCode
);
1559 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1565 * Updates the device's base clock time with however many samples have been
1566 * done. This is used so frequency changes on the device don't cause the time
1567 * to jump forward or back.
1569 static inline void UpdateClockBase(ALCdevice
*device
)
1571 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1572 device
->SamplesDone
= 0;
1575 /* UpdateDeviceParams
1577 * Updates device parameters according to the attribute list (caller is
1578 * responsible for holding the list lock).
1580 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1582 ALCcontext
*context
;
1583 enum DevFmtChannels oldChans
;
1584 enum DevFmtType oldType
;
1588 // Check for attributes
1589 if(device
->Type
== Loopback
)
1595 GotAll
= GotFreq
|GotChans
|GotType
1597 ALCuint freq
, numMono
, numStereo
, numSends
, flags
;
1598 enum DevFmtChannels schans
;
1599 enum DevFmtType stype
;
1600 ALCuint attrIdx
= 0;
1605 WARN("Missing attributes for loopback device\n");
1606 return ALC_INVALID_VALUE
;
1609 numMono
= device
->NumMonoSources
;
1610 numStereo
= device
->NumStereoSources
;
1611 numSends
= device
->NumAuxSends
;
1612 schans
= device
->FmtChans
;
1613 stype
= device
->FmtType
;
1614 freq
= device
->Frequency
;
1615 flags
= device
->Flags
;
1617 while(attrList
[attrIdx
])
1619 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1621 ALCint val
= attrList
[attrIdx
+ 1];
1622 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1623 return ALC_INVALID_VALUE
;
1628 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1630 ALCint val
= attrList
[attrIdx
+ 1];
1631 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1632 return ALC_INVALID_VALUE
;
1637 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1639 freq
= attrList
[attrIdx
+ 1];
1640 if(freq
< MIN_OUTPUT_RATE
)
1641 return ALC_INVALID_VALUE
;
1645 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1647 numStereo
= attrList
[attrIdx
+ 1];
1648 if(numStereo
> device
->MaxNoOfSources
)
1649 numStereo
= device
->MaxNoOfSources
;
1651 numMono
= device
->MaxNoOfSources
- numStereo
;
1654 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1655 numSends
= attrList
[attrIdx
+ 1];
1657 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1659 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1660 flags
|= DEVICE_HRTF_REQUEST
;
1662 flags
&= ~DEVICE_HRTF_REQUEST
;
1668 if(gotFmt
!= GotAll
)
1670 WARN("Missing format for loopback device\n");
1671 return ALC_INVALID_VALUE
;
1674 ConfigValueUInt(NULL
, "sends", &numSends
);
1675 numSends
= minu(MAX_SENDS
, numSends
);
1677 if((device
->Flags
&DEVICE_RUNNING
))
1678 V0(device
->Backend
,stop
)();
1679 device
->Flags
= (flags
& ~DEVICE_RUNNING
);
1681 UpdateClockBase(device
);
1683 device
->Frequency
= freq
;
1684 device
->FmtChans
= schans
;
1685 device
->FmtType
= stype
;
1686 device
->NumMonoSources
= numMono
;
1687 device
->NumStereoSources
= numStereo
;
1688 device
->NumAuxSends
= numSends
;
1690 else if(attrList
&& attrList
[0])
1692 ALCuint freq
, numMono
, numStereo
, numSends
;
1693 ALCuint attrIdx
= 0;
1695 /* If a context is already running on the device, stop playback so the
1696 * device attributes can be updated. */
1697 if((device
->Flags
&DEVICE_RUNNING
))
1698 V0(device
->Backend
,stop
)();
1699 device
->Flags
&= ~DEVICE_RUNNING
;
1701 freq
= device
->Frequency
;
1702 numMono
= device
->NumMonoSources
;
1703 numStereo
= device
->NumStereoSources
;
1704 numSends
= device
->NumAuxSends
;
1706 while(attrList
[attrIdx
])
1708 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1710 freq
= attrList
[attrIdx
+ 1];
1711 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1714 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1716 numStereo
= attrList
[attrIdx
+ 1];
1717 if(numStereo
> device
->MaxNoOfSources
)
1718 numStereo
= device
->MaxNoOfSources
;
1720 numMono
= device
->MaxNoOfSources
- numStereo
;
1723 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1724 numSends
= attrList
[attrIdx
+ 1];
1726 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1728 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1729 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1731 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1737 ConfigValueUInt(NULL
, "frequency", &freq
);
1738 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1740 ConfigValueUInt(NULL
, "sends", &numSends
);
1741 numSends
= minu(MAX_SENDS
, numSends
);
1743 UpdateClockBase(device
);
1745 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1747 /* SSE and Neon do best with the update size being a multiple of 4 */
1748 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1749 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1751 device
->Frequency
= freq
;
1752 device
->NumMonoSources
= numMono
;
1753 device
->NumStereoSources
= numStereo
;
1754 device
->NumAuxSends
= numSends
;
1757 if((device
->Flags
&DEVICE_RUNNING
))
1758 return ALC_NO_ERROR
;
1760 UpdateClockBase(device
);
1762 if(device
->Type
!= Loopback
)
1764 bool usehrtf
= !!(device
->Flags
&DEVICE_HRTF_REQUEST
);
1765 if(GetConfigValueBool(NULL
, "hrtf", usehrtf
))
1766 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1768 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1770 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1772 enum DevFmtChannels chans
= device
->FmtChans
;
1773 ALCuint freq
= device
->Frequency
;
1774 if(FindHrtfFormat(&chans
, &freq
))
1776 if(device
->Type
!= Loopback
)
1778 device
->Frequency
= freq
;
1779 device
->FmtChans
= chans
;
1780 device
->Flags
|= DEVICE_CHANNELS_REQUEST
|
1781 DEVICE_FREQUENCY_REQUEST
;
1783 else if(device
->Frequency
!= freq
|| device
->FmtChans
!= chans
)
1785 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1786 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1787 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1792 oldFreq
= device
->Frequency
;
1793 oldChans
= device
->FmtChans
;
1794 oldType
= device
->FmtType
;
1796 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1797 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"",
1798 DevFmtChannelsString(device
->FmtChans
),
1799 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"",
1800 DevFmtTypeString(device
->FmtType
),
1801 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"",
1803 device
->UpdateSize
, device
->NumUpdates
);
1805 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1806 return ALC_INVALID_DEVICE
;
1808 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1810 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1811 DevFmtChannelsString(device
->FmtChans
));
1812 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1814 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1816 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1817 DevFmtTypeString(device
->FmtType
));
1818 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1820 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1822 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1823 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1826 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1827 DevFmtChannelsString(device
->FmtChans
),
1828 DevFmtTypeString(device
->FmtType
), device
->Frequency
,
1829 device
->UpdateSize
, device
->NumUpdates
);
1831 aluInitPanning(device
);
1833 V(device
->Synth
,update
)(device
);
1835 device
->Hrtf
= NULL
;
1836 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1838 device
->Hrtf
= GetHrtf(device
->FmtChans
, device
->Frequency
);
1840 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1842 TRACE("HRTF %s\n", device
->Hrtf
?"enabled":"disabled");
1844 if(!device
->Hrtf
&& device
->Bs2bLevel
> 0 && device
->Bs2bLevel
<= 6)
1848 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
1849 bs2b_clear(device
->Bs2b
);
1851 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
1852 bs2b_set_level(device
->Bs2b
, device
->Bs2bLevel
);
1853 TRACE("BS2B level %d\n", device
->Bs2bLevel
);
1858 device
->Bs2b
= NULL
;
1859 TRACE("BS2B disabled\n");
1862 device
->Flags
&= ~DEVICE_WIDE_STEREO
;
1863 if(device
->Type
!= Loopback
&& !device
->Hrtf
&& GetConfigValueBool(NULL
, "wide-stereo", AL_FALSE
))
1864 device
->Flags
|= DEVICE_WIDE_STEREO
;
1866 if(!device
->Hrtf
&& (device
->UpdateSize
&3))
1868 if((CPUCapFlags
&CPU_CAP_SSE
))
1869 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1870 if((CPUCapFlags
&CPU_CAP_NEON
))
1871 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1874 SetMixerFPUMode(&oldMode
);
1875 ALCdevice_Lock(device
);
1876 context
= ATOMIC_LOAD(&device
->ContextList
);
1881 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
1882 LockUIntMapRead(&context
->EffectSlotMap
);
1883 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
1885 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
1887 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1889 UnlockUIntMapRead(&context
->EffectSlotMap
);
1890 ALCdevice_Unlock(device
);
1891 RestoreFPUMode(&oldMode
);
1892 return ALC_INVALID_DEVICE
;
1894 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
1895 V(slot
->EffectState
,update
)(device
, slot
);
1897 UnlockUIntMapRead(&context
->EffectSlotMap
);
1899 LockUIntMapRead(&context
->SourceMap
);
1900 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1902 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
1903 ALuint s
= device
->NumAuxSends
;
1904 while(s
< MAX_SENDS
)
1906 if(source
->Send
[s
].Slot
)
1907 DecrementRef(&source
->Send
[s
].Slot
->ref
);
1908 source
->Send
[s
].Slot
= NULL
;
1909 source
->Send
[s
].Gain
= 1.0f
;
1910 source
->Send
[s
].GainHF
= 1.0f
;
1913 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
1915 UnlockUIntMapRead(&context
->SourceMap
);
1917 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
1919 ALvoice
*voice
= &context
->Voices
[pos
];
1920 ALsource
*source
= voice
->Source
;
1921 ALuint s
= device
->NumAuxSends
;
1923 while(s
< MAX_SENDS
)
1925 voice
->Send
[s
].Moving
= AL_FALSE
;
1926 voice
->Send
[s
].Counter
= 0;
1932 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
1933 voice
->Update(voice
, source
, context
);
1937 context
= context
->next
;
1939 if(device
->DefaultSlot
)
1941 ALeffectslot
*slot
= device
->DefaultSlot
;
1943 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1945 ALCdevice_Unlock(device
);
1946 RestoreFPUMode(&oldMode
);
1947 return ALC_INVALID_DEVICE
;
1949 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
1950 V(slot
->EffectState
,update
)(device
, slot
);
1952 ALCdevice_Unlock(device
);
1953 RestoreFPUMode(&oldMode
);
1955 if(!(device
->Flags
&DEVICE_PAUSED
))
1957 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
1958 return ALC_INVALID_DEVICE
;
1959 device
->Flags
|= DEVICE_RUNNING
;
1962 return ALC_NO_ERROR
;
1967 * Frees the device structure, and destroys any objects the app failed to
1968 * delete. Called once there's no more references on the device.
1970 static ALCvoid
FreeDevice(ALCdevice
*device
)
1972 TRACE("%p\n", device
);
1974 V0(device
->Backend
,close
)();
1975 DELETE_OBJ(device
->Backend
);
1976 device
->Backend
= NULL
;
1978 DELETE_OBJ(device
->Synth
);
1979 device
->Synth
= NULL
;
1981 if(device
->DefaultSlot
)
1983 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
1984 device
->DefaultSlot
= NULL
;
1988 if(device
->DefaultSfont
)
1989 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
1990 device
->DefaultSfont
= NULL
;
1992 if(device
->BufferMap
.size
> 0)
1994 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
1995 ReleaseALBuffers(device
);
1997 ResetUIntMap(&device
->BufferMap
);
1999 if(device
->EffectMap
.size
> 0)
2001 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2002 ReleaseALEffects(device
);
2004 ResetUIntMap(&device
->EffectMap
);
2006 if(device
->FilterMap
.size
> 0)
2008 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2009 ReleaseALFilters(device
);
2011 ResetUIntMap(&device
->FilterMap
);
2013 if(device
->SfontMap
.size
> 0)
2015 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2016 ReleaseALSoundfonts(device
);
2018 ResetUIntMap(&device
->SfontMap
);
2020 if(device
->PresetMap
.size
> 0)
2022 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2023 ReleaseALPresets(device
);
2025 ResetUIntMap(&device
->PresetMap
);
2027 if(device
->FontsoundMap
.size
> 0)
2029 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2030 ReleaseALFontsounds(device
);
2032 ResetUIntMap(&device
->FontsoundMap
);
2035 device
->Bs2b
= NULL
;
2037 AL_STRING_DEINIT(device
->DeviceName
);
2043 void ALCdevice_IncRef(ALCdevice
*device
)
2046 ref
= IncrementRef(&device
->ref
);
2047 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2050 void ALCdevice_DecRef(ALCdevice
*device
)
2053 ref
= DecrementRef(&device
->ref
);
2054 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2055 if(ref
== 0) FreeDevice(device
);
2060 * Checks if the device handle is valid, and increments its ref count if so.
2062 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2064 ALCdevice
*tmpDevice
;
2070 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2071 while(tmpDevice
&& tmpDevice
!= device
)
2072 tmpDevice
= tmpDevice
->next
;
2075 ALCdevice_IncRef(tmpDevice
);
2083 * Initializes context fields
2085 static ALvoid
InitContext(ALCcontext
*Context
)
2089 //Initialise listener
2090 Context
->Listener
->Gain
= 1.0f
;
2091 Context
->Listener
->MetersPerUnit
= 1.0f
;
2092 Context
->Listener
->Position
[0] = 0.0f
;
2093 Context
->Listener
->Position
[1] = 0.0f
;
2094 Context
->Listener
->Position
[2] = 0.0f
;
2095 Context
->Listener
->Velocity
[0] = 0.0f
;
2096 Context
->Listener
->Velocity
[1] = 0.0f
;
2097 Context
->Listener
->Velocity
[2] = 0.0f
;
2098 Context
->Listener
->Forward
[0] = 0.0f
;
2099 Context
->Listener
->Forward
[1] = 0.0f
;
2100 Context
->Listener
->Forward
[2] = -1.0f
;
2101 Context
->Listener
->Up
[0] = 0.0f
;
2102 Context
->Listener
->Up
[1] = 1.0f
;
2103 Context
->Listener
->Up
[2] = 0.0f
;
2104 for(i
= 0;i
< 4;i
++)
2106 for(j
= 0;j
< 4;j
++)
2107 Context
->Listener
->Params
.Matrix
[i
][j
] = ((i
==j
) ? 1.0f
: 0.0f
);
2109 for(i
= 0;i
< 3;i
++)
2110 Context
->Listener
->Params
.Velocity
[i
] = 0.0f
;
2113 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2114 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2115 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2116 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2119 Context
->DistanceModel
= DefaultDistanceModel
;
2120 Context
->SourceDistanceModel
= AL_FALSE
;
2121 Context
->DopplerFactor
= 1.0f
;
2122 Context
->DopplerVelocity
= 1.0f
;
2123 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2124 Context
->DeferUpdates
= AL_FALSE
;
2126 Context
->ExtensionList
= alExtList
;
2132 * Cleans up the context, and destroys any remaining objects the app failed to
2133 * delete. Called once there's no more references on the context.
2135 static void FreeContext(ALCcontext
*context
)
2137 TRACE("%p\n", context
);
2139 if(context
->SourceMap
.size
> 0)
2141 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2142 ReleaseALSources(context
);
2144 ResetUIntMap(&context
->SourceMap
);
2146 if(context
->EffectSlotMap
.size
> 0)
2148 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2149 ReleaseALAuxiliaryEffectSlots(context
);
2151 ResetUIntMap(&context
->EffectSlotMap
);
2153 al_free(context
->Voices
);
2154 context
->Voices
= NULL
;
2155 context
->VoiceCount
= 0;
2156 context
->MaxVoices
= 0;
2158 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2160 ALCdevice_DecRef(context
->Device
);
2161 context
->Device
= NULL
;
2163 //Invalidate context
2164 memset(context
, 0, sizeof(ALCcontext
));
2170 * Removes the context reference from the given device and removes it from
2171 * being current on the running thread or globally.
2173 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2175 ALCcontext
*nextctx
;
2176 ALCcontext
*origctx
;
2178 if(altss_get(LocalContext
) == context
)
2180 WARN("%p released while current on thread\n", context
);
2181 altss_set(LocalContext
, NULL
);
2182 ALCcontext_DecRef(context
);
2186 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2187 ALCcontext_DecRef(context
);
2189 ALCdevice_Lock(device
);
2191 nextctx
= context
->next
;
2192 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2198 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2200 ALCdevice_Unlock(device
);
2202 ALCcontext_DecRef(context
);
2205 void ALCcontext_IncRef(ALCcontext
*context
)
2208 ref
= IncrementRef(&context
->ref
);
2209 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2212 void ALCcontext_DecRef(ALCcontext
*context
)
2215 ref
= DecrementRef(&context
->ref
);
2216 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2217 if(ref
== 0) FreeContext(context
);
2220 static void ReleaseThreadCtx(void *ptr
)
2222 WARN("%p current for thread being destroyed\n", ptr
);
2223 ALCcontext_DecRef(ptr
);
2228 * Checks that the given context is valid, and increments its reference count.
2230 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2235 dev
= ATOMIC_LOAD(&DeviceList
);
2238 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2243 ALCcontext_IncRef(ctx
);
2259 * Returns the currently active context for this thread, and adds a reference
2260 * without locking it.
2262 ALCcontext
*GetContextRef(void)
2264 ALCcontext
*context
;
2266 context
= altss_get(LocalContext
);
2268 ALCcontext_IncRef(context
);
2272 context
= ATOMIC_LOAD(&GlobalContext
);
2274 ALCcontext_IncRef(context
);
2282 /************************************************
2283 * Standard ALC functions
2284 ************************************************/
2288 * Return last ALC generated error code for the given device
2290 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2294 if(VerifyDevice(device
))
2296 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2297 ALCdevice_DecRef(device
);
2300 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2306 /* alcSuspendContext
2310 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*UNUSED(context
))
2314 /* alcProcessContext
2318 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*UNUSED(context
))
2325 * Returns information about the device, and error strings
2327 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2329 const ALCchar
*value
= NULL
;
2337 case ALC_INVALID_ENUM
:
2338 value
= alcErrInvalidEnum
;
2341 case ALC_INVALID_VALUE
:
2342 value
= alcErrInvalidValue
;
2345 case ALC_INVALID_DEVICE
:
2346 value
= alcErrInvalidDevice
;
2349 case ALC_INVALID_CONTEXT
:
2350 value
= alcErrInvalidContext
;
2353 case ALC_OUT_OF_MEMORY
:
2354 value
= alcErrOutOfMemory
;
2357 case ALC_DEVICE_SPECIFIER
:
2358 value
= alcDefaultName
;
2361 case ALC_ALL_DEVICES_SPECIFIER
:
2362 if(VerifyDevice(Device
))
2364 value
= al_string_get_cstr(Device
->DeviceName
);
2365 ALCdevice_DecRef(Device
);
2369 ProbeAllDevicesList();
2370 value
= al_string_get_cstr(alcAllDevicesList
);
2374 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2375 if(VerifyDevice(Device
))
2377 value
= al_string_get_cstr(Device
->DeviceName
);
2378 ALCdevice_DecRef(Device
);
2382 ProbeCaptureDeviceList();
2383 value
= al_string_get_cstr(alcCaptureDeviceList
);
2387 /* Default devices are always first in the list */
2388 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2389 value
= alcDefaultName
;
2392 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2393 if(al_string_empty(alcAllDevicesList
))
2394 ProbeAllDevicesList();
2396 Device
= VerifyDevice(Device
);
2398 free(alcDefaultAllDevicesSpecifier
);
2399 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2400 if(!alcDefaultAllDevicesSpecifier
)
2401 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2403 value
= alcDefaultAllDevicesSpecifier
;
2404 if(Device
) ALCdevice_DecRef(Device
);
2407 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2408 if(al_string_empty(alcCaptureDeviceList
))
2409 ProbeCaptureDeviceList();
2411 Device
= VerifyDevice(Device
);
2413 free(alcCaptureDefaultDeviceSpecifier
);
2414 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2415 if(!alcCaptureDefaultDeviceSpecifier
)
2416 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2418 value
= alcCaptureDefaultDeviceSpecifier
;
2419 if(Device
) ALCdevice_DecRef(Device
);
2422 case ALC_EXTENSIONS
:
2423 if(!VerifyDevice(Device
))
2424 value
= alcNoDeviceExtList
;
2427 value
= alcExtensionList
;
2428 ALCdevice_DecRef(Device
);
2433 Device
= VerifyDevice(Device
);
2434 alcSetError(Device
, ALC_INVALID_ENUM
);
2435 if(Device
) ALCdevice_DecRef(Device
);
2443 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2447 if(size
<= 0 || values
== NULL
)
2449 alcSetError(device
, ALC_INVALID_VALUE
);
2457 case ALC_MAJOR_VERSION
:
2458 values
[0] = alcMajorVersion
;
2460 case ALC_MINOR_VERSION
:
2461 values
[0] = alcMinorVersion
;
2464 case ALC_ATTRIBUTES_SIZE
:
2465 case ALC_ALL_ATTRIBUTES
:
2469 case ALC_MONO_SOURCES
:
2470 case ALC_STEREO_SOURCES
:
2471 case ALC_CAPTURE_SAMPLES
:
2472 case ALC_FORMAT_CHANNELS_SOFT
:
2473 case ALC_FORMAT_TYPE_SOFT
:
2474 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2478 alcSetError(NULL
, ALC_INVALID_ENUM
);
2484 if(device
->Type
== Capture
)
2488 case ALC_CAPTURE_SAMPLES
:
2489 ALCdevice_Lock(device
);
2490 values
[0] = V0(device
->Backend
,availableSamples
)();
2491 ALCdevice_Unlock(device
);
2495 values
[0] = device
->Connected
;
2499 alcSetError(device
, ALC_INVALID_ENUM
);
2508 case ALC_MAJOR_VERSION
:
2509 values
[0] = alcMajorVersion
;
2512 case ALC_MINOR_VERSION
:
2513 values
[0] = alcMinorVersion
;
2516 case ALC_EFX_MAJOR_VERSION
:
2517 values
[0] = alcEFXMajorVersion
;
2520 case ALC_EFX_MINOR_VERSION
:
2521 values
[0] = alcEFXMinorVersion
;
2524 case ALC_ATTRIBUTES_SIZE
:
2528 case ALC_ALL_ATTRIBUTES
:
2531 alcSetError(device
, ALC_INVALID_VALUE
);
2536 values
[i
++] = ALC_FREQUENCY
;
2537 values
[i
++] = device
->Frequency
;
2539 if(device
->Type
!= Loopback
)
2541 values
[i
++] = ALC_REFRESH
;
2542 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2544 values
[i
++] = ALC_SYNC
;
2545 values
[i
++] = ALC_FALSE
;
2549 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2550 values
[i
++] = device
->FmtChans
;
2552 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2553 values
[i
++] = device
->FmtType
;
2556 values
[i
++] = ALC_MONO_SOURCES
;
2557 values
[i
++] = device
->NumMonoSources
;
2559 values
[i
++] = ALC_STEREO_SOURCES
;
2560 values
[i
++] = device
->NumStereoSources
;
2562 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2563 values
[i
++] = device
->NumAuxSends
;
2565 values
[i
++] = ALC_HRTF_SOFT
;
2566 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2572 values
[0] = device
->Frequency
;
2576 if(device
->Type
== Loopback
)
2578 alcSetError(device
, ALC_INVALID_DEVICE
);
2581 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2585 if(device
->Type
== Loopback
)
2587 alcSetError(device
, ALC_INVALID_DEVICE
);
2590 values
[0] = ALC_FALSE
;
2593 case ALC_FORMAT_CHANNELS_SOFT
:
2594 if(device
->Type
!= Loopback
)
2596 alcSetError(device
, ALC_INVALID_DEVICE
);
2599 values
[0] = device
->FmtChans
;
2602 case ALC_FORMAT_TYPE_SOFT
:
2603 if(device
->Type
!= Loopback
)
2605 alcSetError(device
, ALC_INVALID_DEVICE
);
2608 values
[0] = device
->FmtType
;
2611 case ALC_MONO_SOURCES
:
2612 values
[0] = device
->NumMonoSources
;
2615 case ALC_STEREO_SOURCES
:
2616 values
[0] = device
->NumStereoSources
;
2619 case ALC_MAX_AUXILIARY_SENDS
:
2620 values
[0] = device
->NumAuxSends
;
2624 values
[0] = device
->Connected
;
2628 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2632 alcSetError(device
, ALC_INVALID_ENUM
);
2640 * Returns information about the device and the version of OpenAL
2642 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2644 device
= VerifyDevice(device
);
2645 if(size
<= 0 || values
== NULL
)
2646 alcSetError(device
, ALC_INVALID_VALUE
);
2648 GetIntegerv(device
, param
, size
, values
);
2649 if(device
) ALCdevice_DecRef(device
);
2652 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2657 device
= VerifyDevice(device
);
2658 if(size
<= 0 || values
== NULL
)
2659 alcSetError(device
, ALC_INVALID_VALUE
);
2660 else if(!device
|| device
->Type
== Capture
)
2662 ivals
= malloc(size
* sizeof(ALCint
));
2663 size
= GetIntegerv(device
, pname
, size
, ivals
);
2664 for(i
= 0;i
< size
;i
++)
2665 values
[i
] = ivals
[i
];
2668 else /* render device */
2672 case ALC_ATTRIBUTES_SIZE
:
2676 case ALC_ALL_ATTRIBUTES
:
2678 alcSetError(device
, ALC_INVALID_VALUE
);
2683 V0(device
->Backend
,lock
)();
2684 values
[i
++] = ALC_FREQUENCY
;
2685 values
[i
++] = device
->Frequency
;
2687 if(device
->Type
!= Loopback
)
2689 values
[i
++] = ALC_REFRESH
;
2690 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2692 values
[i
++] = ALC_SYNC
;
2693 values
[i
++] = ALC_FALSE
;
2697 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2698 values
[i
++] = device
->FmtChans
;
2700 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2701 values
[i
++] = device
->FmtType
;
2704 values
[i
++] = ALC_MONO_SOURCES
;
2705 values
[i
++] = device
->NumMonoSources
;
2707 values
[i
++] = ALC_STEREO_SOURCES
;
2708 values
[i
++] = device
->NumStereoSources
;
2710 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2711 values
[i
++] = device
->NumAuxSends
;
2713 values
[i
++] = ALC_HRTF_SOFT
;
2714 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2716 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2717 values
[i
++] = device
->ClockBase
+
2718 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2721 V0(device
->Backend
,unlock
)();
2725 case ALC_DEVICE_CLOCK_SOFT
:
2726 V0(device
->Backend
,lock
)();
2727 *values
= device
->ClockBase
+
2728 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2729 V0(device
->Backend
,unlock
)();
2733 ivals
= malloc(size
* sizeof(ALCint
));
2734 size
= GetIntegerv(device
, pname
, size
, ivals
);
2735 for(i
= 0;i
< size
;i
++)
2736 values
[i
] = ivals
[i
];
2742 ALCdevice_DecRef(device
);
2746 /* alcIsExtensionPresent
2748 * Determines if there is support for a particular extension
2750 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2752 ALCboolean bResult
= ALC_FALSE
;
2754 device
= VerifyDevice(device
);
2757 alcSetError(device
, ALC_INVALID_VALUE
);
2760 size_t len
= strlen(extName
);
2761 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2764 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2765 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2770 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2774 } while(isspace(*ptr
));
2779 ALCdevice_DecRef(device
);
2784 /* alcGetProcAddress
2786 * Retrieves the function address for a particular extension function
2788 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2790 ALCvoid
*ptr
= NULL
;
2794 device
= VerifyDevice(device
);
2795 alcSetError(device
, ALC_INVALID_VALUE
);
2796 if(device
) ALCdevice_DecRef(device
);
2801 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2803 ptr
= alcFunctions
[i
].address
;
2812 * Get the value for a particular ALC enumeration name
2814 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
2820 device
= VerifyDevice(device
);
2821 alcSetError(device
, ALC_INVALID_VALUE
);
2822 if(device
) ALCdevice_DecRef(device
);
2827 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
2829 val
= enumeration
[i
].value
;
2838 * Create and attach a context to the given device.
2840 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
2842 ALCcontext
*ALContext
;
2846 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
2849 alcSetError(device
, ALC_INVALID_DEVICE
);
2850 if(device
) ALCdevice_DecRef(device
);
2854 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
2856 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
2859 alcSetError(device
, err
);
2860 if(err
== ALC_INVALID_DEVICE
)
2862 ALCdevice_Lock(device
);
2863 aluHandleDisconnect(device
);
2864 ALCdevice_Unlock(device
);
2866 ALCdevice_DecRef(device
);
2870 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
2873 InitRef(&ALContext
->ref
, 1);
2874 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
2876 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
2878 ALContext
->VoiceCount
= 0;
2879 ALContext
->MaxVoices
= 256;
2880 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
2882 if(!ALContext
|| !ALContext
->Voices
)
2884 if(!ATOMIC_LOAD(&device
->ContextList
))
2886 V0(device
->Backend
,stop
)();
2887 device
->Flags
&= ~DEVICE_RUNNING
;
2893 al_free(ALContext
->Voices
);
2894 ALContext
->Voices
= NULL
;
2896 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
2902 alcSetError(device
, ALC_OUT_OF_MEMORY
);
2903 ALCdevice_DecRef(device
);
2907 ALContext
->Device
= device
;
2908 ALCdevice_IncRef(device
);
2909 InitContext(ALContext
);
2912 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
2914 ALContext
->next
= head
;
2915 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
2919 ALCdevice_DecRef(device
);
2921 TRACE("Created context %p\n", ALContext
);
2925 /* alcDestroyContext
2927 * Remove a context from its device
2929 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
2934 /* alcGetContextsDevice sets an error for invalid contexts */
2935 Device
= alcGetContextsDevice(context
);
2938 ReleaseContext(context
, Device
);
2939 if(!ATOMIC_LOAD(&Device
->ContextList
))
2941 V0(Device
->Backend
,stop
)();
2942 Device
->Flags
&= ~DEVICE_RUNNING
;
2949 /* alcGetCurrentContext
2951 * Returns the currently active context on the calling thread
2953 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
2955 ALCcontext
*Context
= altss_get(LocalContext
);
2956 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
2960 /* alcGetThreadContext
2962 * Returns the currently active thread-local context
2964 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
2966 return altss_get(LocalContext
);
2970 /* alcMakeContextCurrent
2972 * Makes the given context the active process-wide context, and removes the
2973 * thread-local context for the calling thread.
2975 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
2977 /* context must be valid or NULL */
2978 if(context
&& !(context
=VerifyContext(context
)))
2980 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2983 /* context's reference count is already incremented */
2984 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
2985 if(context
) ALCcontext_DecRef(context
);
2987 if((context
=altss_get(LocalContext
)) != NULL
)
2989 altss_set(LocalContext
, NULL
);
2990 ALCcontext_DecRef(context
);
2996 /* alcSetThreadContext
2998 * Makes the given context the active context for the current thread
3000 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3004 /* context must be valid or NULL */
3005 if(context
&& !(context
=VerifyContext(context
)))
3007 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3010 /* context's reference count is already incremented */
3011 old
= altss_get(LocalContext
);
3012 altss_set(LocalContext
, context
);
3013 if(old
) ALCcontext_DecRef(old
);
3019 /* alcGetContextsDevice
3021 * Returns the device that a particular context is attached to
3023 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3027 if(!(Context
=VerifyContext(Context
)))
3029 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3032 Device
= Context
->Device
;
3033 ALCcontext_DecRef(Context
);
3041 * Opens the named device.
3043 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3051 if(!PlaybackBackend
.name
)
3053 alcSetError(NULL
, ALC_INVALID_VALUE
);
3057 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3060 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3063 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3068 InitRef(&device
->ref
, 1);
3069 device
->Connected
= ALC_TRUE
;
3070 device
->Type
= Playback
;
3071 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3074 device
->Bs2b
= NULL
;
3075 device
->Bs2bLevel
= 0;
3076 AL_STRING_INIT(device
->DeviceName
);
3078 ATOMIC_INIT(&device
->ContextList
, NULL
);
3080 device
->ClockBase
= 0;
3081 device
->SamplesDone
= 0;
3083 device
->MaxNoOfSources
= 256;
3084 device
->AuxiliaryEffectSlotMax
= 4;
3085 device
->NumAuxSends
= MAX_SENDS
;
3087 InitUIntMap(&device
->BufferMap
, ~0);
3088 InitUIntMap(&device
->EffectMap
, ~0);
3089 InitUIntMap(&device
->FilterMap
, ~0);
3090 InitUIntMap(&device
->SfontMap
, ~0);
3091 InitUIntMap(&device
->PresetMap
, ~0);
3092 InitUIntMap(&device
->FontsoundMap
, ~0);
3095 device
->FmtChans
= DevFmtChannelsDefault
;
3096 device
->FmtType
= DevFmtTypeDefault
;
3097 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3098 device
->NumUpdates
= 4;
3099 device
->UpdateSize
= 1024;
3101 if(!PlaybackBackend
.getFactory
)
3102 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3103 ALCbackend_Playback
);
3106 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3107 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3109 if(!device
->Backend
)
3112 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3117 if(ConfigValueStr(NULL
, "channels", &fmt
))
3119 static const struct {
3120 const char name
[16];
3121 enum DevFmtChannels chans
;
3123 { "mono", DevFmtMono
},
3124 { "stereo", DevFmtStereo
},
3125 { "quad", DevFmtQuad
},
3126 { "surround51", DevFmtX51
},
3127 { "surround61", DevFmtX61
},
3128 { "surround71", DevFmtX71
},
3132 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3134 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3136 device
->FmtChans
= chanlist
[i
].chans
;
3137 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3141 if(i
== COUNTOF(chanlist
))
3142 ERR("Unsupported channels: %s\n", fmt
);
3144 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3146 static const struct {
3147 const char name
[16];
3148 enum DevFmtType type
;
3150 { "int8", DevFmtByte
},
3151 { "uint8", DevFmtUByte
},
3152 { "int16", DevFmtShort
},
3153 { "uint16", DevFmtUShort
},
3154 { "int32", DevFmtInt
},
3155 { "uint32", DevFmtUInt
},
3156 { "float32", DevFmtFloat
},
3160 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3162 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3164 device
->FmtType
= typelist
[i
].type
;
3165 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3169 if(i
== COUNTOF(typelist
))
3170 ERR("Unsupported sample-type: %s\n", fmt
);
3172 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3173 if((device
->Flags
&DEVICE_FORMAT_REQUEST
) != DEVICE_FORMAT_REQUEST
&&
3174 ConfigValueStr(NULL
, "format", &fmt
))
3176 static const struct {
3177 const char name
[32];
3178 enum DevFmtChannels channels
;
3179 enum DevFmtType type
;
3181 { "AL_FORMAT_MONO32", DevFmtMono
, DevFmtFloat
},
3182 { "AL_FORMAT_STEREO32", DevFmtStereo
, DevFmtFloat
},
3183 { "AL_FORMAT_QUAD32", DevFmtQuad
, DevFmtFloat
},
3184 { "AL_FORMAT_51CHN32", DevFmtX51
, DevFmtFloat
},
3185 { "AL_FORMAT_61CHN32", DevFmtX61
, DevFmtFloat
},
3186 { "AL_FORMAT_71CHN32", DevFmtX71
, DevFmtFloat
},
3188 { "AL_FORMAT_MONO16", DevFmtMono
, DevFmtShort
},
3189 { "AL_FORMAT_STEREO16", DevFmtStereo
, DevFmtShort
},
3190 { "AL_FORMAT_QUAD16", DevFmtQuad
, DevFmtShort
},
3191 { "AL_FORMAT_51CHN16", DevFmtX51
, DevFmtShort
},
3192 { "AL_FORMAT_61CHN16", DevFmtX61
, DevFmtShort
},
3193 { "AL_FORMAT_71CHN16", DevFmtX71
, DevFmtShort
},
3195 { "AL_FORMAT_MONO8", DevFmtMono
, DevFmtByte
},
3196 { "AL_FORMAT_STEREO8", DevFmtStereo
, DevFmtByte
},
3197 { "AL_FORMAT_QUAD8", DevFmtQuad
, DevFmtByte
},
3198 { "AL_FORMAT_51CHN8", DevFmtX51
, DevFmtByte
},
3199 { "AL_FORMAT_61CHN8", DevFmtX61
, DevFmtByte
},
3200 { "AL_FORMAT_71CHN8", DevFmtX71
, DevFmtByte
}
3204 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3205 for(i
= 0;i
< COUNTOF(formats
);i
++)
3207 if(strcasecmp(fmt
, formats
[i
].name
) == 0)
3209 if(!(device
->Flags
&DEVICE_CHANNELS_REQUEST
))
3210 device
->FmtChans
= formats
[i
].channels
;
3211 if(!(device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
3212 device
->FmtType
= formats
[i
].type
;
3213 device
->Flags
|= DEVICE_FORMAT_REQUEST
;
3217 if(i
== COUNTOF(formats
))
3218 ERR("Unsupported format: %s\n", fmt
);
3220 #undef DEVICE_FORMAT_REQUEST
3222 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3224 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3225 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3226 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3227 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3230 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3231 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3233 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3234 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3235 if((CPUCapFlags
&CPU_CAP_SSE
))
3236 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3238 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3239 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3241 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3242 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3244 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3245 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3247 ConfigValueInt(NULL
, "cf_level", &device
->Bs2bLevel
);
3249 device
->NumStereoSources
= 1;
3250 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3252 device
->Synth
= SynthCreate(device
);
3255 DELETE_OBJ(device
->Backend
);
3257 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3261 // Find a playback device to open
3262 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3264 DELETE_OBJ(device
->Synth
);
3265 DELETE_OBJ(device
->Backend
);
3267 alcSetError(NULL
, err
);
3271 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3273 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3274 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3276 device
->DefaultSlot
= NULL
;
3277 ERR("Failed to initialize the default effect slot\n");
3279 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3281 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3282 device
->DefaultSlot
= NULL
;
3284 ERR("Failed to initialize the default effect\n");
3289 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3291 device
->next
= head
;
3292 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3295 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3301 * Closes the given device.
3303 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3305 ALCdevice
*list
, *origdev
, *nextdev
;
3309 list
= ATOMIC_LOAD(&DeviceList
);
3313 } while((list
=list
->next
) != NULL
);
3314 if(!list
|| list
->Type
== Capture
)
3316 alcSetError(list
, ALC_INVALID_DEVICE
);
3322 nextdev
= device
->next
;
3323 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3328 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3332 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3335 ALCcontext
*next
= ctx
->next
;
3336 WARN("Releasing context %p\n", ctx
);
3337 ReleaseContext(ctx
, device
);
3340 if((device
->Flags
&DEVICE_RUNNING
))
3341 V0(device
->Backend
,stop
)();
3342 device
->Flags
&= ~DEVICE_RUNNING
;
3344 ALCdevice_DecRef(device
);
3350 /************************************************
3351 * ALC capture functions
3352 ************************************************/
3353 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3355 ALCdevice
*device
= NULL
;
3360 if(!CaptureBackend
.name
)
3362 alcSetError(NULL
, ALC_INVALID_VALUE
);
3368 alcSetError(NULL
, ALC_INVALID_VALUE
);
3372 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3375 device
= al_calloc(16, sizeof(ALCdevice
));
3378 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3383 InitRef(&device
->ref
, 1);
3384 device
->Connected
= ALC_TRUE
;
3385 device
->Type
= Capture
;
3387 AL_STRING_INIT(device
->DeviceName
);
3389 InitUIntMap(&device
->BufferMap
, ~0);
3390 InitUIntMap(&device
->EffectMap
, ~0);
3391 InitUIntMap(&device
->FilterMap
, ~0);
3392 InitUIntMap(&device
->SfontMap
, ~0);
3393 InitUIntMap(&device
->PresetMap
, ~0);
3394 InitUIntMap(&device
->FontsoundMap
, ~0);
3396 if(!CaptureBackend
.getFactory
)
3397 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3398 ALCbackend_Capture
);
3401 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3402 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3404 if(!device
->Backend
)
3407 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3411 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3412 device
->Frequency
= frequency
;
3414 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3415 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3418 alcSetError(NULL
, ALC_INVALID_ENUM
);
3422 device
->UpdateSize
= samples
;
3423 device
->NumUpdates
= 1;
3425 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3428 alcSetError(NULL
, err
);
3433 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3435 device
->next
= head
;
3436 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3439 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3443 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3445 ALCdevice
*list
, *next
, *nextdev
;
3448 list
= ATOMIC_LOAD(&DeviceList
);
3452 } while((list
=list
->next
) != NULL
);
3453 if(!list
|| list
->Type
!= Capture
)
3455 alcSetError(list
, ALC_INVALID_DEVICE
);
3461 nextdev
= device
->next
;
3462 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3467 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3471 ALCdevice_DecRef(device
);
3476 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3478 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3479 alcSetError(device
, ALC_INVALID_DEVICE
);
3482 ALCdevice_Lock(device
);
3483 if(device
->Connected
)
3485 if(!(device
->Flags
&DEVICE_RUNNING
))
3486 V0(device
->Backend
,start
)();
3487 device
->Flags
|= DEVICE_RUNNING
;
3489 ALCdevice_Unlock(device
);
3492 if(device
) ALCdevice_DecRef(device
);
3495 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3497 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3498 alcSetError(device
, ALC_INVALID_DEVICE
);
3501 ALCdevice_Lock(device
);
3502 if((device
->Flags
&DEVICE_RUNNING
))
3503 V0(device
->Backend
,stop
)();
3504 device
->Flags
&= ~DEVICE_RUNNING
;
3505 ALCdevice_Unlock(device
);
3508 if(device
) ALCdevice_DecRef(device
);
3511 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3513 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3514 alcSetError(device
, ALC_INVALID_DEVICE
);
3517 ALCenum err
= ALC_INVALID_VALUE
;
3519 ALCdevice_Lock(device
);
3520 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3521 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3522 ALCdevice_Unlock(device
);
3524 if(err
!= ALC_NO_ERROR
)
3525 alcSetError(device
, err
);
3527 if(device
) ALCdevice_DecRef(device
);
3531 /************************************************
3532 * ALC loopback functions
3533 ************************************************/
3535 /* alcLoopbackOpenDeviceSOFT
3537 * Open a loopback device, for manual rendering.
3539 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3541 ALCbackendFactory
*factory
;
3546 /* Make sure the device name, if specified, is us. */
3547 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3549 alcSetError(NULL
, ALC_INVALID_VALUE
);
3553 device
= al_calloc(16, sizeof(ALCdevice
));
3556 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3561 InitRef(&device
->ref
, 1);
3562 device
->Connected
= ALC_TRUE
;
3563 device
->Type
= Loopback
;
3564 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3567 device
->Bs2b
= NULL
;
3568 device
->Bs2bLevel
= 0;
3569 AL_STRING_INIT(device
->DeviceName
);
3571 ATOMIC_INIT(&device
->ContextList
, NULL
);
3573 device
->ClockBase
= 0;
3574 device
->SamplesDone
= 0;
3576 device
->MaxNoOfSources
= 256;
3577 device
->AuxiliaryEffectSlotMax
= 4;
3578 device
->NumAuxSends
= MAX_SENDS
;
3580 InitUIntMap(&device
->BufferMap
, ~0);
3581 InitUIntMap(&device
->EffectMap
, ~0);
3582 InitUIntMap(&device
->FilterMap
, ~0);
3583 InitUIntMap(&device
->SfontMap
, ~0);
3584 InitUIntMap(&device
->PresetMap
, ~0);
3585 InitUIntMap(&device
->FontsoundMap
, ~0);
3587 factory
= ALCloopbackFactory_getFactory();
3588 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3589 if(!device
->Backend
)
3592 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3597 device
->NumUpdates
= 0;
3598 device
->UpdateSize
= 0;
3600 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3601 device
->FmtChans
= DevFmtChannelsDefault
;
3602 device
->FmtType
= DevFmtTypeDefault
;
3604 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3605 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3607 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3608 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3610 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3611 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3613 device
->NumStereoSources
= 1;
3614 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3616 device
->Synth
= SynthCreate(device
);
3619 DELETE_OBJ(device
->Backend
);
3621 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3625 // Open the "backend"
3626 V(device
->Backend
,open
)("Loopback");
3629 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3631 device
->next
= head
;
3632 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3635 TRACE("Created device %p\n", device
);
3639 /* alcIsRenderFormatSupportedSOFT
3641 * Determines if the loopback device supports the given format for rendering.
3643 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3645 ALCboolean ret
= ALC_FALSE
;
3647 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3648 alcSetError(device
, ALC_INVALID_DEVICE
);
3650 alcSetError(device
, ALC_INVALID_VALUE
);
3653 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3654 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3655 freq
>= MIN_OUTPUT_RATE
)
3658 if(device
) ALCdevice_DecRef(device
);
3663 /* alcRenderSamplesSOFT
3665 * Renders some samples into a buffer, using the format last set by the
3666 * attributes given to alcCreateContext.
3668 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3670 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3671 alcSetError(device
, ALC_INVALID_DEVICE
);
3672 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3673 alcSetError(device
, ALC_INVALID_VALUE
);
3675 aluMixData(device
, buffer
, samples
);
3676 if(device
) ALCdevice_DecRef(device
);
3680 /************************************************
3681 * ALC DSP pause/resume functions
3682 ************************************************/
3684 /* alcDevicePauseSOFT
3686 * Pause the DSP to stop audio processing.
3688 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3690 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3691 alcSetError(device
, ALC_INVALID_DEVICE
);
3695 if((device
->Flags
&DEVICE_RUNNING
))
3696 V0(device
->Backend
,stop
)();
3697 device
->Flags
&= ~DEVICE_RUNNING
;
3698 device
->Flags
|= DEVICE_PAUSED
;
3701 if(device
) ALCdevice_DecRef(device
);
3704 /* alcDeviceResumeSOFT
3706 * Resume the DSP to restart audio processing.
3708 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3710 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3711 alcSetError(device
, ALC_INVALID_DEVICE
);
3715 if((device
->Flags
&DEVICE_PAUSED
))
3717 device
->Flags
&= ~DEVICE_PAUSED
;
3718 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3720 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3721 device
->Flags
|= DEVICE_RUNNING
;
3724 alcSetError(device
, ALC_INVALID_DEVICE
);
3725 ALCdevice_Lock(device
);
3726 aluHandleDisconnect(device
);
3727 ALCdevice_Unlock(device
);
3733 if(device
) ALCdevice_DecRef(device
);