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"
45 #include "backends/base.h"
48 /************************************************
50 ************************************************/
53 ALCbackendFactory* (*getFactory)(void);
54 ALCboolean (*Init)(BackendFuncs*);
56 void (*Probe)(enum DevProbe);
60 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
61 static struct BackendInfo BackendList[] = {
63 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
65 #ifdef HAVE_PULSEAUDIO
66 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
69 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
72 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
75 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
78 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
81 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
84 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
87 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
90 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
93 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
96 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
99 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
102 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
104 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
107 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
111 static struct BackendInfo PlaybackBackend;
112 static struct BackendInfo CaptureBackend;
115 /************************************************
116 * Functions, enums, and errors
117 ************************************************/
118 typedef struct ALCfunction {
119 const ALCchar *funcName;
123 typedef struct ALCenums {
124 const ALCchar *enumName;
128 #define DECL(x) { #x, (ALCvoid*)(x) }
129 static const ALCfunction alcFunctions[] = {
130 DECL(alcCreateContext),
131 DECL(alcMakeContextCurrent),
132 DECL(alcProcessContext),
133 DECL(alcSuspendContext),
134 DECL(alcDestroyContext),
135 DECL(alcGetCurrentContext),
136 DECL(alcGetContextsDevice),
138 DECL(alcCloseDevice),
140 DECL(alcIsExtensionPresent),
141 DECL(alcGetProcAddress),
142 DECL(alcGetEnumValue),
144 DECL(alcGetIntegerv),
145 DECL(alcCaptureOpenDevice),
146 DECL(alcCaptureCloseDevice),
147 DECL(alcCaptureStart),
148 DECL(alcCaptureStop),
149 DECL(alcCaptureSamples),
151 DECL(alcSetThreadContext),
152 DECL(alcGetThreadContext),
154 DECL(alcLoopbackOpenDeviceSOFT),
155 DECL(alcIsRenderFormatSupportedSOFT),
156 DECL(alcRenderSamplesSOFT),
158 DECL(alcDevicePauseSOFT),
159 DECL(alcDeviceResumeSOFT),
161 DECL(alcGetStringiSOFT),
162 DECL(alcResetDeviceSOFT),
164 DECL(alcGetInteger64vSOFT),
179 DECL(alIsExtensionPresent),
180 DECL(alGetProcAddress),
181 DECL(alGetEnumValue),
188 DECL(alGetListenerf),
189 DECL(alGetListener3f),
190 DECL(alGetListenerfv),
191 DECL(alGetListeneri),
192 DECL(alGetListener3i),
193 DECL(alGetListeneriv),
195 DECL(alDeleteSources),
211 DECL(alSourceRewindv),
212 DECL(alSourcePausev),
215 DECL(alSourceRewind),
217 DECL(alSourceQueueBuffers),
218 DECL(alSourceUnqueueBuffers),
220 DECL(alDeleteBuffers),
235 DECL(alDopplerFactor),
236 DECL(alDopplerVelocity),
237 DECL(alSpeedOfSound),
238 DECL(alDistanceModel),
241 DECL(alDeleteFilters),
252 DECL(alDeleteEffects),
262 DECL(alGenAuxiliaryEffectSlots),
263 DECL(alDeleteAuxiliaryEffectSlots),
264 DECL(alIsAuxiliaryEffectSlot),
265 DECL(alAuxiliaryEffectSloti),
266 DECL(alAuxiliaryEffectSlotiv),
267 DECL(alAuxiliaryEffectSlotf),
268 DECL(alAuxiliaryEffectSlotfv),
269 DECL(alGetAuxiliaryEffectSloti),
270 DECL(alGetAuxiliaryEffectSlotiv),
271 DECL(alGetAuxiliaryEffectSlotf),
272 DECL(alGetAuxiliaryEffectSlotfv),
274 DECL(alBufferSubDataSOFT),
276 DECL(alBufferSamplesSOFT),
277 DECL(alBufferSubSamplesSOFT),
278 DECL(alGetBufferSamplesSOFT),
279 DECL(alIsBufferFormatSupportedSOFT),
281 DECL(alDeferUpdatesSOFT),
282 DECL(alProcessUpdatesSOFT),
285 DECL(alSource3dSOFT),
286 DECL(alSourcedvSOFT),
287 DECL(alGetSourcedSOFT),
288 DECL(alGetSource3dSOFT),
289 DECL(alGetSourcedvSOFT),
290 DECL(alSourcei64SOFT),
291 DECL(alSource3i64SOFT),
292 DECL(alSourcei64vSOFT),
293 DECL(alGetSourcei64SOFT),
294 DECL(alGetSource3i64SOFT),
295 DECL(alGetSourcei64vSOFT),
301 #define DECL(x) { #x, (x) }
302 static const ALCenums enumeration[] = {
307 DECL(ALC_MAJOR_VERSION),
308 DECL(ALC_MINOR_VERSION),
309 DECL(ALC_ATTRIBUTES_SIZE),
310 DECL(ALC_ALL_ATTRIBUTES),
311 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
312 DECL(ALC_DEVICE_SPECIFIER),
313 DECL(ALC_ALL_DEVICES_SPECIFIER),
314 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
315 DECL(ALC_EXTENSIONS),
319 DECL(ALC_MONO_SOURCES),
320 DECL(ALC_STEREO_SOURCES),
321 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
322 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
323 DECL(ALC_CAPTURE_SAMPLES),
326 DECL(ALC_EFX_MAJOR_VERSION),
327 DECL(ALC_EFX_MINOR_VERSION),
328 DECL(ALC_MAX_AUXILIARY_SENDS),
330 DECL(ALC_FORMAT_CHANNELS_SOFT),
331 DECL(ALC_FORMAT_TYPE_SOFT),
334 DECL(ALC_STEREO_SOFT),
336 DECL(ALC_5POINT1_SOFT),
337 DECL(ALC_6POINT1_SOFT),
338 DECL(ALC_7POINT1_SOFT),
341 DECL(ALC_UNSIGNED_BYTE_SOFT),
342 DECL(ALC_SHORT_SOFT),
343 DECL(ALC_UNSIGNED_SHORT_SOFT),
345 DECL(ALC_UNSIGNED_INT_SOFT),
346 DECL(ALC_FLOAT_SOFT),
349 DECL(ALC_DONT_CARE_SOFT),
350 DECL(ALC_HRTF_STATUS_SOFT),
351 DECL(ALC_HRTF_DISABLED_SOFT),
352 DECL(ALC_HRTF_ENABLED_SOFT),
353 DECL(ALC_HRTF_DENIED_SOFT),
354 DECL(ALC_HRTF_REQUIRED_SOFT),
355 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
356 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
357 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
358 DECL(ALC_HRTF_SPECIFIER_SOFT),
359 DECL(ALC_HRTF_ID_SOFT),
362 DECL(ALC_INVALID_DEVICE),
363 DECL(ALC_INVALID_CONTEXT),
364 DECL(ALC_INVALID_ENUM),
365 DECL(ALC_INVALID_VALUE),
366 DECL(ALC_OUT_OF_MEMORY),
374 DECL(AL_SOURCE_RELATIVE),
375 DECL(AL_CONE_INNER_ANGLE),
376 DECL(AL_CONE_OUTER_ANGLE),
389 DECL(AL_ORIENTATION),
390 DECL(AL_REFERENCE_DISTANCE),
391 DECL(AL_ROLLOFF_FACTOR),
392 DECL(AL_CONE_OUTER_GAIN),
393 DECL(AL_MAX_DISTANCE),
395 DECL(AL_SAMPLE_OFFSET),
396 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
397 DECL(AL_BYTE_OFFSET),
398 DECL(AL_BYTE_RW_OFFSETS_SOFT),
399 DECL(AL_SOURCE_TYPE),
402 DECL(AL_UNDETERMINED),
403 DECL(AL_METERS_PER_UNIT),
404 DECL(AL_LOOP_POINTS_SOFT),
405 DECL(AL_DIRECT_CHANNELS_SOFT),
407 DECL(AL_DIRECT_FILTER),
408 DECL(AL_AUXILIARY_SEND_FILTER),
409 DECL(AL_AIR_ABSORPTION_FACTOR),
410 DECL(AL_ROOM_ROLLOFF_FACTOR),
411 DECL(AL_CONE_OUTER_GAINHF),
412 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
413 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
414 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
416 DECL(AL_SOURCE_STATE),
422 DECL(AL_BUFFERS_QUEUED),
423 DECL(AL_BUFFERS_PROCESSED),
425 DECL(AL_FORMAT_MONO8),
426 DECL(AL_FORMAT_MONO16),
427 DECL(AL_FORMAT_MONO_FLOAT32),
428 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
429 DECL(AL_FORMAT_STEREO8),
430 DECL(AL_FORMAT_STEREO16),
431 DECL(AL_FORMAT_STEREO_FLOAT32),
432 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
433 DECL(AL_FORMAT_MONO_IMA4),
434 DECL(AL_FORMAT_STEREO_IMA4),
435 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
436 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
437 DECL(AL_FORMAT_QUAD8_LOKI),
438 DECL(AL_FORMAT_QUAD16_LOKI),
439 DECL(AL_FORMAT_QUAD8),
440 DECL(AL_FORMAT_QUAD16),
441 DECL(AL_FORMAT_QUAD32),
442 DECL(AL_FORMAT_51CHN8),
443 DECL(AL_FORMAT_51CHN16),
444 DECL(AL_FORMAT_51CHN32),
445 DECL(AL_FORMAT_61CHN8),
446 DECL(AL_FORMAT_61CHN16),
447 DECL(AL_FORMAT_61CHN32),
448 DECL(AL_FORMAT_71CHN8),
449 DECL(AL_FORMAT_71CHN16),
450 DECL(AL_FORMAT_71CHN32),
451 DECL(AL_FORMAT_REAR8),
452 DECL(AL_FORMAT_REAR16),
453 DECL(AL_FORMAT_REAR32),
454 DECL(AL_FORMAT_MONO_MULAW),
455 DECL(AL_FORMAT_MONO_MULAW_EXT),
456 DECL(AL_FORMAT_STEREO_MULAW),
457 DECL(AL_FORMAT_STEREO_MULAW_EXT),
458 DECL(AL_FORMAT_QUAD_MULAW),
459 DECL(AL_FORMAT_51CHN_MULAW),
460 DECL(AL_FORMAT_61CHN_MULAW),
461 DECL(AL_FORMAT_71CHN_MULAW),
462 DECL(AL_FORMAT_REAR_MULAW),
463 DECL(AL_FORMAT_MONO_ALAW_EXT),
464 DECL(AL_FORMAT_STEREO_ALAW_EXT),
467 DECL(AL_MONO16_SOFT),
468 DECL(AL_MONO32F_SOFT),
469 DECL(AL_STEREO8_SOFT),
470 DECL(AL_STEREO16_SOFT),
471 DECL(AL_STEREO32F_SOFT),
473 DECL(AL_QUAD16_SOFT),
474 DECL(AL_QUAD32F_SOFT),
476 DECL(AL_REAR16_SOFT),
477 DECL(AL_REAR32F_SOFT),
478 DECL(AL_5POINT1_8_SOFT),
479 DECL(AL_5POINT1_16_SOFT),
480 DECL(AL_5POINT1_32F_SOFT),
481 DECL(AL_6POINT1_8_SOFT),
482 DECL(AL_6POINT1_16_SOFT),
483 DECL(AL_6POINT1_32F_SOFT),
484 DECL(AL_7POINT1_8_SOFT),
485 DECL(AL_7POINT1_16_SOFT),
486 DECL(AL_7POINT1_32F_SOFT),
487 DECL(AL_FORMAT_BFORMAT2D_8),
488 DECL(AL_FORMAT_BFORMAT2D_16),
489 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
490 DECL(AL_FORMAT_BFORMAT2D_MULAW),
491 DECL(AL_FORMAT_BFORMAT3D_8),
492 DECL(AL_FORMAT_BFORMAT3D_16),
493 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
494 DECL(AL_FORMAT_BFORMAT3D_MULAW),
497 DECL(AL_STEREO_SOFT),
500 DECL(AL_5POINT1_SOFT),
501 DECL(AL_6POINT1_SOFT),
502 DECL(AL_7POINT1_SOFT),
505 DECL(AL_UNSIGNED_BYTE_SOFT),
507 DECL(AL_UNSIGNED_SHORT_SOFT),
509 DECL(AL_UNSIGNED_INT_SOFT),
511 DECL(AL_DOUBLE_SOFT),
513 DECL(AL_UNSIGNED_BYTE3_SOFT),
519 DECL(AL_INTERNAL_FORMAT_SOFT),
520 DECL(AL_BYTE_LENGTH_SOFT),
521 DECL(AL_SAMPLE_LENGTH_SOFT),
522 DECL(AL_SEC_LENGTH_SOFT),
523 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
524 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
531 DECL(AL_INVALID_NAME),
532 DECL(AL_INVALID_ENUM),
533 DECL(AL_INVALID_VALUE),
534 DECL(AL_INVALID_OPERATION),
535 DECL(AL_OUT_OF_MEMORY),
542 DECL(AL_DOPPLER_FACTOR),
543 DECL(AL_DOPPLER_VELOCITY),
544 DECL(AL_DISTANCE_MODEL),
545 DECL(AL_SPEED_OF_SOUND),
546 DECL(AL_SOURCE_DISTANCE_MODEL),
547 DECL(AL_DEFERRED_UPDATES_SOFT),
549 DECL(AL_INVERSE_DISTANCE),
550 DECL(AL_INVERSE_DISTANCE_CLAMPED),
551 DECL(AL_LINEAR_DISTANCE),
552 DECL(AL_LINEAR_DISTANCE_CLAMPED),
553 DECL(AL_EXPONENT_DISTANCE),
554 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
556 DECL(AL_FILTER_TYPE),
557 DECL(AL_FILTER_NULL),
558 DECL(AL_FILTER_LOWPASS),
559 DECL(AL_FILTER_HIGHPASS),
560 DECL(AL_FILTER_BANDPASS),
562 DECL(AL_LOWPASS_GAIN),
563 DECL(AL_LOWPASS_GAINHF),
565 DECL(AL_HIGHPASS_GAIN),
566 DECL(AL_HIGHPASS_GAINLF),
568 DECL(AL_BANDPASS_GAIN),
569 DECL(AL_BANDPASS_GAINHF),
570 DECL(AL_BANDPASS_GAINLF),
572 DECL(AL_EFFECT_TYPE),
573 DECL(AL_EFFECT_NULL),
574 DECL(AL_EFFECT_REVERB),
575 DECL(AL_EFFECT_EAXREVERB),
576 DECL(AL_EFFECT_CHORUS),
577 DECL(AL_EFFECT_DISTORTION),
578 DECL(AL_EFFECT_ECHO),
579 DECL(AL_EFFECT_FLANGER),
581 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
582 DECL(AL_EFFECT_VOCAL_MORPHER),
583 DECL(AL_EFFECT_PITCH_SHIFTER),
585 DECL(AL_EFFECT_RING_MODULATOR),
587 DECL(AL_EFFECT_AUTOWAH),
589 DECL(AL_EFFECT_COMPRESSOR),
590 DECL(AL_EFFECT_EQUALIZER),
591 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
592 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
594 DECL(AL_EAXREVERB_DENSITY),
595 DECL(AL_EAXREVERB_DIFFUSION),
596 DECL(AL_EAXREVERB_GAIN),
597 DECL(AL_EAXREVERB_GAINHF),
598 DECL(AL_EAXREVERB_GAINLF),
599 DECL(AL_EAXREVERB_DECAY_TIME),
600 DECL(AL_EAXREVERB_DECAY_HFRATIO),
601 DECL(AL_EAXREVERB_DECAY_LFRATIO),
602 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
603 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
604 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
605 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
606 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
607 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
608 DECL(AL_EAXREVERB_ECHO_TIME),
609 DECL(AL_EAXREVERB_ECHO_DEPTH),
610 DECL(AL_EAXREVERB_MODULATION_TIME),
611 DECL(AL_EAXREVERB_MODULATION_DEPTH),
612 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
613 DECL(AL_EAXREVERB_HFREFERENCE),
614 DECL(AL_EAXREVERB_LFREFERENCE),
615 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
616 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
618 DECL(AL_REVERB_DENSITY),
619 DECL(AL_REVERB_DIFFUSION),
620 DECL(AL_REVERB_GAIN),
621 DECL(AL_REVERB_GAINHF),
622 DECL(AL_REVERB_DECAY_TIME),
623 DECL(AL_REVERB_DECAY_HFRATIO),
624 DECL(AL_REVERB_REFLECTIONS_GAIN),
625 DECL(AL_REVERB_REFLECTIONS_DELAY),
626 DECL(AL_REVERB_LATE_REVERB_GAIN),
627 DECL(AL_REVERB_LATE_REVERB_DELAY),
628 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
629 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
630 DECL(AL_REVERB_DECAY_HFLIMIT),
632 DECL(AL_CHORUS_WAVEFORM),
633 DECL(AL_CHORUS_PHASE),
634 DECL(AL_CHORUS_RATE),
635 DECL(AL_CHORUS_DEPTH),
636 DECL(AL_CHORUS_FEEDBACK),
637 DECL(AL_CHORUS_DELAY),
639 DECL(AL_DISTORTION_EDGE),
640 DECL(AL_DISTORTION_GAIN),
641 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
642 DECL(AL_DISTORTION_EQCENTER),
643 DECL(AL_DISTORTION_EQBANDWIDTH),
646 DECL(AL_ECHO_LRDELAY),
647 DECL(AL_ECHO_DAMPING),
648 DECL(AL_ECHO_FEEDBACK),
649 DECL(AL_ECHO_SPREAD),
651 DECL(AL_FLANGER_WAVEFORM),
652 DECL(AL_FLANGER_PHASE),
653 DECL(AL_FLANGER_RATE),
654 DECL(AL_FLANGER_DEPTH),
655 DECL(AL_FLANGER_FEEDBACK),
656 DECL(AL_FLANGER_DELAY),
658 DECL(AL_RING_MODULATOR_FREQUENCY),
659 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
660 DECL(AL_RING_MODULATOR_WAVEFORM),
663 DECL(AL_AUTOWAH_ATTACK_TIME),
664 DECL(AL_AUTOWAH_PEAK_GAIN),
665 DECL(AL_AUTOWAH_RELEASE_TIME),
666 DECL(AL_AUTOWAH_RESONANCE),
669 DECL(AL_COMPRESSOR_ONOFF),
671 DECL(AL_EQUALIZER_LOW_GAIN),
672 DECL(AL_EQUALIZER_LOW_CUTOFF),
673 DECL(AL_EQUALIZER_MID1_GAIN),
674 DECL(AL_EQUALIZER_MID1_CENTER),
675 DECL(AL_EQUALIZER_MID1_WIDTH),
676 DECL(AL_EQUALIZER_MID2_GAIN),
677 DECL(AL_EQUALIZER_MID2_CENTER),
678 DECL(AL_EQUALIZER_MID2_WIDTH),
679 DECL(AL_EQUALIZER_HIGH_GAIN),
680 DECL(AL_EQUALIZER_HIGH_CUTOFF),
682 DECL(AL_DEDICATED_GAIN),
688 static const ALCchar alcNoError[] = "No Error";
689 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
690 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
691 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
692 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
693 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
696 /************************************************
698 ************************************************/
700 /* Enumerated device names */
701 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
703 static al_string alcAllDevicesList;
704 static al_string alcCaptureDeviceList;
706 /* Default is always the first in the list */
707 static ALCchar *alcDefaultAllDevicesSpecifier;
708 static ALCchar *alcCaptureDefaultDeviceSpecifier;
710 /* Default context extensions */
711 static const ALchar alExtList[] =
712 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
713 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
714 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
715 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
716 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
717 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
718 "AL_SOFT_source_latency AL_SOFT_source_length";
720 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
722 /* Thread-local current context */
723 static altss_t LocalContext;
724 /* Process-wide current context */
725 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
727 /* Mixing thread piority level */
732 enum LogLevel LogLevel = LogWarning;
734 enum LogLevel LogLevel = LogError;
737 /* Flag to trap ALC device errors */
738 static ALCboolean TrapALCError = ALC_FALSE;
740 /* One-time configuration init control */
741 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
743 /* Default effect that applies to sources that don't have an effect on send 0 */
744 static ALeffect DefaultEffect;
746 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
749 static ALCboolean SuspendDefers = ALC_TRUE;
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_SOFT_HRTF "
762 "ALC_SOFT_loopback 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);
911 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
914 if(strcasecmp(str, "ignore") == 0)
916 SuspendDefers = ALC_FALSE;
917 TRACE("Selected context suspend behavior, \"ignore\"\n");
920 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
924 #if defined(HAVE_SSE4_1)
925 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
926 #elif defined(HAVE_SSE3)
927 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
928 #elif defined(HAVE_SSE2)
929 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
930 #elif defined(HAVE_SSE)
931 capfilter |= CPU_CAP_SSE;
934 capfilter |= CPU_CAP_NEON;
936 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
938 if(strcasecmp(str, "all") == 0)
943 const char *next = str;
947 while(isspace(str[0]))
949 next = strchr(str, ',');
951 if(!str[0] || str[0] == ',')
954 len = (next ? ((size_t)(next-str)) : strlen(str));
955 while(len > 0 && isspace(str[len-1]))
957 if(len == 3 && strncasecmp(str, "sse", len) == 0)
958 capfilter &= ~CPU_CAP_SSE;
959 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
960 capfilter &= ~CPU_CAP_SSE2;
961 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
962 capfilter &= ~CPU_CAP_SSE3;
963 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
964 capfilter &= ~CPU_CAP_SSE4_1;
965 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
966 capfilter &= ~CPU_CAP_NEON;
968 WARN("Invalid CPU extension \"%s\"\n", str);
972 FillCPUCaps(capfilter);
979 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
983 str = getenv("ALSOFT_TRAP_ERROR");
984 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
986 TrapALError = AL_TRUE;
987 TrapALCError = AL_TRUE;
991 str = getenv("ALSOFT_TRAP_AL_ERROR");
992 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
993 TrapALError = AL_TRUE;
994 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
996 str = getenv("ALSOFT_TRAP_ALC_ERROR");
997 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
998 TrapALCError = ALC_TRUE;
999 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1002 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1003 ReverbBoost *= powf(10.0f, valf / 20.0f);
1005 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1007 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1008 ConfigValueStr(NULL, NULL, "drivers", &devs))
1012 const char *next = devs;
1013 int endlist, delitem;
1018 while(isspace(devs[0]))
1020 next = strchr(devs, ',');
1022 delitem = (devs[0] == '-');
1023 if(devs[0] == '-') devs++;
1025 if(!devs[0] || devs[0] == ',')
1032 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1033 while(len > 0 && isspace(devs[len-1]))
1035 for(n = i;BackendList[n].name;n++)
1037 if(len == strlen(BackendList[n].name) &&
1038 strncmp(BackendList[n].name, devs, len) == 0)
1043 BackendList[n] = BackendList[n+1];
1045 } while(BackendList[n].name);
1049 struct BackendInfo Bkp = BackendList[n];
1052 BackendList[n] = BackendList[n-1];
1055 BackendList[n] = Bkp;
1066 BackendList[i].name = NULL;
1067 BackendList[i].getFactory = NULL;
1068 BackendList[i].Init = NULL;
1069 BackendList[i].Deinit = NULL;
1070 BackendList[i].Probe = NULL;
1074 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1076 if(BackendList[i].getFactory)
1078 ALCbackendFactory *factory = BackendList[i].getFactory();
1079 if(!V0(factory,init)())
1081 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1085 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1086 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1088 PlaybackBackend = BackendList[i];
1089 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1091 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1093 CaptureBackend = BackendList[i];
1094 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1100 if(!BackendList[i].Init(&BackendList[i].Funcs))
1102 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1106 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1107 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1109 PlaybackBackend = BackendList[i];
1110 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1112 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1114 CaptureBackend = BackendList[i];
1115 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1119 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1123 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1126 const char *next = str;
1130 next = strchr(str, ',');
1132 if(!str[0] || next == str)
1135 len = (next ? ((size_t)(next-str)) : strlen(str));
1136 for(n = 0;EffectList[n].name;n++)
1138 if(len == strlen(EffectList[n].name) &&
1139 strncmp(EffectList[n].name, str, len) == 0)
1140 DisabledEffects[EffectList[n].type] = AL_TRUE;
1145 InitEffectFactoryMap();
1147 InitEffect(&DefaultEffect);
1148 str = getenv("ALSOFT_DEFAULT_REVERB");
1149 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1150 LoadReverbPreset(str, &DefaultEffect);
1152 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1155 /************************************************
1156 * Library deinitialization
1157 ************************************************/
1158 static void alc_cleanup(void)
1162 AL_STRING_DEINIT(alcAllDevicesList);
1163 AL_STRING_DEINIT(alcCaptureDeviceList);
1165 free(alcDefaultAllDevicesSpecifier);
1166 alcDefaultAllDevicesSpecifier = NULL;
1167 free(alcCaptureDefaultDeviceSpecifier);
1168 alcCaptureDefaultDeviceSpecifier = NULL;
1170 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1175 } while((dev=dev->next) != NULL);
1176 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1179 DeinitEffectFactoryMap();
1182 static void alc_deinit_safe(void)
1190 almtx_destroy(&ListLock);
1191 altss_delete(LocalContext);
1193 if(LogFile != stderr)
1198 static void alc_deinit(void)
1204 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1205 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1207 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1209 if(!BackendList[i].getFactory)
1210 BackendList[i].Deinit();
1213 ALCbackendFactory *factory = BackendList[i].getFactory();
1214 V0(factory,deinit)();
1218 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1219 V0(factory,deinit)();
1226 /************************************************
1227 * Device enumeration
1228 ************************************************/
1229 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1234 al_string_clear(list);
1236 if(!backendinfo->getFactory)
1237 backendinfo->Probe(type);
1240 ALCbackendFactory *factory = backendinfo->getFactory();
1241 V(factory,probe)(type);
1246 static void ProbeAllDevicesList(void)
1247 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1248 static void ProbeCaptureDeviceList(void)
1249 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1251 static void AppendDevice(const ALCchar *name, al_string *devnames)
1253 size_t len = strlen(name);
1255 al_string_append_range(devnames, name, name+len+1);
1257 void AppendAllDevicesList(const ALCchar *name)
1258 { AppendDevice(name, &alcAllDevicesList); }
1259 void AppendCaptureDeviceList(const ALCchar *name)
1260 { AppendDevice(name, &alcCaptureDeviceList); }
1263 /************************************************
1264 * Device format information
1265 ************************************************/
1266 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1270 case DevFmtByte: return "Signed Byte";
1271 case DevFmtUByte: return "Unsigned Byte";
1272 case DevFmtShort: return "Signed Short";
1273 case DevFmtUShort: return "Unsigned Short";
1274 case DevFmtInt: return "Signed Int";
1275 case DevFmtUInt: return "Unsigned Int";
1276 case DevFmtFloat: return "Float";
1278 return "(unknown type)";
1280 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1284 case DevFmtMono: return "Mono";
1285 case DevFmtStereo: return "Stereo";
1286 case DevFmtQuad: return "Quadraphonic";
1287 case DevFmtX51: return "5.1 Surround";
1288 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1289 case DevFmtX61: return "6.1 Surround";
1290 case DevFmtX71: return "7.1 Surround";
1291 case DevFmtBFormat3D: return "B-Format 3D";
1293 return "(unknown channels)";
1296 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1297 ALuint BytesFromDevFmt(enum DevFmtType type)
1301 case DevFmtByte: return sizeof(ALbyte);
1302 case DevFmtUByte: return sizeof(ALubyte);
1303 case DevFmtShort: return sizeof(ALshort);
1304 case DevFmtUShort: return sizeof(ALushort);
1305 case DevFmtInt: return sizeof(ALint);
1306 case DevFmtUInt: return sizeof(ALuint);
1307 case DevFmtFloat: return sizeof(ALfloat);
1311 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1315 case DevFmtMono: return 1;
1316 case DevFmtStereo: return 2;
1317 case DevFmtQuad: return 4;
1318 case DevFmtX51: return 6;
1319 case DevFmtX51Rear: return 6;
1320 case DevFmtX61: return 7;
1321 case DevFmtX71: return 8;
1322 case DevFmtBFormat3D: return 4;
1327 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1328 enum DevFmtChannels *chans, enum DevFmtType *type)
1330 static const struct {
1332 enum DevFmtChannels channels;
1333 enum DevFmtType type;
1335 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1336 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1337 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1339 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1340 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1341 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1343 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1344 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1345 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1347 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1348 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1349 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1351 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1352 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1353 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1355 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1356 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1357 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1361 for(i = 0;i < COUNTOF(list);i++)
1363 if(list[i].format == format)
1365 *chans = list[i].channels;
1366 *type = list[i].type;
1374 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1379 case ALC_UNSIGNED_BYTE_SOFT:
1380 case ALC_SHORT_SOFT:
1381 case ALC_UNSIGNED_SHORT_SOFT:
1383 case ALC_UNSIGNED_INT_SOFT:
1384 case ALC_FLOAT_SOFT:
1390 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1395 case ALC_STEREO_SOFT:
1397 case ALC_5POINT1_SOFT:
1398 case ALC_6POINT1_SOFT:
1399 case ALC_7POINT1_SOFT:
1406 /************************************************
1407 * Miscellaneous ALC helpers
1408 ************************************************/
1409 enum HrtfRequestMode {
1415 extern inline void LockContext(ALCcontext *context);
1416 extern inline void UnlockContext(ALCcontext *context);
1418 void ALCdevice_Lock(ALCdevice *device)
1420 V0(device->Backend,lock)();
1423 void ALCdevice_Unlock(ALCdevice *device)
1425 V0(device->Backend,unlock)();
1429 /* SetDefaultWFXChannelOrder
1431 * Sets the default channel order used by WaveFormatEx.
1433 void SetDefaultWFXChannelOrder(ALCdevice *device)
1437 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1438 device->ChannelName[i] = InvalidChannel;
1440 switch(device->FmtChans)
1443 device->ChannelName[0] = FrontCenter;
1446 device->ChannelName[0] = FrontLeft;
1447 device->ChannelName[1] = FrontRight;
1450 device->ChannelName[0] = FrontLeft;
1451 device->ChannelName[1] = FrontRight;
1452 device->ChannelName[2] = BackLeft;
1453 device->ChannelName[3] = BackRight;
1456 device->ChannelName[0] = FrontLeft;
1457 device->ChannelName[1] = FrontRight;
1458 device->ChannelName[2] = FrontCenter;
1459 device->ChannelName[3] = LFE;
1460 device->ChannelName[4] = SideLeft;
1461 device->ChannelName[5] = SideRight;
1464 device->ChannelName[0] = FrontLeft;
1465 device->ChannelName[1] = FrontRight;
1466 device->ChannelName[2] = FrontCenter;
1467 device->ChannelName[3] = LFE;
1468 device->ChannelName[4] = BackLeft;
1469 device->ChannelName[5] = BackRight;
1472 device->ChannelName[0] = FrontLeft;
1473 device->ChannelName[1] = FrontRight;
1474 device->ChannelName[2] = FrontCenter;
1475 device->ChannelName[3] = LFE;
1476 device->ChannelName[4] = BackCenter;
1477 device->ChannelName[5] = SideLeft;
1478 device->ChannelName[6] = SideRight;
1481 device->ChannelName[0] = FrontLeft;
1482 device->ChannelName[1] = FrontRight;
1483 device->ChannelName[2] = FrontCenter;
1484 device->ChannelName[3] = LFE;
1485 device->ChannelName[4] = BackLeft;
1486 device->ChannelName[5] = BackRight;
1487 device->ChannelName[6] = SideLeft;
1488 device->ChannelName[7] = SideRight;
1490 case DevFmtBFormat3D:
1491 device->ChannelName[0] = BFormatW;
1492 device->ChannelName[1] = BFormatX;
1493 device->ChannelName[2] = BFormatY;
1494 device->ChannelName[3] = BFormatZ;
1499 /* SetDefaultChannelOrder
1501 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1503 void SetDefaultChannelOrder(ALCdevice *device)
1507 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1508 device->ChannelName[i] = InvalidChannel;
1510 switch(device->FmtChans)
1513 device->ChannelName[0] = FrontLeft;
1514 device->ChannelName[1] = FrontRight;
1515 device->ChannelName[2] = BackLeft;
1516 device->ChannelName[3] = BackRight;
1517 device->ChannelName[4] = FrontCenter;
1518 device->ChannelName[5] = LFE;
1521 device->ChannelName[0] = FrontLeft;
1522 device->ChannelName[1] = FrontRight;
1523 device->ChannelName[2] = BackLeft;
1524 device->ChannelName[3] = BackRight;
1525 device->ChannelName[4] = FrontCenter;
1526 device->ChannelName[5] = LFE;
1527 device->ChannelName[6] = SideLeft;
1528 device->ChannelName[7] = SideRight;
1531 /* Same as WFX order */
1537 case DevFmtBFormat3D:
1538 SetDefaultWFXChannelOrder(device);
1543 extern inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan);
1546 /* ALCcontext_DeferUpdates
1548 * Defers/suspends updates for the given context's listener and sources. This
1549 * does *NOT* stop mixing, but rather prevents certain property changes from
1552 void ALCcontext_DeferUpdates(ALCcontext *context)
1554 ALCdevice *device = context->Device;
1557 SetMixerFPUMode(&oldMode);
1559 V0(device->Backend,lock)();
1560 if(!context->DeferUpdates)
1562 context->DeferUpdates = AL_TRUE;
1564 /* Make sure all pending updates are performed */
1565 UpdateContextSources(context);
1566 #define UPDATE_SLOT(iter) do { \
1567 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1568 V((*iter)->EffectState,update)(device, *iter); \
1570 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1573 V0(device->Backend,unlock)();
1575 RestoreFPUMode(&oldMode);
1578 /* ALCcontext_ProcessUpdates
1580 * Resumes update processing after being deferred.
1582 void ALCcontext_ProcessUpdates(ALCcontext *context)
1584 ALCdevice *device = context->Device;
1586 V0(device->Backend,lock)();
1587 if(context->DeferUpdates)
1591 context->DeferUpdates = AL_FALSE;
1593 LockUIntMapRead(&context->SourceMap);
1594 for(pos = 0;pos < context->SourceMap.size;pos++)
1596 ALsource *Source = context->SourceMap.array[pos].value;
1599 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1600 Source->Offset >= 0.0)
1602 WriteLock(&Source->queue_lock);
1603 ApplyOffset(Source);
1604 WriteUnlock(&Source->queue_lock);
1607 new_state = Source->new_state;
1608 Source->new_state = AL_NONE;
1610 SetSourceState(Source, context, new_state);
1612 UnlockUIntMapRead(&context->SourceMap);
1614 V0(device->Backend,unlock)();
1620 * Stores the latest ALC device error
1622 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1627 /* DebugBreak() will cause an exception if there is no debugger */
1628 if(IsDebuggerPresent())
1630 #elif defined(SIGTRAP)
1636 ATOMIC_STORE(&device->LastError, errorCode);
1638 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1644 * Updates the device's base clock time with however many samples have been
1645 * done. This is used so frequency changes on the device don't cause the time
1646 * to jump forward or back.
1648 static inline void UpdateClockBase(ALCdevice *device)
1650 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1651 device->SamplesDone = 0;
1654 /* UpdateDeviceParams
1656 * Updates device parameters according to the attribute list (caller is
1657 * responsible for holding the list lock).
1659 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1661 ALCcontext *context;
1662 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1663 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1664 enum DevFmtChannels oldChans;
1665 enum DevFmtType oldType;
1668 ALCsizei hrtf_id = -1;
1671 // Check for attributes
1672 if(device->Type == Loopback)
1678 GotAll = GotFreq|GotChans|GotType
1680 ALCuint freq, numMono, numStereo, numSends;
1681 enum DevFmtChannels schans;
1682 enum DevFmtType stype;
1683 ALCuint attrIdx = 0;
1688 WARN("Missing attributes for loopback device\n");
1689 return ALC_INVALID_VALUE;
1692 numMono = device->NumMonoSources;
1693 numStereo = device->NumStereoSources;
1694 numSends = device->NumAuxSends;
1695 schans = device->FmtChans;
1696 stype = device->FmtType;
1697 freq = device->Frequency;
1699 while(attrList[attrIdx])
1701 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1703 ALCint val = attrList[attrIdx + 1];
1704 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1705 return ALC_INVALID_VALUE;
1710 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1712 ALCint val = attrList[attrIdx + 1];
1713 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1714 return ALC_INVALID_VALUE;
1719 if(attrList[attrIdx] == ALC_FREQUENCY)
1721 freq = attrList[attrIdx + 1];
1722 if(freq < MIN_OUTPUT_RATE)
1723 return ALC_INVALID_VALUE;
1727 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1729 numStereo = attrList[attrIdx + 1];
1730 if(numStereo > device->MaxNoOfSources)
1731 numStereo = device->MaxNoOfSources;
1733 numMono = device->MaxNoOfSources - numStereo;
1736 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1737 numSends = attrList[attrIdx + 1];
1739 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1741 if(attrList[attrIdx + 1] == ALC_FALSE)
1742 hrtf_appreq = Hrtf_Disable;
1743 else if(attrList[attrIdx + 1] == ALC_TRUE)
1744 hrtf_appreq = Hrtf_Enable;
1746 hrtf_appreq = Hrtf_Default;
1749 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1750 hrtf_id = attrList[attrIdx + 1];
1755 if(gotFmt != GotAll)
1757 WARN("Missing format for loopback device\n");
1758 return ALC_INVALID_VALUE;
1761 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1762 numSends = minu(MAX_SENDS, numSends);
1764 if((device->Flags&DEVICE_RUNNING))
1765 V0(device->Backend,stop)();
1766 device->Flags &= ~DEVICE_RUNNING;
1768 UpdateClockBase(device);
1770 device->Frequency = freq;
1771 device->FmtChans = schans;
1772 device->FmtType = stype;
1773 device->NumMonoSources = numMono;
1774 device->NumStereoSources = numStereo;
1775 device->NumAuxSends = numSends;
1777 else if(attrList && attrList[0])
1779 ALCuint freq, numMono, numStereo, numSends;
1780 ALCuint attrIdx = 0;
1782 /* If a context is already running on the device, stop playback so the
1783 * device attributes can be updated. */
1784 if((device->Flags&DEVICE_RUNNING))
1785 V0(device->Backend,stop)();
1786 device->Flags &= ~DEVICE_RUNNING;
1788 freq = device->Frequency;
1789 numMono = device->NumMonoSources;
1790 numStereo = device->NumStereoSources;
1791 numSends = device->NumAuxSends;
1793 while(attrList[attrIdx])
1795 if(attrList[attrIdx] == ALC_FREQUENCY)
1797 freq = attrList[attrIdx + 1];
1798 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1801 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1803 numStereo = attrList[attrIdx + 1];
1804 if(numStereo > device->MaxNoOfSources)
1805 numStereo = device->MaxNoOfSources;
1807 numMono = device->MaxNoOfSources - numStereo;
1810 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1811 numSends = attrList[attrIdx + 1];
1813 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1815 if(attrList[attrIdx + 1] == ALC_FALSE)
1816 hrtf_appreq = Hrtf_Disable;
1817 else if(attrList[attrIdx + 1] == ALC_TRUE)
1818 hrtf_appreq = Hrtf_Enable;
1820 hrtf_appreq = Hrtf_Default;
1823 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1824 hrtf_id = attrList[attrIdx + 1];
1829 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1830 freq = maxu(freq, MIN_OUTPUT_RATE);
1832 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1833 numSends = minu(MAX_SENDS, numSends);
1835 UpdateClockBase(device);
1837 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1839 /* SSE and Neon do best with the update size being a multiple of 4 */
1840 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1841 device->UpdateSize = (device->UpdateSize+3)&~3;
1843 device->Frequency = freq;
1844 device->NumMonoSources = numMono;
1845 device->NumStereoSources = numStereo;
1846 device->NumAuxSends = numSends;
1849 if((device->Flags&DEVICE_RUNNING))
1850 return ALC_NO_ERROR;
1852 al_free(device->DryBuffer);
1853 device->DryBuffer = NULL;
1855 UpdateClockBase(device);
1857 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1858 if(device->Type != Loopback)
1861 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1863 if(strcasecmp(hrtf, "true") == 0)
1864 hrtf_userreq = Hrtf_Enable;
1865 else if(strcasecmp(hrtf, "false") == 0)
1866 hrtf_userreq = Hrtf_Disable;
1867 else if(strcasecmp(hrtf, "auto") != 0)
1868 ERR("Unexpected hrtf value: %s\n", hrtf);
1871 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1873 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1875 VECTOR_DEINIT(device->Hrtf_List);
1876 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1878 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1880 device->FmtChans = DevFmtStereo;
1881 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1882 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1884 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1885 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1889 hrtf_userreq = hrtf_appreq = Hrtf_Default;
1890 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1894 else if(hrtf_appreq == Hrtf_Enable)
1897 /* Loopback device. We don't need to match to a specific HRTF entry
1898 * here. If the requested ID matches, we'll pick that later, if not,
1899 * we'll try to auto-select one anyway. */
1900 if(device->FmtChans != DevFmtStereo)
1901 i = VECTOR_SIZE(device->Hrtf_List);
1904 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1906 VECTOR_DEINIT(device->Hrtf_List);
1907 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1909 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1911 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1912 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1916 if(i == VECTOR_SIZE(device->Hrtf_List))
1918 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1919 DevFmtChannelsString(device->FmtChans), device->Frequency);
1920 hrtf_appreq = Hrtf_Default;
1921 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1925 oldFreq = device->Frequency;
1926 oldChans = device->FmtChans;
1927 oldType = device->FmtType;
1929 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1930 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1931 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1932 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1933 device->UpdateSize, device->NumUpdates
1936 if(V0(device->Backend,reset)() == ALC_FALSE)
1937 return ALC_INVALID_DEVICE;
1939 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1941 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1942 DevFmtChannelsString(device->FmtChans));
1943 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1945 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1947 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1948 DevFmtTypeString(device->FmtType));
1949 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1951 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1953 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1954 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1957 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1958 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1959 device->Frequency, device->UpdateSize, device->NumUpdates
1962 if((device->UpdateSize&3) != 0)
1964 if((CPUCapFlags&CPU_CAP_SSE))
1965 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1966 if((CPUCapFlags&CPU_CAP_NEON))
1967 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1970 device->Hrtf = NULL;
1971 device->Hrtf_Mode = DisabledHrtf;
1972 al_string_clear(&device->Hrtf_Name);
1973 if(device->FmtChans != DevFmtStereo)
1975 if(hrtf_appreq == Hrtf_Enable)
1976 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1979 device->Bs2b = NULL;
1983 bool headphones = device->IsHeadphones;
1984 enum HrtfMode hrtf_mode = FullHrtf;
1985 ALCenum hrtf_status = device->Hrtf_Status;
1990 if(device->Type != Loopback)
1992 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
1994 if(strcasecmp(mode, "headphones") == 0)
1996 else if(strcasecmp(mode, "speakers") == 0)
1998 else if(strcasecmp(mode, "auto") != 0)
1999 ERR("Unexpected stereo-mode: %s\n", mode);
2002 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
2004 if(strcasecmp(mode, "full") == 0)
2005 hrtf_mode = FullHrtf;
2006 else if(strcasecmp(mode, "basic") == 0)
2007 hrtf_mode = BasicHrtf;
2009 ERR("Unexpected hrtf-mode: %s\n", mode);
2014 if(hrtf_userreq == Hrtf_Default)
2016 usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
2017 (hrtf_appreq == Hrtf_Enable);
2018 if(headphones && hrtf_appreq != Hrtf_Disable)
2019 hrtf_status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
2021 hrtf_status = ALC_HRTF_ENABLED_SOFT;
2025 usehrtf = (hrtf_userreq == Hrtf_Enable);
2027 hrtf_status = ALC_HRTF_DENIED_SOFT;
2029 hrtf_status = ALC_HRTF_REQUIRED_SOFT;
2033 device->Hrtf_Status = hrtf_status;
2038 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2039 if(VECTOR_SIZE(device->Hrtf_List) == 0)
2041 VECTOR_DEINIT(device->Hrtf_List);
2042 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2045 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
2047 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, hrtf_id);
2048 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2050 device->Hrtf = entry->hrtf;
2051 al_string_copy(&device->Hrtf_Name, entry->name);
2056 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
2058 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
2059 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2061 device->Hrtf = entry->hrtf;
2062 al_string_copy(&device->Hrtf_Name, entry->name);
2070 device->Hrtf_Mode = hrtf_mode;
2071 device->Hrtf_Status = hrtf_status;
2072 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
2074 device->Bs2b = NULL;
2078 TRACE("HRTF disabled\n");
2080 bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
2081 (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
2082 if(device->Type != Loopback)
2083 ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
2084 if(bs2blevel > 0 && bs2blevel <= 6)
2088 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
2089 bs2b_clear(device->Bs2b);
2091 bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
2092 TRACE("BS2B enabled\n");
2097 device->Bs2b = NULL;
2098 TRACE("BS2B disabled\n");
2103 aluInitPanning(device);
2105 /* With HRTF, allocate two extra channels for the post-filter output. */
2106 size = sizeof(device->DryBuffer[0]) * (device->NumChannels + (device->Hrtf ? 2 : 0));
2107 device->DryBuffer = al_calloc(16, size);
2108 if(!device->DryBuffer)
2110 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2111 return ALC_INVALID_DEVICE;
2114 SetMixerFPUMode(&oldMode);
2115 V0(device->Backend,lock)();
2116 context = ATOMIC_LOAD(&device->ContextList);
2121 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2122 LockUIntMapRead(&context->EffectSlotMap);
2123 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2125 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2127 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2129 UnlockUIntMapRead(&context->EffectSlotMap);
2130 V0(device->Backend,unlock)();
2131 RestoreFPUMode(&oldMode);
2132 return ALC_INVALID_DEVICE;
2134 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2135 V(slot->EffectState,update)(device, slot);
2137 UnlockUIntMapRead(&context->EffectSlotMap);
2139 LockUIntMapRead(&context->SourceMap);
2140 for(pos = 0;pos < context->SourceMap.size;pos++)
2142 ALsource *source = context->SourceMap.array[pos].value;
2143 ALuint s = device->NumAuxSends;
2144 while(s < MAX_SENDS)
2146 if(source->Send[s].Slot)
2147 DecrementRef(&source->Send[s].Slot->ref);
2148 source->Send[s].Slot = NULL;
2149 source->Send[s].Gain = 1.0f;
2150 source->Send[s].GainHF = 1.0f;
2153 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2155 UnlockUIntMapRead(&context->SourceMap);
2157 for(pos = 0;pos < context->VoiceCount;pos++)
2159 ALvoice *voice = &context->Voices[pos];
2160 ALsource *source = voice->Source;
2161 ALuint s = device->NumAuxSends;
2163 while(s < MAX_SENDS)
2165 voice->Send[s].Moving = AL_FALSE;
2166 voice->Send[s].Counter = 0;
2172 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2173 voice->Update(voice, source, context);
2177 context = context->next;
2179 if(device->DefaultSlot)
2181 ALeffectslot *slot = device->DefaultSlot;
2183 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2185 V0(device->Backend,unlock)();
2186 RestoreFPUMode(&oldMode);
2187 return ALC_INVALID_DEVICE;
2189 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2190 V(slot->EffectState,update)(device, slot);
2192 V0(device->Backend,unlock)();
2193 RestoreFPUMode(&oldMode);
2195 if(!(device->Flags&DEVICE_PAUSED))
2197 if(V0(device->Backend,start)() == ALC_FALSE)
2198 return ALC_INVALID_DEVICE;
2199 device->Flags |= DEVICE_RUNNING;
2202 return ALC_NO_ERROR;
2207 * Frees the device structure, and destroys any objects the app failed to
2208 * delete. Called once there's no more references on the device.
2210 static ALCvoid FreeDevice(ALCdevice *device)
2212 TRACE("%p\n", device);
2214 V0(device->Backend,close)();
2215 DELETE_OBJ(device->Backend);
2216 device->Backend = NULL;
2218 if(device->DefaultSlot)
2220 ALeffectState *state = device->DefaultSlot->EffectState;
2221 device->DefaultSlot = NULL;
2225 if(device->BufferMap.size > 0)
2227 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2228 ReleaseALBuffers(device);
2230 ResetUIntMap(&device->BufferMap);
2232 if(device->EffectMap.size > 0)
2234 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2235 ReleaseALEffects(device);
2237 ResetUIntMap(&device->EffectMap);
2239 if(device->FilterMap.size > 0)
2241 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2242 ReleaseALFilters(device);
2244 ResetUIntMap(&device->FilterMap);
2246 AL_STRING_DEINIT(device->Hrtf_Name);
2247 FreeHrtfList(&device->Hrtf_List);
2250 device->Bs2b = NULL;
2252 AL_STRING_DEINIT(device->DeviceName);
2254 al_free(device->DryBuffer);
2255 device->DryBuffer = NULL;
2261 void ALCdevice_IncRef(ALCdevice *device)
2264 ref = IncrementRef(&device->ref);
2265 TRACEREF("%p increasing refcount to %u\n", device, ref);
2268 void ALCdevice_DecRef(ALCdevice *device)
2271 ref = DecrementRef(&device->ref);
2272 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2273 if(ref == 0) FreeDevice(device);
2278 * Checks if the device handle is valid, and increments its ref count if so.
2280 static ALCboolean VerifyDevice(ALCdevice **device)
2282 ALCdevice *tmpDevice;
2285 tmpDevice = ATOMIC_LOAD(&DeviceList);
2288 if(tmpDevice == *device)
2290 ALCdevice_IncRef(tmpDevice);
2294 tmpDevice = tmpDevice->next;
2305 * Initializes context fields
2307 static ALvoid InitContext(ALCcontext *Context)
2309 ALlistener *listener = Context->Listener;
2310 //Initialise listener
2311 listener->Gain = 1.0f;
2312 listener->MetersPerUnit = 1.0f;
2313 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2314 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2315 listener->Forward[0] = 0.0f;
2316 listener->Forward[1] = 0.0f;
2317 listener->Forward[2] = -1.0f;
2318 listener->Up[0] = 0.0f;
2319 listener->Up[1] = 1.0f;
2320 listener->Up[2] = 0.0f;
2321 aluMatrixdSet(&listener->Params.Matrix,
2327 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2330 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2331 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2332 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2333 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2336 Context->DistanceModel = DefaultDistanceModel;
2337 Context->SourceDistanceModel = AL_FALSE;
2338 Context->DopplerFactor = 1.0f;
2339 Context->DopplerVelocity = 1.0f;
2340 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2341 Context->DeferUpdates = AL_FALSE;
2343 Context->ExtensionList = alExtList;
2349 * Cleans up the context, and destroys any remaining objects the app failed to
2350 * delete. Called once there's no more references on the context.
2352 static void FreeContext(ALCcontext *context)
2354 TRACE("%p\n", context);
2356 if(context->SourceMap.size > 0)
2358 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2359 ReleaseALSources(context);
2361 ResetUIntMap(&context->SourceMap);
2363 if(context->EffectSlotMap.size > 0)
2365 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2366 ReleaseALAuxiliaryEffectSlots(context);
2368 ResetUIntMap(&context->EffectSlotMap);
2370 al_free(context->Voices);
2371 context->Voices = NULL;
2372 context->VoiceCount = 0;
2373 context->MaxVoices = 0;
2375 VECTOR_DEINIT(context->ActiveAuxSlots);
2377 ALCdevice_DecRef(context->Device);
2378 context->Device = NULL;
2380 //Invalidate context
2381 memset(context, 0, sizeof(ALCcontext));
2387 * Removes the context reference from the given device and removes it from
2388 * being current on the running thread or globally.
2390 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2392 ALCcontext *nextctx;
2393 ALCcontext *origctx;
2395 if(altss_get(LocalContext) == context)
2397 WARN("%p released while current on thread\n", context);
2398 altss_set(LocalContext, NULL);
2399 ALCcontext_DecRef(context);
2403 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2404 ALCcontext_DecRef(context);
2406 ALCdevice_Lock(device);
2408 nextctx = context->next;
2409 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2415 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2417 ALCdevice_Unlock(device);
2419 ALCcontext_DecRef(context);
2422 void ALCcontext_IncRef(ALCcontext *context)
2425 ref = IncrementRef(&context->ref);
2426 TRACEREF("%p increasing refcount to %u\n", context, ref);
2429 void ALCcontext_DecRef(ALCcontext *context)
2432 ref = DecrementRef(&context->ref);
2433 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2434 if(ref == 0) FreeContext(context);
2437 static void ReleaseThreadCtx(void *ptr)
2439 WARN("%p current for thread being destroyed\n", ptr);
2440 ALCcontext_DecRef(ptr);
2445 * Checks that the given context is valid, and increments its reference count.
2447 static ALCboolean VerifyContext(ALCcontext **context)
2452 dev = ATOMIC_LOAD(&DeviceList);
2455 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2460 ALCcontext_IncRef(ctx);
2477 * Returns the currently active context for this thread, and adds a reference
2478 * without locking it.
2480 ALCcontext *GetContextRef(void)
2482 ALCcontext *context;
2484 context = altss_get(LocalContext);
2486 ALCcontext_IncRef(context);
2490 context = ATOMIC_LOAD(&GlobalContext);
2492 ALCcontext_IncRef(context);
2500 /************************************************
2501 * Standard ALC functions
2502 ************************************************/
2506 * Return last ALC generated error code for the given device
2508 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2512 if(VerifyDevice(&device))
2514 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2515 ALCdevice_DecRef(device);
2518 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2524 /* alcSuspendContext
2526 * Suspends updates for the given context
2528 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2533 if(!VerifyContext(&context))
2534 alcSetError(NULL, ALC_INVALID_CONTEXT);
2537 ALCcontext_DeferUpdates(context);
2538 ALCcontext_DecRef(context);
2542 /* alcProcessContext
2544 * Resumes processing updates for the given context
2546 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2551 if(!VerifyContext(&context))
2552 alcSetError(NULL, ALC_INVALID_CONTEXT);
2555 ALCcontext_ProcessUpdates(context);
2556 ALCcontext_DecRef(context);
2563 * Returns information about the device, and error strings
2565 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2567 const ALCchar *value = NULL;
2575 case ALC_INVALID_ENUM:
2576 value = alcErrInvalidEnum;
2579 case ALC_INVALID_VALUE:
2580 value = alcErrInvalidValue;
2583 case ALC_INVALID_DEVICE:
2584 value = alcErrInvalidDevice;
2587 case ALC_INVALID_CONTEXT:
2588 value = alcErrInvalidContext;
2591 case ALC_OUT_OF_MEMORY:
2592 value = alcErrOutOfMemory;
2595 case ALC_DEVICE_SPECIFIER:
2596 value = alcDefaultName;
2599 case ALC_ALL_DEVICES_SPECIFIER:
2600 if(VerifyDevice(&Device))
2602 value = al_string_get_cstr(Device->DeviceName);
2603 ALCdevice_DecRef(Device);
2607 ProbeAllDevicesList();
2608 value = al_string_get_cstr(alcAllDevicesList);
2612 case ALC_CAPTURE_DEVICE_SPECIFIER:
2613 if(VerifyDevice(&Device))
2615 value = al_string_get_cstr(Device->DeviceName);
2616 ALCdevice_DecRef(Device);
2620 ProbeCaptureDeviceList();
2621 value = al_string_get_cstr(alcCaptureDeviceList);
2625 /* Default devices are always first in the list */
2626 case ALC_DEFAULT_DEVICE_SPECIFIER:
2627 value = alcDefaultName;
2630 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2631 if(al_string_empty(alcAllDevicesList))
2632 ProbeAllDevicesList();
2634 VerifyDevice(&Device);
2636 free(alcDefaultAllDevicesSpecifier);
2637 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2638 if(!alcDefaultAllDevicesSpecifier)
2639 alcSetError(Device, ALC_OUT_OF_MEMORY);
2641 value = alcDefaultAllDevicesSpecifier;
2642 if(Device) ALCdevice_DecRef(Device);
2645 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2646 if(al_string_empty(alcCaptureDeviceList))
2647 ProbeCaptureDeviceList();
2649 VerifyDevice(&Device);
2651 free(alcCaptureDefaultDeviceSpecifier);
2652 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2653 if(!alcCaptureDefaultDeviceSpecifier)
2654 alcSetError(Device, ALC_OUT_OF_MEMORY);
2656 value = alcCaptureDefaultDeviceSpecifier;
2657 if(Device) ALCdevice_DecRef(Device);
2660 case ALC_EXTENSIONS:
2661 if(!VerifyDevice(&Device))
2662 value = alcNoDeviceExtList;
2665 value = alcExtensionList;
2666 ALCdevice_DecRef(Device);
2670 case ALC_HRTF_SPECIFIER_SOFT:
2671 if(!VerifyDevice(&Device))
2672 alcSetError(NULL, ALC_INVALID_DEVICE);
2676 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2678 ALCdevice_DecRef(Device);
2683 VerifyDevice(&Device);
2684 alcSetError(Device, ALC_INVALID_ENUM);
2685 if(Device) ALCdevice_DecRef(Device);
2693 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2697 if(size <= 0 || values == NULL)
2699 alcSetError(device, ALC_INVALID_VALUE);
2707 case ALC_MAJOR_VERSION:
2708 values[0] = alcMajorVersion;
2710 case ALC_MINOR_VERSION:
2711 values[0] = alcMinorVersion;
2714 case ALC_ATTRIBUTES_SIZE:
2715 case ALC_ALL_ATTRIBUTES:
2719 case ALC_MONO_SOURCES:
2720 case ALC_STEREO_SOURCES:
2721 case ALC_CAPTURE_SAMPLES:
2722 case ALC_FORMAT_CHANNELS_SOFT:
2723 case ALC_FORMAT_TYPE_SOFT:
2724 alcSetError(NULL, ALC_INVALID_DEVICE);
2728 alcSetError(NULL, ALC_INVALID_ENUM);
2734 if(device->Type == Capture)
2738 case ALC_CAPTURE_SAMPLES:
2739 V0(device->Backend,lock)();
2740 values[0] = V0(device->Backend,availableSamples)();
2741 V0(device->Backend,unlock)();
2745 values[0] = device->Connected;
2749 alcSetError(device, ALC_INVALID_ENUM);
2758 case ALC_MAJOR_VERSION:
2759 values[0] = alcMajorVersion;
2762 case ALC_MINOR_VERSION:
2763 values[0] = alcMinorVersion;
2766 case ALC_EFX_MAJOR_VERSION:
2767 values[0] = alcEFXMajorVersion;
2770 case ALC_EFX_MINOR_VERSION:
2771 values[0] = alcEFXMinorVersion;
2774 case ALC_ATTRIBUTES_SIZE:
2778 case ALC_ALL_ATTRIBUTES:
2781 alcSetError(device, ALC_INVALID_VALUE);
2786 values[i++] = ALC_FREQUENCY;
2787 values[i++] = device->Frequency;
2789 if(device->Type != Loopback)
2791 values[i++] = ALC_REFRESH;
2792 values[i++] = device->Frequency / device->UpdateSize;
2794 values[i++] = ALC_SYNC;
2795 values[i++] = ALC_FALSE;
2799 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2800 values[i++] = device->FmtChans;
2802 values[i++] = ALC_FORMAT_TYPE_SOFT;
2803 values[i++] = device->FmtType;
2806 values[i++] = ALC_MONO_SOURCES;
2807 values[i++] = device->NumMonoSources;
2809 values[i++] = ALC_STEREO_SOURCES;
2810 values[i++] = device->NumStereoSources;
2812 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2813 values[i++] = device->NumAuxSends;
2815 values[i++] = ALC_HRTF_SOFT;
2816 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2818 values[i++] = ALC_HRTF_STATUS_SOFT;
2819 values[i++] = device->Hrtf_Status;
2825 values[0] = device->Frequency;
2829 if(device->Type == Loopback)
2831 alcSetError(device, ALC_INVALID_DEVICE);
2834 values[0] = device->Frequency / device->UpdateSize;
2838 if(device->Type == Loopback)
2840 alcSetError(device, ALC_INVALID_DEVICE);
2843 values[0] = ALC_FALSE;
2846 case ALC_FORMAT_CHANNELS_SOFT:
2847 if(device->Type != Loopback)
2849 alcSetError(device, ALC_INVALID_DEVICE);
2852 values[0] = device->FmtChans;
2855 case ALC_FORMAT_TYPE_SOFT:
2856 if(device->Type != Loopback)
2858 alcSetError(device, ALC_INVALID_DEVICE);
2861 values[0] = device->FmtType;
2864 case ALC_MONO_SOURCES:
2865 values[0] = device->NumMonoSources;
2868 case ALC_STEREO_SOURCES:
2869 values[0] = device->NumStereoSources;
2872 case ALC_MAX_AUXILIARY_SENDS:
2873 values[0] = device->NumAuxSends;
2877 values[0] = device->Connected;
2881 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2884 case ALC_HRTF_STATUS_SOFT:
2885 values[0] = device->Hrtf_Status;
2888 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2889 FreeHrtfList(&device->Hrtf_List);
2890 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2891 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2895 alcSetError(device, ALC_INVALID_ENUM);
2903 * Returns information about the device and the version of OpenAL
2905 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2907 VerifyDevice(&device);
2908 if(size <= 0 || values == NULL)
2909 alcSetError(device, ALC_INVALID_VALUE);
2911 GetIntegerv(device, param, size, values);
2912 if(device) ALCdevice_DecRef(device);
2915 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2920 VerifyDevice(&device);
2921 if(size <= 0 || values == NULL)
2922 alcSetError(device, ALC_INVALID_VALUE);
2923 else if(!device || device->Type == Capture)
2925 ivals = malloc(size * sizeof(ALCint));
2926 size = GetIntegerv(device, pname, size, ivals);
2927 for(i = 0;i < size;i++)
2928 values[i] = ivals[i];
2931 else /* render device */
2935 case ALC_ATTRIBUTES_SIZE:
2939 case ALC_ALL_ATTRIBUTES:
2941 alcSetError(device, ALC_INVALID_VALUE);
2946 V0(device->Backend,lock)();
2947 values[i++] = ALC_FREQUENCY;
2948 values[i++] = device->Frequency;
2950 if(device->Type != Loopback)
2952 values[i++] = ALC_REFRESH;
2953 values[i++] = device->Frequency / device->UpdateSize;
2955 values[i++] = ALC_SYNC;
2956 values[i++] = ALC_FALSE;
2960 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2961 values[i++] = device->FmtChans;
2963 values[i++] = ALC_FORMAT_TYPE_SOFT;
2964 values[i++] = device->FmtType;
2967 values[i++] = ALC_MONO_SOURCES;
2968 values[i++] = device->NumMonoSources;
2970 values[i++] = ALC_STEREO_SOURCES;
2971 values[i++] = device->NumStereoSources;
2973 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2974 values[i++] = device->NumAuxSends;
2976 values[i++] = ALC_HRTF_SOFT;
2977 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2979 values[i++] = ALC_HRTF_STATUS_SOFT;
2980 values[i++] = device->Hrtf_Status;
2982 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2983 values[i++] = device->ClockBase +
2984 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2987 V0(device->Backend,unlock)();
2991 case ALC_DEVICE_CLOCK_SOFT:
2992 V0(device->Backend,lock)();
2993 *values = device->ClockBase +
2994 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2995 V0(device->Backend,unlock)();
2999 ivals = malloc(size * sizeof(ALCint));
3000 size = GetIntegerv(device, pname, size, ivals);
3001 for(i = 0;i < size;i++)
3002 values[i] = ivals[i];
3008 ALCdevice_DecRef(device);
3012 /* alcIsExtensionPresent
3014 * Determines if there is support for a particular extension
3016 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3018 ALCboolean bResult = ALC_FALSE;
3020 VerifyDevice(&device);
3023 alcSetError(device, ALC_INVALID_VALUE);
3026 size_t len = strlen(extName);
3027 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3030 if(strncasecmp(ptr, extName, len) == 0 &&
3031 (ptr[len] == '\0' || isspace(ptr[len])))
3036 if((ptr=strchr(ptr, ' ')) != NULL)
3040 } while(isspace(*ptr));
3045 ALCdevice_DecRef(device);
3050 /* alcGetProcAddress
3052 * Retrieves the function address for a particular extension function
3054 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3056 ALCvoid *ptr = NULL;
3060 VerifyDevice(&device);
3061 alcSetError(device, ALC_INVALID_VALUE);
3062 if(device) ALCdevice_DecRef(device);
3067 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3069 ptr = alcFunctions[i].address;
3078 * Get the value for a particular ALC enumeration name
3080 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3086 VerifyDevice(&device);
3087 alcSetError(device, ALC_INVALID_VALUE);
3088 if(device) ALCdevice_DecRef(device);
3093 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3095 val = enumeration[i].value;
3104 * Create and attach a context to the given device.
3106 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3108 ALCcontext *ALContext;
3112 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3115 alcSetError(device, ALC_INVALID_DEVICE);
3116 if(device) ALCdevice_DecRef(device);
3120 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3122 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3125 alcSetError(device, err);
3126 if(err == ALC_INVALID_DEVICE)
3128 V0(device->Backend,lock)();
3129 aluHandleDisconnect(device);
3130 V0(device->Backend,unlock)();
3132 ALCdevice_DecRef(device);
3136 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3139 InitRef(&ALContext->ref, 1);
3140 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3142 VECTOR_INIT(ALContext->ActiveAuxSlots);
3144 ALContext->VoiceCount = 0;
3145 ALContext->MaxVoices = 256;
3146 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3148 if(!ALContext || !ALContext->Voices)
3150 if(!ATOMIC_LOAD(&device->ContextList))
3152 V0(device->Backend,stop)();
3153 device->Flags &= ~DEVICE_RUNNING;
3159 al_free(ALContext->Voices);
3160 ALContext->Voices = NULL;
3162 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3168 alcSetError(device, ALC_OUT_OF_MEMORY);
3169 ALCdevice_DecRef(device);
3173 ALContext->Device = device;
3174 ALCdevice_IncRef(device);
3175 InitContext(ALContext);
3178 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3180 ALContext->next = head;
3181 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3185 ALCdevice_DecRef(device);
3187 TRACE("Created context %p\n", ALContext);
3191 /* alcDestroyContext
3193 * Remove a context from its device
3195 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3200 /* alcGetContextsDevice sets an error for invalid contexts */
3201 Device = alcGetContextsDevice(context);
3204 ReleaseContext(context, Device);
3205 if(!ATOMIC_LOAD(&Device->ContextList))
3207 V0(Device->Backend,stop)();
3208 Device->Flags &= ~DEVICE_RUNNING;
3215 /* alcGetCurrentContext
3217 * Returns the currently active context on the calling thread
3219 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3221 ALCcontext *Context = altss_get(LocalContext);
3222 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3226 /* alcGetThreadContext
3228 * Returns the currently active thread-local context
3230 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3232 return altss_get(LocalContext);
3236 /* alcMakeContextCurrent
3238 * Makes the given context the active process-wide context, and removes the
3239 * thread-local context for the calling thread.
3241 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3243 /* context must be valid or NULL */
3244 if(context && !VerifyContext(&context))
3246 alcSetError(NULL, ALC_INVALID_CONTEXT);
3249 /* context's reference count is already incremented */
3250 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3251 if(context) ALCcontext_DecRef(context);
3253 if((context=altss_get(LocalContext)) != NULL)
3255 altss_set(LocalContext, NULL);
3256 ALCcontext_DecRef(context);
3262 /* alcSetThreadContext
3264 * Makes the given context the active context for the current thread
3266 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3270 /* context must be valid or NULL */
3271 if(context && !VerifyContext(&context))
3273 alcSetError(NULL, ALC_INVALID_CONTEXT);
3276 /* context's reference count is already incremented */
3277 old = altss_get(LocalContext);
3278 altss_set(LocalContext, context);
3279 if(old) ALCcontext_DecRef(old);
3285 /* alcGetContextsDevice
3287 * Returns the device that a particular context is attached to
3289 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3293 if(!VerifyContext(&Context))
3295 alcSetError(NULL, ALC_INVALID_CONTEXT);
3298 Device = Context->Device;
3299 ALCcontext_DecRef(Context);
3307 * Opens the named device.
3309 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3317 if(!PlaybackBackend.name)
3319 alcSetError(NULL, ALC_INVALID_VALUE);
3323 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3325 /* Some old Windows apps hardcode these expecting OpenAL to use a
3326 * specific audio API, even when they're not enumerated. Creative's
3327 * router effectively ignores them too.
3329 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3330 || strcasecmp(deviceName, "MMSYSTEM") == 0
3335 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3338 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3343 InitRef(&device->ref, 1);
3344 device->Connected = ALC_TRUE;
3345 device->Type = Playback;
3346 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3349 device->Bs2b = NULL;
3350 VECTOR_INIT(device->Hrtf_List);
3351 AL_STRING_INIT(device->Hrtf_Name);
3352 device->Hrtf_Mode = DisabledHrtf;
3353 AL_STRING_INIT(device->DeviceName);
3354 device->DryBuffer = NULL;
3356 ATOMIC_INIT(&device->ContextList, NULL);
3358 device->ClockBase = 0;
3359 device->SamplesDone = 0;
3361 device->MaxNoOfSources = 256;
3362 device->AuxiliaryEffectSlotMax = 4;
3363 device->NumAuxSends = MAX_SENDS;
3365 InitUIntMap(&device->BufferMap, ~0);
3366 InitUIntMap(&device->EffectMap, ~0);
3367 InitUIntMap(&device->FilterMap, ~0);
3370 device->FmtChans = DevFmtChannelsDefault;
3371 device->FmtType = DevFmtTypeDefault;
3372 device->Frequency = DEFAULT_OUTPUT_RATE;
3373 device->IsHeadphones = AL_FALSE;
3374 device->NumUpdates = 4;
3375 device->UpdateSize = 1024;
3377 if(!PlaybackBackend.getFactory)
3378 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3379 ALCbackend_Playback);
3382 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3383 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3385 if(!device->Backend)
3388 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3393 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3395 static const struct {
3396 const char name[16];
3397 enum DevFmtChannels chans;
3399 { "mono", DevFmtMono },
3400 { "stereo", DevFmtStereo },
3401 { "quad", DevFmtQuad },
3402 { "surround51", DevFmtX51 },
3403 { "surround61", DevFmtX61 },
3404 { "surround71", DevFmtX71 },
3405 { "surround51rear", DevFmtX51Rear },
3409 for(i = 0;i < COUNTOF(chanlist);i++)
3411 if(strcasecmp(chanlist[i].name, fmt) == 0)
3413 device->FmtChans = chanlist[i].chans;
3414 device->Flags |= DEVICE_CHANNELS_REQUEST;
3418 if(i == COUNTOF(chanlist))
3419 ERR("Unsupported channels: %s\n", fmt);
3421 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3423 static const struct {
3424 const char name[16];
3425 enum DevFmtType type;
3427 { "int8", DevFmtByte },
3428 { "uint8", DevFmtUByte },
3429 { "int16", DevFmtShort },
3430 { "uint16", DevFmtUShort },
3431 { "int32", DevFmtInt },
3432 { "uint32", DevFmtUInt },
3433 { "float32", DevFmtFloat },
3437 for(i = 0;i < COUNTOF(typelist);i++)
3439 if(strcasecmp(typelist[i].name, fmt) == 0)
3441 device->FmtType = typelist[i].type;
3442 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3446 if(i == COUNTOF(typelist))
3447 ERR("Unsupported sample-type: %s\n", fmt);
3450 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3452 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3453 if(device->Frequency < MIN_OUTPUT_RATE)
3454 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3455 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3458 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3459 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3461 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3462 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3463 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3464 device->UpdateSize = (device->UpdateSize+3)&~3;
3466 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3467 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3469 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3470 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3472 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3473 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3475 device->NumStereoSources = 1;
3476 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3478 // Find a playback device to open
3479 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3481 DELETE_OBJ(device->Backend);
3483 alcSetError(NULL, err);
3487 if(DefaultEffect.type != AL_EFFECT_NULL)
3489 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3490 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3492 device->DefaultSlot = NULL;
3493 ERR("Failed to initialize the default effect slot\n");
3495 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3497 ALeffectState *state = device->DefaultSlot->EffectState;
3498 device->DefaultSlot = NULL;
3500 ERR("Failed to initialize the default effect\n");
3505 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3507 device->next = head;
3508 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3511 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3517 * Closes the given device.
3519 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3521 ALCdevice *list, *origdev, *nextdev;
3525 list = ATOMIC_LOAD(&DeviceList);
3529 } while((list=list->next) != NULL);
3530 if(!list || list->Type == Capture)
3532 alcSetError(list, ALC_INVALID_DEVICE);
3538 nextdev = device->next;
3539 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3544 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3548 ctx = ATOMIC_LOAD(&device->ContextList);
3551 ALCcontext *next = ctx->next;
3552 WARN("Releasing context %p\n", ctx);
3553 ReleaseContext(ctx, device);
3556 if((device->Flags&DEVICE_RUNNING))
3557 V0(device->Backend,stop)();
3558 device->Flags &= ~DEVICE_RUNNING;
3560 ALCdevice_DecRef(device);
3566 /************************************************
3567 * ALC capture functions
3568 ************************************************/
3569 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3571 ALCdevice *device = NULL;
3576 if(!CaptureBackend.name)
3578 alcSetError(NULL, ALC_INVALID_VALUE);
3584 alcSetError(NULL, ALC_INVALID_VALUE);
3588 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3591 device = al_calloc(16, sizeof(ALCdevice));
3594 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3599 InitRef(&device->ref, 1);
3600 device->Connected = ALC_TRUE;
3601 device->Type = Capture;
3603 VECTOR_INIT(device->Hrtf_List);
3604 AL_STRING_INIT(device->Hrtf_Name);
3606 AL_STRING_INIT(device->DeviceName);
3607 device->DryBuffer = NULL;
3609 InitUIntMap(&device->BufferMap, ~0);
3610 InitUIntMap(&device->EffectMap, ~0);
3611 InitUIntMap(&device->FilterMap, ~0);
3613 if(!CaptureBackend.getFactory)
3614 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3615 ALCbackend_Capture);
3618 ALCbackendFactory *factory = CaptureBackend.getFactory();
3619 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3621 if(!device->Backend)
3624 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3628 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3629 device->Frequency = frequency;
3631 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3632 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3635 alcSetError(NULL, ALC_INVALID_ENUM);
3638 device->IsHeadphones = AL_FALSE;
3640 device->UpdateSize = samples;
3641 device->NumUpdates = 1;
3643 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3646 alcSetError(NULL, err);
3651 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3653 device->next = head;
3654 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3657 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3661 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3663 ALCdevice *list, *next, *nextdev;
3666 list = ATOMIC_LOAD(&DeviceList);
3670 } while((list=list->next) != NULL);
3671 if(!list || list->Type != Capture)
3673 alcSetError(list, ALC_INVALID_DEVICE);
3679 nextdev = device->next;
3680 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3685 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3689 ALCdevice_DecRef(device);
3694 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3696 if(!VerifyDevice(&device) || device->Type != Capture)
3697 alcSetError(device, ALC_INVALID_DEVICE);
3700 V0(device->Backend,lock)();
3701 if(!device->Connected)
3702 alcSetError(device, ALC_INVALID_DEVICE);
3703 else if(!(device->Flags&DEVICE_RUNNING))
3705 if(V0(device->Backend,start)())
3706 device->Flags |= DEVICE_RUNNING;
3709 aluHandleDisconnect(device);
3710 alcSetError(device, ALC_INVALID_DEVICE);
3713 V0(device->Backend,unlock)();
3716 if(device) ALCdevice_DecRef(device);
3719 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3721 if(!VerifyDevice(&device) || device->Type != Capture)
3722 alcSetError(device, ALC_INVALID_DEVICE);
3725 V0(device->Backend,lock)();
3726 if((device->Flags&DEVICE_RUNNING))
3727 V0(device->Backend,stop)();
3728 device->Flags &= ~DEVICE_RUNNING;
3729 V0(device->Backend,unlock)();
3732 if(device) ALCdevice_DecRef(device);
3735 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3737 if(!VerifyDevice(&device) || device->Type != Capture)
3738 alcSetError(device, ALC_INVALID_DEVICE);
3741 ALCenum err = ALC_INVALID_VALUE;
3743 V0(device->Backend,lock)();
3744 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3745 err = V(device->Backend,captureSamples)(buffer, samples);
3746 V0(device->Backend,unlock)();
3748 if(err != ALC_NO_ERROR)
3749 alcSetError(device, err);
3751 if(device) ALCdevice_DecRef(device);
3755 /************************************************
3756 * ALC loopback functions
3757 ************************************************/
3759 /* alcLoopbackOpenDeviceSOFT
3761 * Open a loopback device, for manual rendering.
3763 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3765 ALCbackendFactory *factory;
3770 /* Make sure the device name, if specified, is us. */
3771 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3773 alcSetError(NULL, ALC_INVALID_VALUE);
3777 device = al_calloc(16, sizeof(ALCdevice));
3780 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3785 InitRef(&device->ref, 1);
3786 device->Connected = ALC_TRUE;
3787 device->Type = Loopback;
3788 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3791 VECTOR_INIT(device->Hrtf_List);
3792 AL_STRING_INIT(device->Hrtf_Name);
3793 device->Bs2b = NULL;
3794 device->Hrtf_Mode = DisabledHrtf;
3795 AL_STRING_INIT(device->DeviceName);
3796 device->DryBuffer = NULL;
3798 ATOMIC_INIT(&device->ContextList, NULL);
3800 device->ClockBase = 0;
3801 device->SamplesDone = 0;
3803 device->MaxNoOfSources = 256;
3804 device->AuxiliaryEffectSlotMax = 4;
3805 device->NumAuxSends = MAX_SENDS;
3807 InitUIntMap(&device->BufferMap, ~0);
3808 InitUIntMap(&device->EffectMap, ~0);
3809 InitUIntMap(&device->FilterMap, ~0);
3811 factory = ALCloopbackFactory_getFactory();
3812 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3813 if(!device->Backend)
3816 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3821 device->NumUpdates = 0;
3822 device->UpdateSize = 0;
3824 device->Frequency = DEFAULT_OUTPUT_RATE;
3825 device->FmtChans = DevFmtChannelsDefault;
3826 device->FmtType = DevFmtTypeDefault;
3827 device->IsHeadphones = AL_FALSE;
3829 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3830 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3832 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3833 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3835 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3836 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3838 device->NumStereoSources = 1;
3839 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3841 // Open the "backend"
3842 V(device->Backend,open)("Loopback");
3845 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3847 device->next = head;
3848 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3851 TRACE("Created device %p\n", device);
3855 /* alcIsRenderFormatSupportedSOFT
3857 * Determines if the loopback device supports the given format for rendering.
3859 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3861 ALCboolean ret = ALC_FALSE;
3863 if(!VerifyDevice(&device) || device->Type != Loopback)
3864 alcSetError(device, ALC_INVALID_DEVICE);
3866 alcSetError(device, ALC_INVALID_VALUE);
3869 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3870 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3871 freq >= MIN_OUTPUT_RATE)
3874 if(device) ALCdevice_DecRef(device);
3879 /* alcRenderSamplesSOFT
3881 * Renders some samples into a buffer, using the format last set by the
3882 * attributes given to alcCreateContext.
3884 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3886 if(!VerifyDevice(&device) || device->Type != Loopback)
3887 alcSetError(device, ALC_INVALID_DEVICE);
3888 else if(samples < 0 || (samples > 0 && buffer == NULL))
3889 alcSetError(device, ALC_INVALID_VALUE);
3891 aluMixData(device, buffer, samples);
3892 if(device) ALCdevice_DecRef(device);
3896 /************************************************
3897 * ALC DSP pause/resume functions
3898 ************************************************/
3900 /* alcDevicePauseSOFT
3902 * Pause the DSP to stop audio processing.
3904 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3906 if(!VerifyDevice(&device) || device->Type != Playback)
3907 alcSetError(device, ALC_INVALID_DEVICE);
3911 if((device->Flags&DEVICE_RUNNING))
3912 V0(device->Backend,stop)();
3913 device->Flags &= ~DEVICE_RUNNING;
3914 device->Flags |= DEVICE_PAUSED;
3917 if(device) ALCdevice_DecRef(device);
3920 /* alcDeviceResumeSOFT
3922 * Resume the DSP to restart audio processing.
3924 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3926 if(!VerifyDevice(&device) || device->Type != Playback)
3927 alcSetError(device, ALC_INVALID_DEVICE);
3931 if((device->Flags&DEVICE_PAUSED))
3933 device->Flags &= ~DEVICE_PAUSED;
3934 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3936 if(V0(device->Backend,start)() != ALC_FALSE)
3937 device->Flags |= DEVICE_RUNNING;
3940 alcSetError(device, ALC_INVALID_DEVICE);
3941 V0(device->Backend,lock)();
3942 aluHandleDisconnect(device);
3943 V0(device->Backend,unlock)();
3949 if(device) ALCdevice_DecRef(device);
3953 /************************************************
3954 * ALC HRTF functions
3955 ************************************************/
3957 /* alcGetStringiSOFT
3959 * Gets a string parameter at the given index.
3961 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3963 const ALCchar *str = NULL;
3965 if(!VerifyDevice(&device) || device->Type == Capture)
3966 alcSetError(device, ALC_INVALID_DEVICE);
3967 else switch(paramName)
3969 case ALC_HRTF_SPECIFIER_SOFT:
3970 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
3971 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
3973 alcSetError(device, ALC_INVALID_VALUE);
3977 alcSetError(device, ALC_INVALID_ENUM);
3980 if(device) ALCdevice_DecRef(device);
3985 /* alcResetDeviceSOFT
3987 * Resets the given device output, using the specified attribute list.
3989 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
3994 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3997 alcSetError(device, ALC_INVALID_DEVICE);
3998 if(device) ALCdevice_DecRef(device);
4002 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
4005 alcSetError(device, err);
4006 if(err == ALC_INVALID_DEVICE)
4008 V0(device->Backend,lock)();
4009 aluHandleDisconnect(device);
4010 V0(device->Backend,unlock)();
4012 ALCdevice_DecRef(device);
4016 ALCdevice_DecRef(device);