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"
38 #include "bformatdec.h"
46 #include "backends/base.h"
49 /************************************************
51 ************************************************/
54 ALCbackendFactory
* (*getFactory
)(void);
55 ALCboolean (*Init
)(BackendFuncs
*);
57 void (*Probe
)(enum DevProbe
);
61 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
62 static struct BackendInfo BackendList
[] = {
64 { "jack", ALCjackBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
66 #ifdef HAVE_PULSEAUDIO
67 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
70 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
73 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
76 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
79 { "solaris", ALCsolarisBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
82 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
85 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
88 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
91 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
94 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
97 { "port", ALCportBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
100 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
103 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
105 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
108 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
112 static struct BackendInfo PlaybackBackend
;
113 static struct BackendInfo CaptureBackend
;
116 /************************************************
117 * Functions, enums, and errors
118 ************************************************/
119 typedef struct ALCfunction
{
120 const ALCchar
*funcName
;
124 typedef struct ALCenums
{
125 const ALCchar
*enumName
;
129 #define DECL(x) { #x, (ALCvoid*)(x) }
130 static const ALCfunction alcFunctions
[] = {
131 DECL(alcCreateContext
),
132 DECL(alcMakeContextCurrent
),
133 DECL(alcProcessContext
),
134 DECL(alcSuspendContext
),
135 DECL(alcDestroyContext
),
136 DECL(alcGetCurrentContext
),
137 DECL(alcGetContextsDevice
),
139 DECL(alcCloseDevice
),
141 DECL(alcIsExtensionPresent
),
142 DECL(alcGetProcAddress
),
143 DECL(alcGetEnumValue
),
145 DECL(alcGetIntegerv
),
146 DECL(alcCaptureOpenDevice
),
147 DECL(alcCaptureCloseDevice
),
148 DECL(alcCaptureStart
),
149 DECL(alcCaptureStop
),
150 DECL(alcCaptureSamples
),
152 DECL(alcSetThreadContext
),
153 DECL(alcGetThreadContext
),
155 DECL(alcLoopbackOpenDeviceSOFT
),
156 DECL(alcIsRenderFormatSupportedSOFT
),
157 DECL(alcRenderSamplesSOFT
),
159 DECL(alcDevicePauseSOFT
),
160 DECL(alcDeviceResumeSOFT
),
162 DECL(alcGetStringiSOFT
),
163 DECL(alcResetDeviceSOFT
),
165 DECL(alcGetInteger64vSOFT
),
180 DECL(alIsExtensionPresent
),
181 DECL(alGetProcAddress
),
182 DECL(alGetEnumValue
),
189 DECL(alGetListenerf
),
190 DECL(alGetListener3f
),
191 DECL(alGetListenerfv
),
192 DECL(alGetListeneri
),
193 DECL(alGetListener3i
),
194 DECL(alGetListeneriv
),
196 DECL(alDeleteSources
),
212 DECL(alSourceRewindv
),
213 DECL(alSourcePausev
),
216 DECL(alSourceRewind
),
218 DECL(alSourceQueueBuffers
),
219 DECL(alSourceUnqueueBuffers
),
221 DECL(alDeleteBuffers
),
236 DECL(alDopplerFactor
),
237 DECL(alDopplerVelocity
),
238 DECL(alSpeedOfSound
),
239 DECL(alDistanceModel
),
242 DECL(alDeleteFilters
),
253 DECL(alDeleteEffects
),
263 DECL(alGenAuxiliaryEffectSlots
),
264 DECL(alDeleteAuxiliaryEffectSlots
),
265 DECL(alIsAuxiliaryEffectSlot
),
266 DECL(alAuxiliaryEffectSloti
),
267 DECL(alAuxiliaryEffectSlotiv
),
268 DECL(alAuxiliaryEffectSlotf
),
269 DECL(alAuxiliaryEffectSlotfv
),
270 DECL(alGetAuxiliaryEffectSloti
),
271 DECL(alGetAuxiliaryEffectSlotiv
),
272 DECL(alGetAuxiliaryEffectSlotf
),
273 DECL(alGetAuxiliaryEffectSlotfv
),
275 DECL(alDeferUpdatesSOFT
),
276 DECL(alProcessUpdatesSOFT
),
279 DECL(alSource3dSOFT
),
280 DECL(alSourcedvSOFT
),
281 DECL(alGetSourcedSOFT
),
282 DECL(alGetSource3dSOFT
),
283 DECL(alGetSourcedvSOFT
),
284 DECL(alSourcei64SOFT
),
285 DECL(alSource3i64SOFT
),
286 DECL(alSourcei64vSOFT
),
287 DECL(alGetSourcei64SOFT
),
288 DECL(alGetSource3i64SOFT
),
289 DECL(alGetSourcei64vSOFT
),
291 DECL(alBufferSamplesSOFT
),
292 DECL(alGetBufferSamplesSOFT
),
293 DECL(alIsBufferFormatSupportedSOFT
),
299 #define DECL(x) { #x, (x) }
300 static const ALCenums enumeration
[] = {
305 DECL(ALC_MAJOR_VERSION
),
306 DECL(ALC_MINOR_VERSION
),
307 DECL(ALC_ATTRIBUTES_SIZE
),
308 DECL(ALC_ALL_ATTRIBUTES
),
309 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
310 DECL(ALC_DEVICE_SPECIFIER
),
311 DECL(ALC_ALL_DEVICES_SPECIFIER
),
312 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
313 DECL(ALC_EXTENSIONS
),
317 DECL(ALC_MONO_SOURCES
),
318 DECL(ALC_STEREO_SOURCES
),
319 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
320 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
321 DECL(ALC_CAPTURE_SAMPLES
),
324 DECL(ALC_EFX_MAJOR_VERSION
),
325 DECL(ALC_EFX_MINOR_VERSION
),
326 DECL(ALC_MAX_AUXILIARY_SENDS
),
328 DECL(ALC_FORMAT_CHANNELS_SOFT
),
329 DECL(ALC_FORMAT_TYPE_SOFT
),
332 DECL(ALC_STEREO_SOFT
),
334 DECL(ALC_5POINT1_SOFT
),
335 DECL(ALC_6POINT1_SOFT
),
336 DECL(ALC_7POINT1_SOFT
),
339 DECL(ALC_UNSIGNED_BYTE_SOFT
),
340 DECL(ALC_SHORT_SOFT
),
341 DECL(ALC_UNSIGNED_SHORT_SOFT
),
343 DECL(ALC_UNSIGNED_INT_SOFT
),
344 DECL(ALC_FLOAT_SOFT
),
347 DECL(ALC_DONT_CARE_SOFT
),
348 DECL(ALC_HRTF_STATUS_SOFT
),
349 DECL(ALC_HRTF_DISABLED_SOFT
),
350 DECL(ALC_HRTF_ENABLED_SOFT
),
351 DECL(ALC_HRTF_DENIED_SOFT
),
352 DECL(ALC_HRTF_REQUIRED_SOFT
),
353 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
354 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
355 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
356 DECL(ALC_HRTF_SPECIFIER_SOFT
),
357 DECL(ALC_HRTF_ID_SOFT
),
360 DECL(ALC_INVALID_DEVICE
),
361 DECL(ALC_INVALID_CONTEXT
),
362 DECL(ALC_INVALID_ENUM
),
363 DECL(ALC_INVALID_VALUE
),
364 DECL(ALC_OUT_OF_MEMORY
),
372 DECL(AL_SOURCE_RELATIVE
),
373 DECL(AL_CONE_INNER_ANGLE
),
374 DECL(AL_CONE_OUTER_ANGLE
),
384 DECL(AL_ORIENTATION
),
385 DECL(AL_REFERENCE_DISTANCE
),
386 DECL(AL_ROLLOFF_FACTOR
),
387 DECL(AL_CONE_OUTER_GAIN
),
388 DECL(AL_MAX_DISTANCE
),
390 DECL(AL_SAMPLE_OFFSET
),
391 DECL(AL_BYTE_OFFSET
),
392 DECL(AL_SOURCE_TYPE
),
395 DECL(AL_UNDETERMINED
),
396 DECL(AL_METERS_PER_UNIT
),
397 DECL(AL_LOOP_POINTS_SOFT
),
398 DECL(AL_DIRECT_CHANNELS_SOFT
),
400 DECL(AL_DIRECT_FILTER
),
401 DECL(AL_AUXILIARY_SEND_FILTER
),
402 DECL(AL_AIR_ABSORPTION_FACTOR
),
403 DECL(AL_ROOM_ROLLOFF_FACTOR
),
404 DECL(AL_CONE_OUTER_GAINHF
),
405 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
406 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
407 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
409 DECL(AL_SOURCE_STATE
),
415 DECL(AL_BUFFERS_QUEUED
),
416 DECL(AL_BUFFERS_PROCESSED
),
418 DECL(AL_FORMAT_MONO8
),
419 DECL(AL_FORMAT_MONO16
),
420 DECL(AL_FORMAT_MONO_FLOAT32
),
421 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
422 DECL(AL_FORMAT_STEREO8
),
423 DECL(AL_FORMAT_STEREO16
),
424 DECL(AL_FORMAT_STEREO_FLOAT32
),
425 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
426 DECL(AL_FORMAT_MONO_IMA4
),
427 DECL(AL_FORMAT_STEREO_IMA4
),
428 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
429 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
430 DECL(AL_FORMAT_QUAD8_LOKI
),
431 DECL(AL_FORMAT_QUAD16_LOKI
),
432 DECL(AL_FORMAT_QUAD8
),
433 DECL(AL_FORMAT_QUAD16
),
434 DECL(AL_FORMAT_QUAD32
),
435 DECL(AL_FORMAT_51CHN8
),
436 DECL(AL_FORMAT_51CHN16
),
437 DECL(AL_FORMAT_51CHN32
),
438 DECL(AL_FORMAT_61CHN8
),
439 DECL(AL_FORMAT_61CHN16
),
440 DECL(AL_FORMAT_61CHN32
),
441 DECL(AL_FORMAT_71CHN8
),
442 DECL(AL_FORMAT_71CHN16
),
443 DECL(AL_FORMAT_71CHN32
),
444 DECL(AL_FORMAT_REAR8
),
445 DECL(AL_FORMAT_REAR16
),
446 DECL(AL_FORMAT_REAR32
),
447 DECL(AL_FORMAT_MONO_MULAW
),
448 DECL(AL_FORMAT_MONO_MULAW_EXT
),
449 DECL(AL_FORMAT_STEREO_MULAW
),
450 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
451 DECL(AL_FORMAT_QUAD_MULAW
),
452 DECL(AL_FORMAT_51CHN_MULAW
),
453 DECL(AL_FORMAT_61CHN_MULAW
),
454 DECL(AL_FORMAT_71CHN_MULAW
),
455 DECL(AL_FORMAT_REAR_MULAW
),
456 DECL(AL_FORMAT_MONO_ALAW_EXT
),
457 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
459 DECL(AL_FORMAT_BFORMAT2D_8
),
460 DECL(AL_FORMAT_BFORMAT2D_16
),
461 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
462 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
463 DECL(AL_FORMAT_BFORMAT3D_8
),
464 DECL(AL_FORMAT_BFORMAT3D_16
),
465 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
466 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
469 DECL(AL_MONO16_SOFT
),
470 DECL(AL_MONO32F_SOFT
),
471 DECL(AL_STEREO8_SOFT
),
472 DECL(AL_STEREO16_SOFT
),
473 DECL(AL_STEREO32F_SOFT
),
475 DECL(AL_QUAD16_SOFT
),
476 DECL(AL_QUAD32F_SOFT
),
478 DECL(AL_REAR16_SOFT
),
479 DECL(AL_REAR32F_SOFT
),
480 DECL(AL_5POINT1_8_SOFT
),
481 DECL(AL_5POINT1_16_SOFT
),
482 DECL(AL_5POINT1_32F_SOFT
),
483 DECL(AL_6POINT1_8_SOFT
),
484 DECL(AL_6POINT1_16_SOFT
),
485 DECL(AL_6POINT1_32F_SOFT
),
486 DECL(AL_7POINT1_8_SOFT
),
487 DECL(AL_7POINT1_16_SOFT
),
488 DECL(AL_7POINT1_32F_SOFT
),
489 DECL(AL_BFORMAT2D_8_SOFT
),
490 DECL(AL_BFORMAT2D_16_SOFT
),
491 DECL(AL_BFORMAT2D_32F_SOFT
),
492 DECL(AL_BFORMAT3D_8_SOFT
),
493 DECL(AL_BFORMAT3D_16_SOFT
),
494 DECL(AL_BFORMAT3D_32F_SOFT
),
497 DECL(AL_STEREO_SOFT
),
500 DECL(AL_5POINT1_SOFT
),
501 DECL(AL_6POINT1_SOFT
),
502 DECL(AL_7POINT1_SOFT
),
503 DECL(AL_BFORMAT2D_SOFT
),
504 DECL(AL_BFORMAT3D_SOFT
),
507 DECL(AL_UNSIGNED_BYTE_SOFT
),
509 DECL(AL_UNSIGNED_SHORT_SOFT
),
511 DECL(AL_UNSIGNED_INT_SOFT
),
513 DECL(AL_DOUBLE_SOFT
),
515 DECL(AL_UNSIGNED_BYTE3_SOFT
),
522 DECL(AL_INTERNAL_FORMAT_SOFT
),
523 DECL(AL_BYTE_LENGTH_SOFT
),
524 DECL(AL_SAMPLE_LENGTH_SOFT
),
525 DECL(AL_SEC_LENGTH_SOFT
),
526 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
527 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
529 DECL(AL_SOURCE_RADIUS
),
531 DECL(AL_STEREO_ANGLES
),
538 DECL(AL_INVALID_NAME
),
539 DECL(AL_INVALID_ENUM
),
540 DECL(AL_INVALID_VALUE
),
541 DECL(AL_INVALID_OPERATION
),
542 DECL(AL_OUT_OF_MEMORY
),
549 DECL(AL_DOPPLER_FACTOR
),
550 DECL(AL_DOPPLER_VELOCITY
),
551 DECL(AL_DISTANCE_MODEL
),
552 DECL(AL_SPEED_OF_SOUND
),
553 DECL(AL_SOURCE_DISTANCE_MODEL
),
554 DECL(AL_DEFERRED_UPDATES_SOFT
),
555 DECL(AL_GAIN_LIMIT_SOFT
),
557 DECL(AL_INVERSE_DISTANCE
),
558 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
559 DECL(AL_LINEAR_DISTANCE
),
560 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
561 DECL(AL_EXPONENT_DISTANCE
),
562 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
564 DECL(AL_FILTER_TYPE
),
565 DECL(AL_FILTER_NULL
),
566 DECL(AL_FILTER_LOWPASS
),
567 DECL(AL_FILTER_HIGHPASS
),
568 DECL(AL_FILTER_BANDPASS
),
570 DECL(AL_LOWPASS_GAIN
),
571 DECL(AL_LOWPASS_GAINHF
),
573 DECL(AL_HIGHPASS_GAIN
),
574 DECL(AL_HIGHPASS_GAINLF
),
576 DECL(AL_BANDPASS_GAIN
),
577 DECL(AL_BANDPASS_GAINHF
),
578 DECL(AL_BANDPASS_GAINLF
),
580 DECL(AL_EFFECT_TYPE
),
581 DECL(AL_EFFECT_NULL
),
582 DECL(AL_EFFECT_REVERB
),
583 DECL(AL_EFFECT_EAXREVERB
),
584 DECL(AL_EFFECT_CHORUS
),
585 DECL(AL_EFFECT_DISTORTION
),
586 DECL(AL_EFFECT_ECHO
),
587 DECL(AL_EFFECT_FLANGER
),
589 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
590 DECL(AL_EFFECT_VOCAL_MORPHER
),
591 DECL(AL_EFFECT_PITCH_SHIFTER
),
593 DECL(AL_EFFECT_RING_MODULATOR
),
595 DECL(AL_EFFECT_AUTOWAH
),
597 DECL(AL_EFFECT_COMPRESSOR
),
598 DECL(AL_EFFECT_EQUALIZER
),
599 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
600 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
602 DECL(AL_EAXREVERB_DENSITY
),
603 DECL(AL_EAXREVERB_DIFFUSION
),
604 DECL(AL_EAXREVERB_GAIN
),
605 DECL(AL_EAXREVERB_GAINHF
),
606 DECL(AL_EAXREVERB_GAINLF
),
607 DECL(AL_EAXREVERB_DECAY_TIME
),
608 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
609 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
610 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
611 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
612 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
613 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
614 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
615 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
616 DECL(AL_EAXREVERB_ECHO_TIME
),
617 DECL(AL_EAXREVERB_ECHO_DEPTH
),
618 DECL(AL_EAXREVERB_MODULATION_TIME
),
619 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
620 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
621 DECL(AL_EAXREVERB_HFREFERENCE
),
622 DECL(AL_EAXREVERB_LFREFERENCE
),
623 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
624 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
626 DECL(AL_REVERB_DENSITY
),
627 DECL(AL_REVERB_DIFFUSION
),
628 DECL(AL_REVERB_GAIN
),
629 DECL(AL_REVERB_GAINHF
),
630 DECL(AL_REVERB_DECAY_TIME
),
631 DECL(AL_REVERB_DECAY_HFRATIO
),
632 DECL(AL_REVERB_REFLECTIONS_GAIN
),
633 DECL(AL_REVERB_REFLECTIONS_DELAY
),
634 DECL(AL_REVERB_LATE_REVERB_GAIN
),
635 DECL(AL_REVERB_LATE_REVERB_DELAY
),
636 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
637 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
638 DECL(AL_REVERB_DECAY_HFLIMIT
),
640 DECL(AL_CHORUS_WAVEFORM
),
641 DECL(AL_CHORUS_PHASE
),
642 DECL(AL_CHORUS_RATE
),
643 DECL(AL_CHORUS_DEPTH
),
644 DECL(AL_CHORUS_FEEDBACK
),
645 DECL(AL_CHORUS_DELAY
),
647 DECL(AL_DISTORTION_EDGE
),
648 DECL(AL_DISTORTION_GAIN
),
649 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
650 DECL(AL_DISTORTION_EQCENTER
),
651 DECL(AL_DISTORTION_EQBANDWIDTH
),
654 DECL(AL_ECHO_LRDELAY
),
655 DECL(AL_ECHO_DAMPING
),
656 DECL(AL_ECHO_FEEDBACK
),
657 DECL(AL_ECHO_SPREAD
),
659 DECL(AL_FLANGER_WAVEFORM
),
660 DECL(AL_FLANGER_PHASE
),
661 DECL(AL_FLANGER_RATE
),
662 DECL(AL_FLANGER_DEPTH
),
663 DECL(AL_FLANGER_FEEDBACK
),
664 DECL(AL_FLANGER_DELAY
),
666 DECL(AL_RING_MODULATOR_FREQUENCY
),
667 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
668 DECL(AL_RING_MODULATOR_WAVEFORM
),
670 DECL(AL_COMPRESSOR_ONOFF
),
672 DECL(AL_EQUALIZER_LOW_GAIN
),
673 DECL(AL_EQUALIZER_LOW_CUTOFF
),
674 DECL(AL_EQUALIZER_MID1_GAIN
),
675 DECL(AL_EQUALIZER_MID1_CENTER
),
676 DECL(AL_EQUALIZER_MID1_WIDTH
),
677 DECL(AL_EQUALIZER_MID2_GAIN
),
678 DECL(AL_EQUALIZER_MID2_CENTER
),
679 DECL(AL_EQUALIZER_MID2_WIDTH
),
680 DECL(AL_EQUALIZER_HIGH_GAIN
),
681 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
683 DECL(AL_DEDICATED_GAIN
),
689 static const ALCchar alcNoError
[] = "No Error";
690 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
691 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
692 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
693 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
694 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
697 /************************************************
699 ************************************************/
701 /* Enumerated device names */
702 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
704 static al_string alcAllDevicesList
;
705 static al_string alcCaptureDeviceList
;
707 /* Default is always the first in the list */
708 static ALCchar
*alcDefaultAllDevicesSpecifier
;
709 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
711 /* Default context extensions */
712 static const ALchar alExtList
[] =
713 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
714 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
715 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
716 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
717 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
718 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
719 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length";
721 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
723 /* Thread-local current context */
724 static altss_t LocalContext
;
725 /* Process-wide current context */
726 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
728 /* Mixing thread piority level */
733 enum LogLevel LogLevel
= LogWarning
;
735 enum LogLevel LogLevel
= LogError
;
738 /* Flag to trap ALC device errors */
739 static ALCboolean TrapALCError
= ALC_FALSE
;
741 /* One-time configuration init control */
742 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
744 /* Default effect that applies to sources that don't have an effect on send 0 */
745 static ALeffect DefaultEffect
;
747 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
750 static ALCboolean SuspendDefers
= ALC_TRUE
;
753 /************************************************
755 ************************************************/
756 static const ALCchar alcNoDeviceExtList
[] =
757 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
758 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
759 static const ALCchar alcExtensionList
[] =
760 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
761 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
762 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
763 "ALC_SOFT_loopback ALC_SOFT_pause_device";
764 static const ALCint alcMajorVersion
= 1;
765 static const ALCint alcMinorVersion
= 1;
767 static const ALCint alcEFXMajorVersion
= 1;
768 static const ALCint alcEFXMinorVersion
= 0;
771 /************************************************
773 ************************************************/
774 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
776 static almtx_t ListLock
;
777 static inline void LockLists(void)
779 int ret
= almtx_lock(&ListLock
);
780 assert(ret
== althrd_success
);
782 static inline void UnlockLists(void)
784 int ret
= almtx_unlock(&ListLock
);
785 assert(ret
== althrd_success
);
788 /************************************************
789 * Library initialization
790 ************************************************/
792 static void alc_init(void);
793 static void alc_deinit(void);
794 static void alc_deinit_safe(void);
796 #ifndef AL_LIBTYPE_STATIC
797 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
801 case DLL_PROCESS_ATTACH
:
802 /* Pin the DLL so we won't get unloaded until the process terminates */
803 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
804 (WCHAR
*)hModule
, &hModule
);
808 case DLL_THREAD_DETACH
:
811 case DLL_PROCESS_DETACH
:
820 #elif defined(_MSC_VER)
821 #pragma section(".CRT$XCU",read)
822 static void alc_constructor(void);
823 static void alc_destructor(void);
824 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
826 static void alc_constructor(void)
828 atexit(alc_destructor
);
832 static void alc_destructor(void)
836 #elif defined(HAVE_GCC_DESTRUCTOR)
837 static void alc_init(void) __attribute__((constructor
));
838 static void alc_deinit(void) __attribute__((destructor
));
840 #error "No static initialization available on this platform!"
843 #elif defined(HAVE_GCC_DESTRUCTOR)
845 static void alc_init(void) __attribute__((constructor
));
846 static void alc_deinit(void) __attribute__((destructor
));
849 #error "No global initialization available on this platform!"
852 static void ReleaseThreadCtx(void *ptr
);
853 static void alc_init(void)
860 AL_STRING_INIT(alcAllDevicesList
);
861 AL_STRING_INIT(alcCaptureDeviceList
);
863 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
864 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
867 str
= getenv("__ALSOFT_REVERSE_Z");
868 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
871 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
872 assert(ret
== althrd_success
);
874 ret
= almtx_init(&ListLock
, almtx_recursive
);
875 assert(ret
== althrd_success
);
880 static void alc_initconfig(void)
882 const char *devs
, *str
;
887 str
= getenv("ALSOFT_LOGLEVEL");
890 long lvl
= strtol(str
, NULL
, 0);
891 if(lvl
>= NoLog
&& lvl
<= LogRef
)
895 str
= getenv("ALSOFT_LOGFILE");
898 FILE *logfile
= al_fopen(str
, "wt");
899 if(logfile
) LogFile
= logfile
;
900 else ERR("Failed to open log file '%s'\n", str
);
905 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
906 for(i
= 1;BackendList
[i
].name
;i
++)
907 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
908 TRACE("Supported backends: %s\n", buf
);
912 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
915 if(strcasecmp(str
, "ignore") == 0)
917 SuspendDefers
= ALC_FALSE
;
918 TRACE("Selected context suspend behavior, \"ignore\"\n");
921 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
925 #if defined(HAVE_SSE4_1)
926 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
927 #elif defined(HAVE_SSE3)
928 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
929 #elif defined(HAVE_SSE2)
930 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
931 #elif defined(HAVE_SSE)
932 capfilter
|= CPU_CAP_SSE
;
935 capfilter
|= CPU_CAP_NEON
;
937 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
939 if(strcasecmp(str
, "all") == 0)
944 const char *next
= str
;
948 while(isspace(str
[0]))
950 next
= strchr(str
, ',');
952 if(!str
[0] || str
[0] == ',')
955 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
956 while(len
> 0 && isspace(str
[len
-1]))
958 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
959 capfilter
&= ~CPU_CAP_SSE
;
960 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
961 capfilter
&= ~CPU_CAP_SSE2
;
962 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
963 capfilter
&= ~CPU_CAP_SSE3
;
964 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
965 capfilter
&= ~CPU_CAP_SSE4_1
;
966 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
967 capfilter
&= ~CPU_CAP_NEON
;
969 WARN("Invalid CPU extension \"%s\"\n", str
);
973 FillCPUCaps(capfilter
);
980 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
984 str
= getenv("ALSOFT_TRAP_ERROR");
985 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
987 TrapALError
= AL_TRUE
;
988 TrapALCError
= AL_TRUE
;
992 str
= getenv("ALSOFT_TRAP_AL_ERROR");
993 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
994 TrapALError
= AL_TRUE
;
995 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
997 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
998 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
999 TrapALCError
= ALC_TRUE
;
1000 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1003 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1004 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1006 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1008 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1009 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1013 const char *next
= devs
;
1014 int endlist
, delitem
;
1019 while(isspace(devs
[0]))
1021 next
= strchr(devs
, ',');
1023 delitem
= (devs
[0] == '-');
1024 if(devs
[0] == '-') devs
++;
1026 if(!devs
[0] || devs
[0] == ',')
1033 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1034 while(len
> 0 && isspace(devs
[len
-1]))
1036 for(n
= i
;BackendList
[n
].name
;n
++)
1038 if(len
== strlen(BackendList
[n
].name
) &&
1039 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1044 BackendList
[n
] = BackendList
[n
+1];
1046 } while(BackendList
[n
].name
);
1050 struct BackendInfo Bkp
= BackendList
[n
];
1053 BackendList
[n
] = BackendList
[n
-1];
1056 BackendList
[n
] = Bkp
;
1067 BackendList
[i
].name
= NULL
;
1068 BackendList
[i
].getFactory
= NULL
;
1069 BackendList
[i
].Init
= NULL
;
1070 BackendList
[i
].Deinit
= NULL
;
1071 BackendList
[i
].Probe
= NULL
;
1075 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1077 if(BackendList
[i
].getFactory
)
1079 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1080 if(!V0(factory
,init
)())
1082 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1086 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1087 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1089 PlaybackBackend
= BackendList
[i
];
1090 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1092 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1094 CaptureBackend
= BackendList
[i
];
1095 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1101 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1103 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1107 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1108 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1110 PlaybackBackend
= BackendList
[i
];
1111 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1113 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1115 CaptureBackend
= BackendList
[i
];
1116 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1120 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1124 if(!PlaybackBackend
.name
)
1125 WARN("No playback backend available!\n");
1126 if(!CaptureBackend
.name
)
1127 WARN("No capture backend available!\n");
1129 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1132 const char *next
= str
;
1136 next
= strchr(str
, ',');
1138 if(!str
[0] || next
== str
)
1141 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1142 for(n
= 0;EffectList
[n
].name
;n
++)
1144 if(len
== strlen(EffectList
[n
].name
) &&
1145 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1146 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1151 InitEffectFactoryMap();
1153 InitEffect(&DefaultEffect
);
1154 str
= getenv("ALSOFT_DEFAULT_REVERB");
1155 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1156 LoadReverbPreset(str
, &DefaultEffect
);
1158 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1161 /************************************************
1162 * Library deinitialization
1163 ************************************************/
1164 static void alc_cleanup(void)
1168 AL_STRING_DEINIT(alcAllDevicesList
);
1169 AL_STRING_DEINIT(alcCaptureDeviceList
);
1171 free(alcDefaultAllDevicesSpecifier
);
1172 alcDefaultAllDevicesSpecifier
= NULL
;
1173 free(alcCaptureDefaultDeviceSpecifier
);
1174 alcCaptureDefaultDeviceSpecifier
= NULL
;
1176 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1181 } while((dev
=dev
->next
) != NULL
);
1182 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1185 DeinitEffectFactoryMap();
1188 static void alc_deinit_safe(void)
1196 almtx_destroy(&ListLock
);
1197 altss_delete(LocalContext
);
1199 if(LogFile
!= stderr
)
1204 static void alc_deinit(void)
1210 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1211 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1213 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1215 if(!BackendList
[i
].getFactory
)
1216 BackendList
[i
].Deinit();
1219 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1220 V0(factory
,deinit
)();
1224 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1225 V0(factory
,deinit
)();
1232 /************************************************
1233 * Device enumeration
1234 ************************************************/
1235 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1240 al_string_clear(list
);
1242 if(backendinfo
->Probe
)
1243 backendinfo
->Probe(type
);
1244 else if(backendinfo
->getFactory
)
1246 ALCbackendFactory
*factory
= backendinfo
->getFactory();
1247 V(factory
,probe
)(type
);
1252 static void ProbeAllDevicesList(void)
1253 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1254 static void ProbeCaptureDeviceList(void)
1255 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1257 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1259 size_t len
= strlen(name
);
1261 al_string_append_range(devnames
, name
, name
+len
+1);
1263 void AppendAllDevicesList(const ALCchar
*name
)
1264 { AppendDevice(name
, &alcAllDevicesList
); }
1265 void AppendCaptureDeviceList(const ALCchar
*name
)
1266 { AppendDevice(name
, &alcCaptureDeviceList
); }
1269 /************************************************
1270 * Device format information
1271 ************************************************/
1272 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1276 case DevFmtByte
: return "Signed Byte";
1277 case DevFmtUByte
: return "Unsigned Byte";
1278 case DevFmtShort
: return "Signed Short";
1279 case DevFmtUShort
: return "Unsigned Short";
1280 case DevFmtInt
: return "Signed Int";
1281 case DevFmtUInt
: return "Unsigned Int";
1282 case DevFmtFloat
: return "Float";
1284 return "(unknown type)";
1286 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1290 case DevFmtMono
: return "Mono";
1291 case DevFmtStereo
: return "Stereo";
1292 case DevFmtQuad
: return "Quadraphonic";
1293 case DevFmtX51
: return "5.1 Surround";
1294 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1295 case DevFmtX61
: return "6.1 Surround";
1296 case DevFmtX71
: return "7.1 Surround";
1297 case DevFmtAmbi1
: return "Ambisonic (1st Order)";
1298 case DevFmtAmbi2
: return "Ambisonic (2nd Order)";
1299 case DevFmtAmbi3
: return "Ambisonic (3rd Order)";
1301 return "(unknown channels)";
1304 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1305 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1309 case DevFmtByte
: return sizeof(ALbyte
);
1310 case DevFmtUByte
: return sizeof(ALubyte
);
1311 case DevFmtShort
: return sizeof(ALshort
);
1312 case DevFmtUShort
: return sizeof(ALushort
);
1313 case DevFmtInt
: return sizeof(ALint
);
1314 case DevFmtUInt
: return sizeof(ALuint
);
1315 case DevFmtFloat
: return sizeof(ALfloat
);
1319 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1323 case DevFmtMono
: return 1;
1324 case DevFmtStereo
: return 2;
1325 case DevFmtQuad
: return 4;
1326 case DevFmtX51
: return 6;
1327 case DevFmtX51Rear
: return 6;
1328 case DevFmtX61
: return 7;
1329 case DevFmtX71
: return 8;
1330 case DevFmtAmbi1
: return 4;
1331 case DevFmtAmbi2
: return 9;
1332 case DevFmtAmbi3
: return 16;
1337 static ALboolean
DecomposeDevFormat(ALenum format
, enum DevFmtChannels
*chans
,
1338 enum DevFmtType
*type
)
1340 static const struct {
1342 enum DevFmtChannels channels
;
1343 enum DevFmtType type
;
1345 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1346 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1347 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1349 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1350 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1351 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1353 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1354 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1355 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1357 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1358 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1359 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1361 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1362 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1363 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1365 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1366 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1367 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1371 for(i
= 0;i
< COUNTOF(list
);i
++)
1373 if(list
[i
].format
== format
)
1375 *chans
= list
[i
].channels
;
1376 *type
= list
[i
].type
;
1384 static ALCboolean
IsValidALCType(ALCenum type
)
1389 case ALC_UNSIGNED_BYTE_SOFT
:
1390 case ALC_SHORT_SOFT
:
1391 case ALC_UNSIGNED_SHORT_SOFT
:
1393 case ALC_UNSIGNED_INT_SOFT
:
1394 case ALC_FLOAT_SOFT
:
1400 static ALCboolean
IsValidALCChannels(ALCenum channels
)
1405 case ALC_STEREO_SOFT
:
1407 case ALC_5POINT1_SOFT
:
1408 case ALC_6POINT1_SOFT
:
1409 case ALC_7POINT1_SOFT
:
1416 /************************************************
1417 * Miscellaneous ALC helpers
1418 ************************************************/
1420 extern inline void LockContext(ALCcontext
*context
);
1421 extern inline void UnlockContext(ALCcontext
*context
);
1423 void ALCdevice_Lock(ALCdevice
*device
)
1425 V0(device
->Backend
,lock
)();
1428 void ALCdevice_Unlock(ALCdevice
*device
)
1430 V0(device
->Backend
,unlock
)();
1434 /* SetDefaultWFXChannelOrder
1436 * Sets the default channel order used by WaveFormatEx.
1438 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1442 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1443 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1445 switch(device
->FmtChans
)
1448 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1451 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1452 device
->RealOut
.ChannelName
[1] = FrontRight
;
1455 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1456 device
->RealOut
.ChannelName
[1] = FrontRight
;
1457 device
->RealOut
.ChannelName
[2] = BackLeft
;
1458 device
->RealOut
.ChannelName
[3] = BackRight
;
1461 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1462 device
->RealOut
.ChannelName
[1] = FrontRight
;
1463 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1464 device
->RealOut
.ChannelName
[3] = LFE
;
1465 device
->RealOut
.ChannelName
[4] = SideLeft
;
1466 device
->RealOut
.ChannelName
[5] = SideRight
;
1469 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1470 device
->RealOut
.ChannelName
[1] = FrontRight
;
1471 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1472 device
->RealOut
.ChannelName
[3] = LFE
;
1473 device
->RealOut
.ChannelName
[4] = BackLeft
;
1474 device
->RealOut
.ChannelName
[5] = BackRight
;
1477 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1478 device
->RealOut
.ChannelName
[1] = FrontRight
;
1479 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1480 device
->RealOut
.ChannelName
[3] = LFE
;
1481 device
->RealOut
.ChannelName
[4] = BackCenter
;
1482 device
->RealOut
.ChannelName
[5] = SideLeft
;
1483 device
->RealOut
.ChannelName
[6] = SideRight
;
1486 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1487 device
->RealOut
.ChannelName
[1] = FrontRight
;
1488 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1489 device
->RealOut
.ChannelName
[3] = LFE
;
1490 device
->RealOut
.ChannelName
[4] = BackLeft
;
1491 device
->RealOut
.ChannelName
[5] = BackRight
;
1492 device
->RealOut
.ChannelName
[6] = SideLeft
;
1493 device
->RealOut
.ChannelName
[7] = SideRight
;
1496 device
->RealOut
.ChannelName
[0] = Aux0
;
1497 device
->RealOut
.ChannelName
[1] = Aux1
;
1498 device
->RealOut
.ChannelName
[2] = Aux2
;
1499 device
->RealOut
.ChannelName
[3] = Aux3
;
1502 device
->RealOut
.ChannelName
[0] = Aux0
;
1503 device
->RealOut
.ChannelName
[1] = Aux1
;
1504 device
->RealOut
.ChannelName
[2] = Aux2
;
1505 device
->RealOut
.ChannelName
[3] = Aux3
;
1506 device
->RealOut
.ChannelName
[4] = Aux4
;
1507 device
->RealOut
.ChannelName
[5] = Aux5
;
1508 device
->RealOut
.ChannelName
[6] = Aux6
;
1509 device
->RealOut
.ChannelName
[7] = Aux7
;
1510 device
->RealOut
.ChannelName
[8] = Aux8
;
1513 device
->RealOut
.ChannelName
[0] = Aux0
;
1514 device
->RealOut
.ChannelName
[1] = Aux1
;
1515 device
->RealOut
.ChannelName
[2] = Aux2
;
1516 device
->RealOut
.ChannelName
[3] = Aux3
;
1517 device
->RealOut
.ChannelName
[4] = Aux4
;
1518 device
->RealOut
.ChannelName
[5] = Aux5
;
1519 device
->RealOut
.ChannelName
[6] = Aux6
;
1520 device
->RealOut
.ChannelName
[7] = Aux7
;
1521 device
->RealOut
.ChannelName
[8] = Aux8
;
1522 device
->RealOut
.ChannelName
[9] = Aux9
;
1523 device
->RealOut
.ChannelName
[10] = Aux10
;
1524 device
->RealOut
.ChannelName
[11] = Aux11
;
1525 device
->RealOut
.ChannelName
[12] = Aux12
;
1526 device
->RealOut
.ChannelName
[13] = Aux13
;
1527 device
->RealOut
.ChannelName
[14] = Aux14
;
1528 device
->RealOut
.ChannelName
[15] = Aux15
;
1533 /* SetDefaultChannelOrder
1535 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1537 void SetDefaultChannelOrder(ALCdevice
*device
)
1541 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1542 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1544 switch(device
->FmtChans
)
1547 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1548 device
->RealOut
.ChannelName
[1] = FrontRight
;
1549 device
->RealOut
.ChannelName
[2] = BackLeft
;
1550 device
->RealOut
.ChannelName
[3] = BackRight
;
1551 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1552 device
->RealOut
.ChannelName
[5] = LFE
;
1555 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1556 device
->RealOut
.ChannelName
[1] = FrontRight
;
1557 device
->RealOut
.ChannelName
[2] = BackLeft
;
1558 device
->RealOut
.ChannelName
[3] = BackRight
;
1559 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1560 device
->RealOut
.ChannelName
[5] = LFE
;
1561 device
->RealOut
.ChannelName
[6] = SideLeft
;
1562 device
->RealOut
.ChannelName
[7] = SideRight
;
1565 /* Same as WFX order */
1574 SetDefaultWFXChannelOrder(device
);
1579 extern inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
);
1582 /* ALCcontext_DeferUpdates
1584 * Defers/suspends updates for the given context's listener and sources. This
1585 * does *NOT* stop mixing, but rather prevents certain property changes from
1588 void ALCcontext_DeferUpdates(ALCcontext
*context
, ALenum type
)
1590 ATOMIC_STORE(&context
->DeferUpdates
, type
);
1593 /* ALCcontext_ProcessUpdates
1595 * Resumes update processing after being deferred.
1597 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1599 ALCdevice
*device
= context
->Device
;
1601 ReadLock(&context
->PropLock
);
1602 if(ATOMIC_EXCHANGE(ALenum
, &context
->DeferUpdates
, AL_FALSE
))
1607 /* Tell the mixer to stop applying updates, then wait for any active
1608 * updating to finish, before providing updates.
1610 ATOMIC_STORE(&context
->HoldUpdates
, AL_TRUE
);
1611 while(((updates
=ReadRef(&context
->UpdateCount
))&1) != 0)
1614 UpdateListenerProps(context
);
1615 UpdateAllEffectSlotProps(context
);
1617 LockUIntMapRead(&context
->SourceMap
);
1618 V0(device
->Backend
,lock
)();
1619 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1621 ALsource
*Source
= context
->SourceMap
.values
[pos
];
1624 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1625 Source
->OffsetType
!= AL_NONE
)
1627 WriteLock(&Source
->queue_lock
);
1628 ApplyOffset(Source
);
1629 WriteUnlock(&Source
->queue_lock
);
1632 new_state
= Source
->new_state
;
1633 Source
->new_state
= AL_NONE
;
1635 SetSourceState(Source
, context
, new_state
);
1637 V0(device
->Backend
,unlock
)();
1638 UnlockUIntMapRead(&context
->SourceMap
);
1640 UpdateAllSourceProps(context
);
1642 /* Now with all updates declared, let the mixer continue applying them
1643 * so they all happen at once.
1645 ATOMIC_STORE(&context
->HoldUpdates
, AL_FALSE
);
1647 ReadUnlock(&context
->PropLock
);
1653 * Stores the latest ALC device error
1655 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1660 /* DebugBreak() will cause an exception if there is no debugger */
1661 if(IsDebuggerPresent())
1663 #elif defined(SIGTRAP)
1669 ATOMIC_STORE(&device
->LastError
, errorCode
);
1671 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1677 * Updates the device's base clock time with however many samples have been
1678 * done. This is used so frequency changes on the device don't cause the time
1679 * to jump forward or back.
1681 static inline void UpdateClockBase(ALCdevice
*device
)
1683 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1684 device
->SamplesDone
= 0;
1687 /* UpdateDeviceParams
1689 * Updates device parameters according to the attribute list (caller is
1690 * responsible for holding the list lock).
1692 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1694 ALCcontext
*context
;
1695 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1696 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1697 enum DevFmtChannels oldChans
;
1698 enum DevFmtType oldType
;
1701 ALCsizei hrtf_id
= -1;
1704 // Check for attributes
1705 if(device
->Type
== Loopback
)
1711 GotAll
= GotFreq
|GotChans
|GotType
1713 ALCuint freq
, numMono
, numStereo
, numSends
;
1714 enum DevFmtChannels schans
;
1715 enum DevFmtType stype
;
1716 ALCuint attrIdx
= 0;
1721 WARN("Missing attributes for loopback device\n");
1722 return ALC_INVALID_VALUE
;
1725 numMono
= device
->NumMonoSources
;
1726 numStereo
= device
->NumStereoSources
;
1727 numSends
= device
->NumAuxSends
;
1728 schans
= device
->FmtChans
;
1729 stype
= device
->FmtType
;
1730 freq
= device
->Frequency
;
1732 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1733 while(attrList
[attrIdx
])
1735 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1737 ALCint val
= attrList
[attrIdx
+ 1];
1738 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT
, val
);
1739 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1740 return ALC_INVALID_VALUE
;
1745 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1747 ALCint val
= attrList
[attrIdx
+ 1];
1748 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT
, val
);
1749 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1750 return ALC_INVALID_VALUE
;
1755 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1757 freq
= attrList
[attrIdx
+ 1];
1758 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1759 if(freq
< MIN_OUTPUT_RATE
)
1760 return ALC_INVALID_VALUE
;
1764 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1766 numStereo
= attrList
[attrIdx
+ 1];
1767 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1768 if(numStereo
> device
->SourcesMax
)
1769 numStereo
= device
->SourcesMax
;
1771 numMono
= device
->SourcesMax
- numStereo
;
1774 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1776 numSends
= attrList
[attrIdx
+ 1];
1777 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1780 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1782 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1783 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1784 hrtf_appreq
= Hrtf_Disable
;
1785 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1786 hrtf_appreq
= Hrtf_Enable
;
1788 hrtf_appreq
= Hrtf_Default
;
1791 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1793 hrtf_id
= attrList
[attrIdx
+ 1];
1794 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1801 if(gotFmt
!= GotAll
)
1803 WARN("Missing format for loopback device\n");
1804 return ALC_INVALID_VALUE
;
1807 ConfigValueUInt(NULL
, NULL
, "sends", &numSends
);
1808 numSends
= minu(MAX_SENDS
, numSends
);
1810 if((device
->Flags
&DEVICE_RUNNING
))
1811 V0(device
->Backend
,stop
)();
1812 device
->Flags
&= ~DEVICE_RUNNING
;
1814 UpdateClockBase(device
);
1816 device
->Frequency
= freq
;
1817 device
->FmtChans
= schans
;
1818 device
->FmtType
= stype
;
1819 device
->NumMonoSources
= numMono
;
1820 device
->NumStereoSources
= numStereo
;
1821 device
->NumAuxSends
= numSends
;
1823 else if(attrList
&& attrList
[0])
1825 ALCuint freq
, numMono
, numStereo
, numSends
;
1826 ALCuint attrIdx
= 0;
1828 /* If a context is already running on the device, stop playback so the
1829 * device attributes can be updated. */
1830 if((device
->Flags
&DEVICE_RUNNING
))
1831 V0(device
->Backend
,stop
)();
1832 device
->Flags
&= ~DEVICE_RUNNING
;
1834 freq
= device
->Frequency
;
1835 numMono
= device
->NumMonoSources
;
1836 numStereo
= device
->NumStereoSources
;
1837 numSends
= device
->NumAuxSends
;
1839 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1840 while(attrList
[attrIdx
])
1842 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1844 freq
= attrList
[attrIdx
+ 1];
1845 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1846 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1849 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1851 numStereo
= attrList
[attrIdx
+ 1];
1852 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1853 if(numStereo
> device
->SourcesMax
)
1854 numStereo
= device
->SourcesMax
;
1856 numMono
= device
->SourcesMax
- numStereo
;
1859 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1861 numSends
= attrList
[attrIdx
+ 1];
1862 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1865 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1867 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1868 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1869 hrtf_appreq
= Hrtf_Disable
;
1870 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1871 hrtf_appreq
= Hrtf_Enable
;
1873 hrtf_appreq
= Hrtf_Default
;
1876 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1878 hrtf_id
= attrList
[attrIdx
+ 1];
1879 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1886 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1887 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1889 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1890 numSends
= minu(MAX_SENDS
, numSends
);
1892 UpdateClockBase(device
);
1894 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1896 /* SSE and Neon do best with the update size being a multiple of 4 */
1897 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1898 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1900 device
->Frequency
= freq
;
1901 device
->NumMonoSources
= numMono
;
1902 device
->NumStereoSources
= numStereo
;
1903 device
->NumAuxSends
= numSends
;
1906 if((device
->Flags
&DEVICE_RUNNING
))
1907 return ALC_NO_ERROR
;
1909 al_free(device
->Uhj_Encoder
);
1910 device
->Uhj_Encoder
= NULL
;
1912 al_free(device
->Bs2b
);
1913 device
->Bs2b
= NULL
;
1915 al_free(device
->Dry
.Buffer
);
1916 device
->Dry
.Buffer
= NULL
;
1917 device
->Dry
.NumChannels
= 0;
1918 device
->FOAOut
.Buffer
= NULL
;
1919 device
->FOAOut
.NumChannels
= 0;
1920 device
->RealOut
.Buffer
= NULL
;
1921 device
->RealOut
.NumChannels
= 0;
1923 UpdateClockBase(device
);
1925 /*************************************************************************
1926 * Update device format request if HRTF is requested
1928 device
->Hrtf
.Status
= ALC_HRTF_DISABLED_SOFT
;
1929 if(device
->Type
!= Loopback
)
1932 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
1934 if(strcasecmp(hrtf
, "true") == 0)
1935 hrtf_userreq
= Hrtf_Enable
;
1936 else if(strcasecmp(hrtf
, "false") == 0)
1937 hrtf_userreq
= Hrtf_Disable
;
1938 else if(strcasecmp(hrtf
, "auto") != 0)
1939 ERR("Unexpected hrtf value: %s\n", hrtf
);
1942 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
1944 if(VECTOR_SIZE(device
->Hrtf
.List
) == 0)
1946 VECTOR_DEINIT(device
->Hrtf
.List
);
1947 device
->Hrtf
.List
= EnumerateHrtf(device
->DeviceName
);
1949 if(VECTOR_SIZE(device
->Hrtf
.List
) > 0)
1951 device
->FmtChans
= DevFmtStereo
;
1952 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf
.List
))
1953 device
->Frequency
= VECTOR_ELEM(device
->Hrtf
.List
, hrtf_id
).hrtf
->sampleRate
;
1955 device
->Frequency
= VECTOR_ELEM(device
->Hrtf
.List
, 0).hrtf
->sampleRate
;
1956 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
1960 hrtf_userreq
= Hrtf_Default
;
1961 hrtf_appreq
= Hrtf_Disable
;
1962 device
->Hrtf
.Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1966 else if(hrtf_appreq
== Hrtf_Enable
)
1968 size_t i
= VECTOR_SIZE(device
->Hrtf
.List
);
1969 /* Loopback device. We don't need to match to a specific HRTF entry
1970 * here. If the requested ID matches, we'll pick that later, if not,
1971 * we'll try to auto-select one anyway. Just make sure one exists
1974 if(device
->FmtChans
== DevFmtStereo
)
1976 if(VECTOR_SIZE(device
->Hrtf
.List
) == 0)
1978 VECTOR_DEINIT(device
->Hrtf
.List
);
1979 device
->Hrtf
.List
= EnumerateHrtf(device
->DeviceName
);
1981 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf
.List
);i
++)
1983 const struct Hrtf
*hrtf
= VECTOR_ELEM(device
->Hrtf
.List
, i
).hrtf
;
1984 if(hrtf
->sampleRate
== device
->Frequency
)
1988 if(i
== VECTOR_SIZE(device
->Hrtf
.List
))
1990 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1991 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1992 hrtf_appreq
= Hrtf_Disable
;
1993 device
->Hrtf
.Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1997 oldFreq
= device
->Frequency
;
1998 oldChans
= device
->FmtChans
;
1999 oldType
= device
->FmtType
;
2001 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2002 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
2003 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
2004 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
2005 device
->UpdateSize
, device
->NumUpdates
2008 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
2009 return ALC_INVALID_DEVICE
;
2011 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
2013 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
2014 DevFmtChannelsString(device
->FmtChans
));
2015 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
2017 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
2019 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
2020 DevFmtTypeString(device
->FmtType
));
2021 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
2023 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
2025 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
2026 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
2029 if((device
->UpdateSize
&3) != 0)
2031 if((CPUCapFlags
&CPU_CAP_SSE
))
2032 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2033 if((CPUCapFlags
&CPU_CAP_NEON
))
2034 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2037 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2038 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
2039 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
2042 aluInitRenderer(device
, hrtf_id
, hrtf_appreq
, hrtf_userreq
);
2044 /* Allocate extra channels for any post-filter output. */
2045 size
= device
->Dry
.NumChannels
* sizeof(device
->Dry
.Buffer
[0]);
2046 if((device
->AmbiDecoder
&& bformatdec_getOrder(device
->AmbiDecoder
) >= 2))
2047 size
+= (ChannelsFromDevFmt(device
->FmtChans
)+4) * sizeof(device
->Dry
.Buffer
[0]);
2048 else if(device
->Hrtf
.Handle
|| device
->Uhj_Encoder
|| device
->AmbiDecoder
)
2049 size
+= ChannelsFromDevFmt(device
->FmtChans
) * sizeof(device
->Dry
.Buffer
[0]);
2050 else if(device
->FmtChans
> DevFmtAmbi1
&& device
->FmtChans
<= DevFmtAmbi3
)
2051 size
+= 4 * sizeof(device
->Dry
.Buffer
[0]);
2052 device
->Dry
.Buffer
= al_calloc(16, size
);
2053 if(!device
->Dry
.Buffer
)
2055 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2056 return ALC_INVALID_DEVICE
;
2059 if(device
->Hrtf
.Handle
|| device
->Uhj_Encoder
|| device
->AmbiDecoder
)
2061 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2062 device
->RealOut
.NumChannels
= ChannelsFromDevFmt(device
->FmtChans
);
2066 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2067 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2070 if((device
->AmbiDecoder
&& bformatdec_getOrder(device
->AmbiDecoder
) >= 2) ||
2071 (device
->FmtChans
> DevFmtAmbi1
&& device
->FmtChans
<= DevFmtAmbi3
))
2073 /* Higher-order rendering requires upsampling first-order content, so
2074 * make sure to mix it separately.
2076 device
->FOAOut
.Buffer
= device
->RealOut
.Buffer
+ device
->RealOut
.NumChannels
;
2077 device
->FOAOut
.NumChannels
= 4;
2081 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
;
2082 device
->FOAOut
.NumChannels
= device
->Dry
.NumChannels
;
2085 SetMixerFPUMode(&oldMode
);
2086 if(device
->DefaultSlot
)
2088 ALeffectslot
*slot
= device
->DefaultSlot
;
2089 ALeffectState
*state
= slot
->Effect
.State
;
2091 state
->OutBuffer
= device
->Dry
.Buffer
;
2092 state
->OutChannels
= device
->Dry
.NumChannels
;
2093 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2095 RestoreFPUMode(&oldMode
);
2096 return ALC_INVALID_DEVICE
;
2098 UpdateEffectSlotProps(slot
);
2101 context
= ATOMIC_LOAD(&device
->ContextList
);
2106 ReadLock(&context
->PropLock
);
2107 LockUIntMapRead(&context
->EffectSlotMap
);
2108 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2110 ALeffectslot
*slot
= context
->EffectSlotMap
.values
[pos
];
2111 ALeffectState
*state
= slot
->Effect
.State
;
2113 state
->OutBuffer
= device
->Dry
.Buffer
;
2114 state
->OutChannels
= device
->Dry
.NumChannels
;
2115 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2117 UnlockUIntMapRead(&context
->EffectSlotMap
);
2118 ReadUnlock(&context
->PropLock
);
2119 RestoreFPUMode(&oldMode
);
2120 return ALC_INVALID_DEVICE
;
2123 UpdateEffectSlotProps(slot
);
2125 UnlockUIntMapRead(&context
->EffectSlotMap
);
2127 LockUIntMapRead(&context
->SourceMap
);
2128 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2130 ALsource
*source
= context
->SourceMap
.values
[pos
];
2131 ALuint s
= device
->NumAuxSends
;
2132 while(s
< MAX_SENDS
)
2134 if(source
->Send
[s
].Slot
)
2135 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2136 source
->Send
[s
].Slot
= NULL
;
2137 source
->Send
[s
].Gain
= 1.0f
;
2138 source
->Send
[s
].GainHF
= 1.0f
;
2139 source
->Send
[s
].HFReference
= LOWPASSFREQREF
;
2140 source
->Send
[s
].GainLF
= 1.0f
;
2141 source
->Send
[s
].LFReference
= HIGHPASSFREQREF
;
2144 source
->NeedsUpdate
= AL_TRUE
;
2146 UnlockUIntMapRead(&context
->SourceMap
);
2148 UpdateListenerProps(context
);
2149 ReadUnlock(&context
->PropLock
);
2151 context
= context
->next
;
2153 RestoreFPUMode(&oldMode
);
2155 if(!(device
->Flags
&DEVICE_PAUSED
))
2157 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2158 return ALC_INVALID_DEVICE
;
2159 device
->Flags
|= DEVICE_RUNNING
;
2162 return ALC_NO_ERROR
;
2167 * Frees the device structure, and destroys any objects the app failed to
2168 * delete. Called once there's no more references on the device.
2170 static ALCvoid
FreeDevice(ALCdevice
*device
)
2172 TRACE("%p\n", device
);
2174 V0(device
->Backend
,close
)();
2175 DELETE_OBJ(device
->Backend
);
2176 device
->Backend
= NULL
;
2178 almtx_destroy(&device
->BackendLock
);
2180 if(device
->DefaultSlot
)
2182 DeinitEffectSlot(device
->DefaultSlot
);
2183 device
->DefaultSlot
= NULL
;
2186 if(device
->BufferMap
.size
> 0)
2188 WARN("(%p) Deleting %d Buffer%s\n", device
, device
->BufferMap
.size
,
2189 (device
->BufferMap
.size
==1)?"":"s");
2190 ReleaseALBuffers(device
);
2192 ResetUIntMap(&device
->BufferMap
);
2194 if(device
->EffectMap
.size
> 0)
2196 WARN("(%p) Deleting %d Effect%s\n", device
, device
->EffectMap
.size
,
2197 (device
->EffectMap
.size
==1)?"":"s");
2198 ReleaseALEffects(device
);
2200 ResetUIntMap(&device
->EffectMap
);
2202 if(device
->FilterMap
.size
> 0)
2204 WARN("(%p) Deleting %d Filter%s\n", device
, device
->FilterMap
.size
,
2205 (device
->FilterMap
.size
==1)?"":"s");
2206 ReleaseALFilters(device
);
2208 ResetUIntMap(&device
->FilterMap
);
2210 AL_STRING_DEINIT(device
->Hrtf
.Name
);
2211 FreeHrtfList(&device
->Hrtf
.List
);
2213 al_free(device
->Bs2b
);
2214 device
->Bs2b
= NULL
;
2216 al_free(device
->Uhj_Encoder
);
2217 device
->Uhj_Encoder
= NULL
;
2219 bformatdec_free(device
->AmbiDecoder
);
2220 device
->AmbiDecoder
= NULL
;
2222 ambiup_free(device
->AmbiUp
);
2223 device
->AmbiUp
= NULL
;
2225 AL_STRING_DEINIT(device
->DeviceName
);
2227 al_free(device
->Dry
.Buffer
);
2228 device
->Dry
.Buffer
= NULL
;
2229 device
->Dry
.NumChannels
= 0;
2230 device
->FOAOut
.Buffer
= NULL
;
2231 device
->FOAOut
.NumChannels
= 0;
2232 device
->RealOut
.Buffer
= NULL
;
2233 device
->RealOut
.NumChannels
= 0;
2239 void ALCdevice_IncRef(ALCdevice
*device
)
2242 ref
= IncrementRef(&device
->ref
);
2243 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2246 void ALCdevice_DecRef(ALCdevice
*device
)
2249 ref
= DecrementRef(&device
->ref
);
2250 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2251 if(ref
== 0) FreeDevice(device
);
2256 * Checks if the device handle is valid, and increments its ref count if so.
2258 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2260 ALCdevice
*tmpDevice
;
2263 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2266 if(tmpDevice
== *device
)
2268 ALCdevice_IncRef(tmpDevice
);
2272 tmpDevice
= tmpDevice
->next
;
2283 * Initializes context fields
2285 static ALvoid
InitContext(ALCcontext
*Context
)
2287 ALlistener
*listener
= Context
->Listener
;
2289 //Initialise listener
2290 listener
->Gain
= 1.0f
;
2291 listener
->MetersPerUnit
= 1.0f
;
2292 listener
->Position
[0] = 0.0f
;
2293 listener
->Position
[1] = 0.0f
;
2294 listener
->Position
[2] = 0.0f
;
2295 listener
->Velocity
[0] = 0.0f
;
2296 listener
->Velocity
[1] = 0.0f
;
2297 listener
->Velocity
[2] = 0.0f
;
2298 listener
->Forward
[0] = 0.0f
;
2299 listener
->Forward
[1] = 0.0f
;
2300 listener
->Forward
[2] = -1.0f
;
2301 listener
->Up
[0] = 0.0f
;
2302 listener
->Up
[1] = 1.0f
;
2303 listener
->Up
[2] = 0.0f
;
2305 aluMatrixfSet(&listener
->Params
.Matrix
,
2306 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2307 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2308 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2309 0.0f
, 0.0f
, 0.0f
, 1.0f
2311 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2312 listener
->Params
.Gain
= 1.0f
;
2313 listener
->Params
.MetersPerUnit
= 1.0f
;
2314 listener
->Params
.DopplerFactor
= 1.0f
;
2315 listener
->Params
.SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2317 ATOMIC_INIT(&listener
->Update
, NULL
);
2318 ATOMIC_INIT(&listener
->FreeList
, NULL
);
2321 InitRef(&Context
->UpdateCount
, 0);
2322 ATOMIC_INIT(&Context
->HoldUpdates
, AL_FALSE
);
2323 Context
->GainBoost
= 1.0f
;
2324 RWLockInit(&Context
->PropLock
);
2325 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2326 InitUIntMap(&Context
->SourceMap
, Context
->Device
->SourcesMax
);
2327 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2330 Context
->DistanceModel
= DefaultDistanceModel
;
2331 Context
->SourceDistanceModel
= AL_FALSE
;
2332 Context
->DopplerFactor
= 1.0f
;
2333 Context
->DopplerVelocity
= 1.0f
;
2334 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2335 ATOMIC_INIT(&Context
->DeferUpdates
, AL_FALSE
);
2337 Context
->ExtensionList
= alExtList
;
2343 * Cleans up the context, and destroys any remaining objects the app failed to
2344 * delete. Called once there's no more references on the context.
2346 static void FreeContext(ALCcontext
*context
)
2348 ALlistener
*listener
= context
->Listener
;
2349 struct ALlistenerProps
*lprops
;
2352 TRACE("%p\n", context
);
2354 if(context
->SourceMap
.size
> 0)
2356 WARN("(%p) Deleting %d Source%s\n", context
, context
->SourceMap
.size
,
2357 (context
->SourceMap
.size
==1)?"":"s");
2358 ReleaseALSources(context
);
2360 ResetUIntMap(&context
->SourceMap
);
2362 if(context
->EffectSlotMap
.size
> 0)
2364 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context
, context
->EffectSlotMap
.size
,
2365 (context
->EffectSlotMap
.size
==1)?"":"s");
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 if((lprops
=ATOMIC_LOAD(&listener
->Update
, almemory_order_acquire
)) != NULL
)
2377 TRACE("Freed unapplied listener update %p\n", lprops
);
2381 lprops
= ATOMIC_LOAD(&listener
->FreeList
, almemory_order_acquire
);
2384 struct ALlistenerProps
*next
= ATOMIC_LOAD(&lprops
->next
, almemory_order_acquire
);
2389 TRACE("Freed "SZFMT
" listener property object%s\n", count
, (count
==1)?"":"s");
2391 ALCdevice_DecRef(context
->Device
);
2392 context
->Device
= NULL
;
2394 //Invalidate context
2395 memset(context
, 0, sizeof(ALCcontext
));
2401 * Removes the context reference from the given device and removes it from
2402 * being current on the running thread or globally.
2404 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2406 ALCcontext
*origctx
;
2408 if(altss_get(LocalContext
) == context
)
2410 WARN("%p released while current on thread\n", context
);
2411 altss_set(LocalContext
, NULL
);
2412 ALCcontext_DecRef(context
);
2416 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2417 ALCcontext_DecRef(context
);
2419 ALCdevice_Lock(device
);
2421 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, context
->next
))
2423 ALCcontext
*volatile*list
= &origctx
->next
;
2426 if(*list
== context
)
2428 *list
= (*list
)->next
;
2431 list
= &(*list
)->next
;
2434 ALCdevice_Unlock(device
);
2436 ALCcontext_DecRef(context
);
2439 void ALCcontext_IncRef(ALCcontext
*context
)
2441 uint ref
= IncrementRef(&context
->ref
);
2442 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2445 void ALCcontext_DecRef(ALCcontext
*context
)
2447 uint ref
= DecrementRef(&context
->ref
);
2448 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2449 if(ref
== 0) FreeContext(context
);
2452 static void ReleaseThreadCtx(void *ptr
)
2454 ALCcontext
*context
= ptr
;
2455 uint ref
= DecrementRef(&context
->ref
);
2456 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2457 ERR("Context %p current for thread being destroyed, possible leak!\n", context
);
2462 * Checks that the given context is valid, and increments its reference count.
2464 static ALCboolean
VerifyContext(ALCcontext
**context
)
2469 dev
= ATOMIC_LOAD(&DeviceList
);
2472 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2477 ALCcontext_IncRef(ctx
);
2494 * Returns the currently active context for this thread, and adds a reference
2495 * without locking it.
2497 ALCcontext
*GetContextRef(void)
2499 ALCcontext
*context
;
2501 context
= altss_get(LocalContext
);
2503 ALCcontext_IncRef(context
);
2507 context
= ATOMIC_LOAD(&GlobalContext
);
2509 ALCcontext_IncRef(context
);
2517 /************************************************
2518 * Standard ALC functions
2519 ************************************************/
2523 * Return last ALC generated error code for the given device
2525 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2529 if(VerifyDevice(&device
))
2531 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2532 ALCdevice_DecRef(device
);
2535 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2541 /* alcSuspendContext
2543 * Suspends updates for the given context
2545 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2550 if(!VerifyContext(&context
))
2551 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2554 ALCcontext_DeferUpdates(context
, DeferAllowPlay
);
2555 ALCcontext_DecRef(context
);
2559 /* alcProcessContext
2561 * Resumes processing updates for the given context
2563 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2568 if(!VerifyContext(&context
))
2569 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2572 ALCcontext_ProcessUpdates(context
);
2573 ALCcontext_DecRef(context
);
2580 * Returns information about the device, and error strings
2582 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2584 const ALCchar
*value
= NULL
;
2592 case ALC_INVALID_ENUM
:
2593 value
= alcErrInvalidEnum
;
2596 case ALC_INVALID_VALUE
:
2597 value
= alcErrInvalidValue
;
2600 case ALC_INVALID_DEVICE
:
2601 value
= alcErrInvalidDevice
;
2604 case ALC_INVALID_CONTEXT
:
2605 value
= alcErrInvalidContext
;
2608 case ALC_OUT_OF_MEMORY
:
2609 value
= alcErrOutOfMemory
;
2612 case ALC_DEVICE_SPECIFIER
:
2613 value
= alcDefaultName
;
2616 case ALC_ALL_DEVICES_SPECIFIER
:
2617 if(VerifyDevice(&Device
))
2619 value
= al_string_get_cstr(Device
->DeviceName
);
2620 ALCdevice_DecRef(Device
);
2624 ProbeAllDevicesList();
2625 value
= al_string_get_cstr(alcAllDevicesList
);
2629 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2630 if(VerifyDevice(&Device
))
2632 value
= al_string_get_cstr(Device
->DeviceName
);
2633 ALCdevice_DecRef(Device
);
2637 ProbeCaptureDeviceList();
2638 value
= al_string_get_cstr(alcCaptureDeviceList
);
2642 /* Default devices are always first in the list */
2643 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2644 value
= alcDefaultName
;
2647 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2648 if(al_string_empty(alcAllDevicesList
))
2649 ProbeAllDevicesList();
2651 VerifyDevice(&Device
);
2653 free(alcDefaultAllDevicesSpecifier
);
2654 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2655 if(!alcDefaultAllDevicesSpecifier
)
2656 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2658 value
= alcDefaultAllDevicesSpecifier
;
2659 if(Device
) ALCdevice_DecRef(Device
);
2662 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2663 if(al_string_empty(alcCaptureDeviceList
))
2664 ProbeCaptureDeviceList();
2666 VerifyDevice(&Device
);
2668 free(alcCaptureDefaultDeviceSpecifier
);
2669 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2670 if(!alcCaptureDefaultDeviceSpecifier
)
2671 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2673 value
= alcCaptureDefaultDeviceSpecifier
;
2674 if(Device
) ALCdevice_DecRef(Device
);
2677 case ALC_EXTENSIONS
:
2678 if(!VerifyDevice(&Device
))
2679 value
= alcNoDeviceExtList
;
2682 value
= alcExtensionList
;
2683 ALCdevice_DecRef(Device
);
2687 case ALC_HRTF_SPECIFIER_SOFT
:
2688 if(!VerifyDevice(&Device
))
2689 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2692 almtx_lock(&Device
->BackendLock
);
2693 value
= (Device
->Hrtf
.Handle
? al_string_get_cstr(Device
->Hrtf
.Name
) : "");
2694 almtx_unlock(&Device
->BackendLock
);
2695 ALCdevice_DecRef(Device
);
2700 VerifyDevice(&Device
);
2701 alcSetError(Device
, ALC_INVALID_ENUM
);
2702 if(Device
) ALCdevice_DecRef(Device
);
2710 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2714 if(size
<= 0 || values
== NULL
)
2716 alcSetError(device
, ALC_INVALID_VALUE
);
2724 case ALC_MAJOR_VERSION
:
2725 values
[0] = alcMajorVersion
;
2727 case ALC_MINOR_VERSION
:
2728 values
[0] = alcMinorVersion
;
2731 case ALC_ATTRIBUTES_SIZE
:
2732 case ALC_ALL_ATTRIBUTES
:
2736 case ALC_MONO_SOURCES
:
2737 case ALC_STEREO_SOURCES
:
2738 case ALC_CAPTURE_SAMPLES
:
2739 case ALC_FORMAT_CHANNELS_SOFT
:
2740 case ALC_FORMAT_TYPE_SOFT
:
2741 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2745 alcSetError(NULL
, ALC_INVALID_ENUM
);
2751 if(device
->Type
== Capture
)
2755 case ALC_CAPTURE_SAMPLES
:
2756 almtx_lock(&device
->BackendLock
);
2757 values
[0] = V0(device
->Backend
,availableSamples
)();
2758 almtx_unlock(&device
->BackendLock
);
2762 values
[0] = device
->Connected
;
2766 alcSetError(device
, ALC_INVALID_ENUM
);
2775 case ALC_MAJOR_VERSION
:
2776 values
[0] = alcMajorVersion
;
2779 case ALC_MINOR_VERSION
:
2780 values
[0] = alcMinorVersion
;
2783 case ALC_EFX_MAJOR_VERSION
:
2784 values
[0] = alcEFXMajorVersion
;
2787 case ALC_EFX_MINOR_VERSION
:
2788 values
[0] = alcEFXMinorVersion
;
2791 case ALC_ATTRIBUTES_SIZE
:
2795 case ALC_ALL_ATTRIBUTES
:
2798 alcSetError(device
, ALC_INVALID_VALUE
);
2803 almtx_lock(&device
->BackendLock
);
2804 values
[i
++] = ALC_FREQUENCY
;
2805 values
[i
++] = device
->Frequency
;
2807 if(device
->Type
!= Loopback
)
2809 values
[i
++] = ALC_REFRESH
;
2810 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2812 values
[i
++] = ALC_SYNC
;
2813 values
[i
++] = ALC_FALSE
;
2817 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2818 values
[i
++] = device
->FmtChans
;
2820 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2821 values
[i
++] = device
->FmtType
;
2824 values
[i
++] = ALC_MONO_SOURCES
;
2825 values
[i
++] = device
->NumMonoSources
;
2827 values
[i
++] = ALC_STEREO_SOURCES
;
2828 values
[i
++] = device
->NumStereoSources
;
2830 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2831 values
[i
++] = device
->NumAuxSends
;
2833 values
[i
++] = ALC_HRTF_SOFT
;
2834 values
[i
++] = (device
->Hrtf
.Handle
? ALC_TRUE
: ALC_FALSE
);
2836 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2837 values
[i
++] = device
->Hrtf
.Status
;
2838 almtx_unlock(&device
->BackendLock
);
2844 values
[0] = device
->Frequency
;
2848 if(device
->Type
== Loopback
)
2850 alcSetError(device
, ALC_INVALID_DEVICE
);
2853 almtx_lock(&device
->BackendLock
);
2854 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2855 almtx_unlock(&device
->BackendLock
);
2859 if(device
->Type
== Loopback
)
2861 alcSetError(device
, ALC_INVALID_DEVICE
);
2864 values
[0] = ALC_FALSE
;
2867 case ALC_FORMAT_CHANNELS_SOFT
:
2868 if(device
->Type
!= Loopback
)
2870 alcSetError(device
, ALC_INVALID_DEVICE
);
2873 values
[0] = device
->FmtChans
;
2876 case ALC_FORMAT_TYPE_SOFT
:
2877 if(device
->Type
!= Loopback
)
2879 alcSetError(device
, ALC_INVALID_DEVICE
);
2882 values
[0] = device
->FmtType
;
2885 case ALC_MONO_SOURCES
:
2886 values
[0] = device
->NumMonoSources
;
2889 case ALC_STEREO_SOURCES
:
2890 values
[0] = device
->NumStereoSources
;
2893 case ALC_MAX_AUXILIARY_SENDS
:
2894 values
[0] = device
->NumAuxSends
;
2898 values
[0] = device
->Connected
;
2902 values
[0] = (device
->Hrtf
.Handle
? ALC_TRUE
: ALC_FALSE
);
2905 case ALC_HRTF_STATUS_SOFT
:
2906 values
[0] = device
->Hrtf
.Status
;
2909 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
2910 almtx_lock(&device
->BackendLock
);
2911 FreeHrtfList(&device
->Hrtf
.List
);
2912 device
->Hrtf
.List
= EnumerateHrtf(device
->DeviceName
);
2913 values
[0] = (ALCint
)VECTOR_SIZE(device
->Hrtf
.List
);
2914 almtx_unlock(&device
->BackendLock
);
2918 alcSetError(device
, ALC_INVALID_ENUM
);
2926 * Returns information about the device and the version of OpenAL
2928 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2930 VerifyDevice(&device
);
2931 if(size
<= 0 || values
== NULL
)
2932 alcSetError(device
, ALC_INVALID_VALUE
);
2934 GetIntegerv(device
, param
, size
, values
);
2935 if(device
) ALCdevice_DecRef(device
);
2938 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2943 VerifyDevice(&device
);
2944 if(size
<= 0 || values
== NULL
)
2945 alcSetError(device
, ALC_INVALID_VALUE
);
2946 else if(!device
|| device
->Type
== Capture
)
2948 ivals
= malloc(size
* sizeof(ALCint
));
2949 size
= GetIntegerv(device
, pname
, size
, ivals
);
2950 for(i
= 0;i
< size
;i
++)
2951 values
[i
] = ivals
[i
];
2954 else /* render device */
2963 case ALC_ATTRIBUTES_SIZE
:
2967 case ALC_ALL_ATTRIBUTES
:
2969 alcSetError(device
, ALC_INVALID_VALUE
);
2973 almtx_lock(&device
->BackendLock
);
2974 values
[i
++] = ALC_FREQUENCY
;
2975 values
[i
++] = device
->Frequency
;
2977 if(device
->Type
!= Loopback
)
2979 values
[i
++] = ALC_REFRESH
;
2980 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2982 values
[i
++] = ALC_SYNC
;
2983 values
[i
++] = ALC_FALSE
;
2987 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2988 values
[i
++] = device
->FmtChans
;
2990 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2991 values
[i
++] = device
->FmtType
;
2994 values
[i
++] = ALC_MONO_SOURCES
;
2995 values
[i
++] = device
->NumMonoSources
;
2997 values
[i
++] = ALC_STEREO_SOURCES
;
2998 values
[i
++] = device
->NumStereoSources
;
3000 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3001 values
[i
++] = device
->NumAuxSends
;
3003 values
[i
++] = ALC_HRTF_SOFT
;
3004 values
[i
++] = (device
->Hrtf
.Handle
? ALC_TRUE
: ALC_FALSE
);
3006 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3007 values
[i
++] = device
->Hrtf
.Status
;
3009 clock
= V0(device
->Backend
,getClockLatency
)();
3010 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3011 values
[i
++] = clock
.ClockTime
;
3013 values
[i
++] = ALC_DEVICE_LATENCY_SOFT
;
3014 values
[i
++] = clock
.Latency
;
3015 almtx_unlock(&device
->BackendLock
);
3021 case ALC_DEVICE_CLOCK_SOFT
:
3022 almtx_lock(&device
->BackendLock
);
3024 while(((refcount
=ReadRef(&device
->MixCount
))&1) != 0)
3026 basecount
= device
->ClockBase
;
3027 samplecount
= device
->SamplesDone
;
3028 } while(refcount
!= ReadRef(&device
->MixCount
));
3029 *values
= basecount
+ (samplecount
*DEVICE_CLOCK_RES
/device
->Frequency
);
3030 almtx_unlock(&device
->BackendLock
);
3033 case ALC_DEVICE_LATENCY_SOFT
:
3035 almtx_lock(&device
->BackendLock
);
3036 clock
= V0(device
->Backend
,getClockLatency
)();
3037 almtx_unlock(&device
->BackendLock
);
3038 *values
= clock
.Latency
;
3042 case ALC_DEVICE_CLOCK_LATENCY_SOFT
:
3044 alcSetError(device
, ALC_INVALID_VALUE
);
3048 almtx_lock(&device
->BackendLock
);
3049 clock
= V0(device
->Backend
,getClockLatency
)();
3050 almtx_unlock(&device
->BackendLock
);
3051 values
[0] = clock
.ClockTime
;
3052 values
[1] = clock
.Latency
;
3057 ivals
= malloc(size
* sizeof(ALCint
));
3058 size
= GetIntegerv(device
, pname
, size
, ivals
);
3059 for(i
= 0;i
< size
;i
++)
3060 values
[i
] = ivals
[i
];
3066 ALCdevice_DecRef(device
);
3070 /* alcIsExtensionPresent
3072 * Determines if there is support for a particular extension
3074 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3076 ALCboolean bResult
= ALC_FALSE
;
3078 VerifyDevice(&device
);
3081 alcSetError(device
, ALC_INVALID_VALUE
);
3084 size_t len
= strlen(extName
);
3085 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3088 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3089 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3094 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3098 } while(isspace(*ptr
));
3103 ALCdevice_DecRef(device
);
3108 /* alcGetProcAddress
3110 * Retrieves the function address for a particular extension function
3112 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3114 ALCvoid
*ptr
= NULL
;
3118 VerifyDevice(&device
);
3119 alcSetError(device
, ALC_INVALID_VALUE
);
3120 if(device
) ALCdevice_DecRef(device
);
3125 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3127 ptr
= alcFunctions
[i
].address
;
3136 * Get the value for a particular ALC enumeration name
3138 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3144 VerifyDevice(&device
);
3145 alcSetError(device
, ALC_INVALID_VALUE
);
3146 if(device
) ALCdevice_DecRef(device
);
3151 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3153 val
= enumeration
[i
].value
;
3162 * Create and attach a context to the given device.
3164 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3166 ALCcontext
*ALContext
;
3171 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3174 alcSetError(device
, ALC_INVALID_DEVICE
);
3175 if(device
) ALCdevice_DecRef(device
);
3178 almtx_lock(&device
->BackendLock
);
3181 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3183 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3186 InitRef(&ALContext
->ref
, 1);
3187 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3189 ATOMIC_INIT(&ALContext
->ActiveAuxSlotList
, NULL
);
3191 ALContext
->VoiceCount
= 0;
3192 ALContext
->MaxVoices
= 256;
3193 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3195 if(!ALContext
|| !ALContext
->Voices
)
3197 almtx_unlock(&device
->BackendLock
);
3201 al_free(ALContext
->Voices
);
3202 ALContext
->Voices
= NULL
;
3208 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3209 ALCdevice_DecRef(device
);
3213 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3215 almtx_unlock(&device
->BackendLock
);
3217 al_free(ALContext
->Voices
);
3218 ALContext
->Voices
= NULL
;
3223 alcSetError(device
, err
);
3224 if(err
== ALC_INVALID_DEVICE
)
3226 V0(device
->Backend
,lock
)();
3227 aluHandleDisconnect(device
);
3228 V0(device
->Backend
,unlock
)();
3230 ALCdevice_DecRef(device
);
3234 ALContext
->Device
= device
;
3235 ALCdevice_IncRef(device
);
3236 InitContext(ALContext
);
3238 if(ConfigValueFloat(al_string_get_cstr(device
->DeviceName
), NULL
, "volume-adjust", &valf
))
3241 ERR("volume-adjust must be finite: %f\n", valf
);
3244 ALfloat db
= clampf(valf
, -24.0f
, 24.0f
);
3246 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf
, 24.0f
);
3247 ALContext
->GainBoost
= powf(10.0f
, db
/20.0f
);
3248 TRACE("volume-adjust gain: %f\n", ALContext
->GainBoost
);
3251 UpdateListenerProps(ALContext
);
3254 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3256 ALContext
->next
= head
;
3257 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3259 almtx_unlock(&device
->BackendLock
);
3261 ALCdevice_DecRef(device
);
3263 TRACE("Created context %p\n", ALContext
);
3267 /* alcDestroyContext
3269 * Remove a context from its device
3271 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3276 /* alcGetContextsDevice sets an error for invalid contexts */
3277 Device
= alcGetContextsDevice(context
);
3280 almtx_lock(&Device
->BackendLock
);
3281 ReleaseContext(context
, Device
);
3282 if(!ATOMIC_LOAD(&Device
->ContextList
))
3284 V0(Device
->Backend
,stop
)();
3285 Device
->Flags
&= ~DEVICE_RUNNING
;
3287 almtx_unlock(&Device
->BackendLock
);
3293 /* alcGetCurrentContext
3295 * Returns the currently active context on the calling thread
3297 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3299 ALCcontext
*Context
= altss_get(LocalContext
);
3300 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3304 /* alcGetThreadContext
3306 * Returns the currently active thread-local context
3308 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3310 return altss_get(LocalContext
);
3314 /* alcMakeContextCurrent
3316 * Makes the given context the active process-wide context, and removes the
3317 * thread-local context for the calling thread.
3319 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3321 /* context must be valid or NULL */
3322 if(context
&& !VerifyContext(&context
))
3324 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3327 /* context's reference count is already incremented */
3328 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3329 if(context
) ALCcontext_DecRef(context
);
3331 if((context
=altss_get(LocalContext
)) != NULL
)
3333 altss_set(LocalContext
, NULL
);
3334 ALCcontext_DecRef(context
);
3340 /* alcSetThreadContext
3342 * Makes the given context the active context for the current thread
3344 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3348 /* context must be valid or NULL */
3349 if(context
&& !VerifyContext(&context
))
3351 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3354 /* context's reference count is already incremented */
3355 old
= altss_get(LocalContext
);
3356 altss_set(LocalContext
, context
);
3357 if(old
) ALCcontext_DecRef(old
);
3363 /* alcGetContextsDevice
3365 * Returns the device that a particular context is attached to
3367 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3371 if(!VerifyContext(&Context
))
3373 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3376 Device
= Context
->Device
;
3377 ALCcontext_DecRef(Context
);
3385 * Opens the named device.
3387 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3395 if(!PlaybackBackend
.name
)
3397 alcSetError(NULL
, ALC_INVALID_VALUE
);
3401 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3403 /* Some old Windows apps hardcode these expecting OpenAL to use a
3404 * specific audio API, even when they're not enumerated. Creative's
3405 * router effectively ignores them too.
3407 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3408 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3413 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3416 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3421 InitRef(&device
->ref
, 1);
3422 device
->Connected
= ALC_TRUE
;
3423 device
->Type
= Playback
;
3424 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3427 device
->Bs2b
= NULL
;
3428 device
->Uhj_Encoder
= NULL
;
3429 VECTOR_INIT(device
->Hrtf
.List
);
3430 AL_STRING_INIT(device
->Hrtf
.Name
);
3431 device
->Render_Mode
= NormalRender
;
3432 AL_STRING_INIT(device
->DeviceName
);
3433 device
->Dry
.Buffer
= NULL
;
3434 device
->Dry
.NumChannels
= 0;
3435 device
->FOAOut
.Buffer
= NULL
;
3436 device
->FOAOut
.NumChannels
= 0;
3437 device
->RealOut
.Buffer
= NULL
;
3438 device
->RealOut
.NumChannels
= 0;
3440 ATOMIC_INIT(&device
->ContextList
, NULL
);
3442 device
->ClockBase
= 0;
3443 device
->SamplesDone
= 0;
3445 device
->SourcesMax
= 256;
3446 device
->AuxiliaryEffectSlotMax
= 4;
3447 device
->NumAuxSends
= MAX_SENDS
;
3449 InitUIntMap(&device
->BufferMap
, ~0);
3450 InitUIntMap(&device
->EffectMap
, ~0);
3451 InitUIntMap(&device
->FilterMap
, ~0);
3454 device
->FmtChans
= DevFmtChannelsDefault
;
3455 device
->FmtType
= DevFmtTypeDefault
;
3456 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3457 device
->IsHeadphones
= AL_FALSE
;
3458 device
->AmbiFmt
= AmbiFormat_Default
;
3459 device
->NumUpdates
= 4;
3460 device
->UpdateSize
= 1024;
3462 if(!PlaybackBackend
.getFactory
)
3463 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3464 ALCbackend_Playback
);
3467 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3468 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3470 if(!device
->Backend
)
3473 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3478 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3480 static const struct {
3481 const char name
[16];
3482 enum DevFmtChannels chans
;
3484 { "mono", DevFmtMono
},
3485 { "stereo", DevFmtStereo
},
3486 { "quad", DevFmtQuad
},
3487 { "surround51", DevFmtX51
},
3488 { "surround61", DevFmtX61
},
3489 { "surround71", DevFmtX71
},
3490 { "surround51rear", DevFmtX51Rear
},
3491 { "ambi1", DevFmtAmbi1
},
3492 { "ambi2", DevFmtAmbi2
},
3493 { "ambi3", DevFmtAmbi3
},
3497 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3499 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3501 device
->FmtChans
= chanlist
[i
].chans
;
3502 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3506 if(i
== COUNTOF(chanlist
))
3507 ERR("Unsupported channels: %s\n", fmt
);
3509 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3511 static const struct {
3512 const char name
[16];
3513 enum DevFmtType type
;
3515 { "int8", DevFmtByte
},
3516 { "uint8", DevFmtUByte
},
3517 { "int16", DevFmtShort
},
3518 { "uint16", DevFmtUShort
},
3519 { "int32", DevFmtInt
},
3520 { "uint32", DevFmtUInt
},
3521 { "float32", DevFmtFloat
},
3525 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3527 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3529 device
->FmtType
= typelist
[i
].type
;
3530 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3534 if(i
== COUNTOF(typelist
))
3535 ERR("Unsupported sample-type: %s\n", fmt
);
3538 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3540 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3541 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3542 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3543 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3546 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3547 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3549 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3550 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3551 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3552 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3554 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
3555 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
3557 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3558 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3560 ConfigValueUInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3561 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3563 device
->NumStereoSources
= 1;
3564 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
3566 // Find a playback device to open
3567 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3569 DELETE_OBJ(device
->Backend
);
3571 alcSetError(NULL
, err
);
3574 almtx_init(&device
->BackendLock
, almtx_plain
);
3576 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "ambi-format", &fmt
))
3578 if(strcasecmp(fmt
, "fuma") == 0)
3579 device
->AmbiFmt
= AmbiFormat_FuMa
;
3580 else if(strcasecmp(fmt
, "acn+sn3d") == 0)
3581 device
->AmbiFmt
= AmbiFormat_ACN_SN3D
;
3582 else if(strcasecmp(fmt
, "acn+n3d") == 0)
3583 device
->AmbiFmt
= AmbiFormat_ACN_N3D
;
3585 ERR("Unsupported ambi-format: %s\n", fmt
);
3588 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3590 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3591 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3593 device
->DefaultSlot
= NULL
;
3594 ERR("Failed to initialize the default effect slot\n");
3598 aluInitEffectPanning(device
->DefaultSlot
);
3599 if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3601 DeinitEffectSlot(device
->DefaultSlot
);
3602 device
->DefaultSlot
= NULL
;
3603 ERR("Failed to initialize the default effect\n");
3609 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3611 device
->next
= head
;
3612 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3615 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3621 * Closes the given device.
3623 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3625 ALCdevice
*iter
, *origdev
;
3629 iter
= ATOMIC_LOAD(&DeviceList
);
3633 } while((iter
=iter
->next
) != NULL
);
3634 if(!iter
|| iter
->Type
== Capture
)
3636 alcSetError(iter
, ALC_INVALID_DEVICE
);
3640 almtx_lock(&device
->BackendLock
);
3643 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, device
->next
))
3645 ALCdevice
*volatile*list
= &origdev
->next
;
3650 *list
= (*list
)->next
;
3653 list
= &(*list
)->next
;
3658 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3661 ALCcontext
*next
= ctx
->next
;
3662 WARN("Releasing context %p\n", ctx
);
3663 ReleaseContext(ctx
, device
);
3666 if((device
->Flags
&DEVICE_RUNNING
))
3667 V0(device
->Backend
,stop
)();
3668 device
->Flags
&= ~DEVICE_RUNNING
;
3669 almtx_unlock(&device
->BackendLock
);
3671 ALCdevice_DecRef(device
);
3677 /************************************************
3678 * ALC capture functions
3679 ************************************************/
3680 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3682 ALCdevice
*device
= NULL
;
3687 if(!CaptureBackend
.name
)
3689 alcSetError(NULL
, ALC_INVALID_VALUE
);
3695 alcSetError(NULL
, ALC_INVALID_VALUE
);
3699 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3702 device
= al_calloc(16, sizeof(ALCdevice
));
3705 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3710 InitRef(&device
->ref
, 1);
3711 device
->Connected
= ALC_TRUE
;
3712 device
->Type
= Capture
;
3714 VECTOR_INIT(device
->Hrtf
.List
);
3715 AL_STRING_INIT(device
->Hrtf
.Name
);
3717 AL_STRING_INIT(device
->DeviceName
);
3718 device
->Dry
.Buffer
= NULL
;
3719 device
->Dry
.NumChannels
= 0;
3720 device
->FOAOut
.Buffer
= NULL
;
3721 device
->FOAOut
.NumChannels
= 0;
3722 device
->RealOut
.Buffer
= NULL
;
3723 device
->RealOut
.NumChannels
= 0;
3725 InitUIntMap(&device
->BufferMap
, ~0);
3726 InitUIntMap(&device
->EffectMap
, ~0);
3727 InitUIntMap(&device
->FilterMap
, ~0);
3729 if(!CaptureBackend
.getFactory
)
3730 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3731 ALCbackend_Capture
);
3734 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3735 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3737 if(!device
->Backend
)
3740 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3744 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3745 device
->Frequency
= frequency
;
3747 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3748 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3751 alcSetError(NULL
, ALC_INVALID_ENUM
);
3754 device
->IsHeadphones
= AL_FALSE
;
3755 device
->AmbiFmt
= AmbiFormat_Default
;
3757 device
->UpdateSize
= samples
;
3758 device
->NumUpdates
= 1;
3760 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3763 alcSetError(NULL
, err
);
3766 almtx_init(&device
->BackendLock
, almtx_plain
);
3769 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3771 device
->next
= head
;
3772 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3775 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3779 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3781 ALCdevice
*iter
, *origdev
;
3784 iter
= ATOMIC_LOAD(&DeviceList
);
3788 } while((iter
=iter
->next
) != NULL
);
3789 if(!iter
|| iter
->Type
!= Capture
)
3791 alcSetError(iter
, ALC_INVALID_DEVICE
);
3797 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, device
->next
))
3799 ALCdevice
*volatile*list
= &origdev
->next
;
3804 *list
= (*list
)->next
;
3807 list
= &(*list
)->next
;
3812 ALCdevice_DecRef(device
);
3817 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3819 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3820 alcSetError(device
, ALC_INVALID_DEVICE
);
3823 almtx_lock(&device
->BackendLock
);
3824 if(!device
->Connected
)
3825 alcSetError(device
, ALC_INVALID_DEVICE
);
3826 else if(!(device
->Flags
&DEVICE_RUNNING
))
3828 if(V0(device
->Backend
,start
)())
3829 device
->Flags
|= DEVICE_RUNNING
;
3832 aluHandleDisconnect(device
);
3833 alcSetError(device
, ALC_INVALID_DEVICE
);
3836 almtx_unlock(&device
->BackendLock
);
3839 if(device
) ALCdevice_DecRef(device
);
3842 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3844 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3845 alcSetError(device
, ALC_INVALID_DEVICE
);
3848 almtx_lock(&device
->BackendLock
);
3849 if((device
->Flags
&DEVICE_RUNNING
))
3850 V0(device
->Backend
,stop
)();
3851 device
->Flags
&= ~DEVICE_RUNNING
;
3852 almtx_unlock(&device
->BackendLock
);
3855 if(device
) ALCdevice_DecRef(device
);
3858 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3860 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3861 alcSetError(device
, ALC_INVALID_DEVICE
);
3864 ALCenum err
= ALC_INVALID_VALUE
;
3866 almtx_lock(&device
->BackendLock
);
3867 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3868 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3869 almtx_unlock(&device
->BackendLock
);
3871 if(err
!= ALC_NO_ERROR
)
3872 alcSetError(device
, err
);
3874 if(device
) ALCdevice_DecRef(device
);
3878 /************************************************
3879 * ALC loopback functions
3880 ************************************************/
3882 /* alcLoopbackOpenDeviceSOFT
3884 * Open a loopback device, for manual rendering.
3886 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3888 ALCbackendFactory
*factory
;
3893 /* Make sure the device name, if specified, is us. */
3894 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3896 alcSetError(NULL
, ALC_INVALID_VALUE
);
3900 device
= al_calloc(16, sizeof(ALCdevice
));
3903 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3908 InitRef(&device
->ref
, 1);
3909 device
->Connected
= ALC_TRUE
;
3910 device
->Type
= Loopback
;
3911 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3914 VECTOR_INIT(device
->Hrtf
.List
);
3915 AL_STRING_INIT(device
->Hrtf
.Name
);
3916 device
->Bs2b
= NULL
;
3917 device
->Uhj_Encoder
= NULL
;
3918 device
->Render_Mode
= NormalRender
;
3919 AL_STRING_INIT(device
->DeviceName
);
3920 device
->Dry
.Buffer
= NULL
;
3921 device
->Dry
.NumChannels
= 0;
3922 device
->FOAOut
.Buffer
= NULL
;
3923 device
->FOAOut
.NumChannels
= 0;
3924 device
->RealOut
.Buffer
= NULL
;
3925 device
->RealOut
.NumChannels
= 0;
3927 ATOMIC_INIT(&device
->ContextList
, NULL
);
3929 device
->ClockBase
= 0;
3930 device
->SamplesDone
= 0;
3932 device
->SourcesMax
= 256;
3933 device
->AuxiliaryEffectSlotMax
= 4;
3934 device
->NumAuxSends
= MAX_SENDS
;
3936 InitUIntMap(&device
->BufferMap
, ~0);
3937 InitUIntMap(&device
->EffectMap
, ~0);
3938 InitUIntMap(&device
->FilterMap
, ~0);
3940 factory
= ALCloopbackFactory_getFactory();
3941 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3942 if(!device
->Backend
)
3945 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3948 almtx_init(&device
->BackendLock
, almtx_plain
);
3951 device
->NumUpdates
= 0;
3952 device
->UpdateSize
= 0;
3954 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3955 device
->FmtChans
= DevFmtChannelsDefault
;
3956 device
->FmtType
= DevFmtTypeDefault
;
3957 device
->IsHeadphones
= AL_FALSE
;
3958 device
->AmbiFmt
= AmbiFormat_Default
;
3960 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
3961 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
3963 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3964 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3966 ConfigValueUInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
3967 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3969 device
->NumStereoSources
= 1;
3970 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
3972 // Open the "backend"
3973 V(device
->Backend
,open
)("Loopback");
3976 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3978 device
->next
= head
;
3979 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3982 TRACE("Created device %p\n", device
);
3986 /* alcIsRenderFormatSupportedSOFT
3988 * Determines if the loopback device supports the given format for rendering.
3990 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3992 ALCboolean ret
= ALC_FALSE
;
3994 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3995 alcSetError(device
, ALC_INVALID_DEVICE
);
3997 alcSetError(device
, ALC_INVALID_VALUE
);
4000 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
4001 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
4002 freq
>= MIN_OUTPUT_RATE
)
4005 if(device
) ALCdevice_DecRef(device
);
4010 /* alcRenderSamplesSOFT
4012 * Renders some samples into a buffer, using the format last set by the
4013 * attributes given to alcCreateContext.
4015 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4017 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4018 alcSetError(device
, ALC_INVALID_DEVICE
);
4019 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
4020 alcSetError(device
, ALC_INVALID_VALUE
);
4022 aluMixData(device
, buffer
, samples
);
4023 if(device
) ALCdevice_DecRef(device
);
4027 /************************************************
4028 * ALC DSP pause/resume functions
4029 ************************************************/
4031 /* alcDevicePauseSOFT
4033 * Pause the DSP to stop audio processing.
4035 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
4037 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4038 alcSetError(device
, ALC_INVALID_DEVICE
);
4041 almtx_lock(&device
->BackendLock
);
4042 if((device
->Flags
&DEVICE_RUNNING
))
4043 V0(device
->Backend
,stop
)();
4044 device
->Flags
&= ~DEVICE_RUNNING
;
4045 device
->Flags
|= DEVICE_PAUSED
;
4046 almtx_unlock(&device
->BackendLock
);
4048 if(device
) ALCdevice_DecRef(device
);
4051 /* alcDeviceResumeSOFT
4053 * Resume the DSP to restart audio processing.
4055 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
4057 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4058 alcSetError(device
, ALC_INVALID_DEVICE
);
4061 almtx_lock(&device
->BackendLock
);
4062 if((device
->Flags
&DEVICE_PAUSED
))
4064 device
->Flags
&= ~DEVICE_PAUSED
;
4065 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
4067 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4068 device
->Flags
|= DEVICE_RUNNING
;
4071 alcSetError(device
, ALC_INVALID_DEVICE
);
4072 V0(device
->Backend
,lock
)();
4073 aluHandleDisconnect(device
);
4074 V0(device
->Backend
,unlock
)();
4078 almtx_unlock(&device
->BackendLock
);
4080 if(device
) ALCdevice_DecRef(device
);
4084 /************************************************
4085 * ALC HRTF functions
4086 ************************************************/
4088 /* alcGetStringiSOFT
4090 * Gets a string parameter at the given index.
4092 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4094 const ALCchar
*str
= NULL
;
4096 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4097 alcSetError(device
, ALC_INVALID_DEVICE
);
4098 else switch(paramName
)
4100 case ALC_HRTF_SPECIFIER_SOFT
:
4101 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->Hrtf
.List
))
4102 str
= al_string_get_cstr(VECTOR_ELEM(device
->Hrtf
.List
, index
).name
);
4104 alcSetError(device
, ALC_INVALID_VALUE
);
4108 alcSetError(device
, ALC_INVALID_ENUM
);
4111 if(device
) ALCdevice_DecRef(device
);
4116 /* alcResetDeviceSOFT
4118 * Resets the given device output, using the specified attribute list.
4120 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4125 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4128 alcSetError(device
, ALC_INVALID_DEVICE
);
4129 if(device
) ALCdevice_DecRef(device
);
4132 almtx_lock(&device
->BackendLock
);
4135 err
= UpdateDeviceParams(device
, attribs
);
4136 almtx_unlock(&device
->BackendLock
);
4138 if(err
!= ALC_NO_ERROR
)
4140 alcSetError(device
, err
);
4141 if(err
== ALC_INVALID_DEVICE
)
4143 V0(device
->Backend
,lock
)();
4144 aluHandleDisconnect(device
);
4145 V0(device
->Backend
,unlock
)();
4147 ALCdevice_DecRef(device
);
4150 ALCdevice_DecRef(device
);