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
34 #include "alListener.h"
38 #include "alAuxEffectSlot.h"
40 #include "bformatdec.h"
48 #include "backends/base.h"
51 /************************************************
53 ************************************************/
56 ALCbackendFactory
* (*getFactory
)(void);
59 static struct BackendInfo BackendList
[] = {
61 { "jack", ALCjackBackendFactory_getFactory
},
63 #ifdef HAVE_PULSEAUDIO
64 { "pulse", ALCpulseBackendFactory_getFactory
},
67 { "alsa", ALCalsaBackendFactory_getFactory
},
70 { "core", ALCcoreAudioBackendFactory_getFactory
},
73 { "oss", ALCossBackendFactory_getFactory
},
76 { "solaris", ALCsolarisBackendFactory_getFactory
},
79 { "sndio", ALCsndioBackendFactory_getFactory
},
82 { "qsa", ALCqsaBackendFactory_getFactory
},
85 { "mmdevapi", ALCmmdevBackendFactory_getFactory
},
88 { "dsound", ALCdsoundBackendFactory_getFactory
},
91 { "winmm", ALCwinmmBackendFactory_getFactory
},
94 { "port", ALCportBackendFactory_getFactory
},
97 { "opensl", ALCopenslBackendFactory_getFactory
},
100 { "null", ALCnullBackendFactory_getFactory
},
102 { "wave", ALCwaveBackendFactory_getFactory
},
105 static ALsizei BackendListSize
= COUNTOF(BackendList
);
108 static struct BackendInfo PlaybackBackend
;
109 static struct BackendInfo CaptureBackend
;
112 /************************************************
113 * Functions, enums, and errors
114 ************************************************/
115 #define DECL(x) { #x, (ALCvoid*)(x) }
116 static const struct {
117 const ALCchar
*funcName
;
120 DECL(alcCreateContext
),
121 DECL(alcMakeContextCurrent
),
122 DECL(alcProcessContext
),
123 DECL(alcSuspendContext
),
124 DECL(alcDestroyContext
),
125 DECL(alcGetCurrentContext
),
126 DECL(alcGetContextsDevice
),
128 DECL(alcCloseDevice
),
130 DECL(alcIsExtensionPresent
),
131 DECL(alcGetProcAddress
),
132 DECL(alcGetEnumValue
),
134 DECL(alcGetIntegerv
),
135 DECL(alcCaptureOpenDevice
),
136 DECL(alcCaptureCloseDevice
),
137 DECL(alcCaptureStart
),
138 DECL(alcCaptureStop
),
139 DECL(alcCaptureSamples
),
141 DECL(alcSetThreadContext
),
142 DECL(alcGetThreadContext
),
144 DECL(alcLoopbackOpenDeviceSOFT
),
145 DECL(alcIsRenderFormatSupportedSOFT
),
146 DECL(alcRenderSamplesSOFT
),
148 DECL(alcIsAmbisonicFormatSupportedSOFT
),
150 DECL(alcDevicePauseSOFT
),
151 DECL(alcDeviceResumeSOFT
),
153 DECL(alcGetStringiSOFT
),
154 DECL(alcResetDeviceSOFT
),
156 DECL(alcGetInteger64vSOFT
),
171 DECL(alIsExtensionPresent
),
172 DECL(alGetProcAddress
),
173 DECL(alGetEnumValue
),
180 DECL(alGetListenerf
),
181 DECL(alGetListener3f
),
182 DECL(alGetListenerfv
),
183 DECL(alGetListeneri
),
184 DECL(alGetListener3i
),
185 DECL(alGetListeneriv
),
187 DECL(alDeleteSources
),
203 DECL(alSourceRewindv
),
204 DECL(alSourcePausev
),
207 DECL(alSourceRewind
),
209 DECL(alSourceQueueBuffers
),
210 DECL(alSourceUnqueueBuffers
),
212 DECL(alDeleteBuffers
),
227 DECL(alDopplerFactor
),
228 DECL(alDopplerVelocity
),
229 DECL(alSpeedOfSound
),
230 DECL(alDistanceModel
),
233 DECL(alDeleteFilters
),
244 DECL(alDeleteEffects
),
254 DECL(alGenAuxiliaryEffectSlots
),
255 DECL(alDeleteAuxiliaryEffectSlots
),
256 DECL(alIsAuxiliaryEffectSlot
),
257 DECL(alAuxiliaryEffectSloti
),
258 DECL(alAuxiliaryEffectSlotiv
),
259 DECL(alAuxiliaryEffectSlotf
),
260 DECL(alAuxiliaryEffectSlotfv
),
261 DECL(alGetAuxiliaryEffectSloti
),
262 DECL(alGetAuxiliaryEffectSlotiv
),
263 DECL(alGetAuxiliaryEffectSlotf
),
264 DECL(alGetAuxiliaryEffectSlotfv
),
266 DECL(alDeferUpdatesSOFT
),
267 DECL(alProcessUpdatesSOFT
),
270 DECL(alSource3dSOFT
),
271 DECL(alSourcedvSOFT
),
272 DECL(alGetSourcedSOFT
),
273 DECL(alGetSource3dSOFT
),
274 DECL(alGetSourcedvSOFT
),
275 DECL(alSourcei64SOFT
),
276 DECL(alSource3i64SOFT
),
277 DECL(alSourcei64vSOFT
),
278 DECL(alGetSourcei64SOFT
),
279 DECL(alGetSource3i64SOFT
),
280 DECL(alGetSourcei64vSOFT
),
282 DECL(alBufferSamplesSOFT
),
283 DECL(alGetBufferSamplesSOFT
),
284 DECL(alIsBufferFormatSupportedSOFT
),
286 DECL(alGetStringiSOFT
),
290 #define DECL(x) { #x, (x) }
291 static const struct {
292 const ALCchar
*enumName
;
294 } alcEnumerations
[] = {
299 DECL(ALC_MAJOR_VERSION
),
300 DECL(ALC_MINOR_VERSION
),
301 DECL(ALC_ATTRIBUTES_SIZE
),
302 DECL(ALC_ALL_ATTRIBUTES
),
303 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
304 DECL(ALC_DEVICE_SPECIFIER
),
305 DECL(ALC_ALL_DEVICES_SPECIFIER
),
306 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
307 DECL(ALC_EXTENSIONS
),
311 DECL(ALC_MONO_SOURCES
),
312 DECL(ALC_STEREO_SOURCES
),
313 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
314 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
315 DECL(ALC_CAPTURE_SAMPLES
),
318 DECL(ALC_EFX_MAJOR_VERSION
),
319 DECL(ALC_EFX_MINOR_VERSION
),
320 DECL(ALC_MAX_AUXILIARY_SENDS
),
322 DECL(ALC_FORMAT_CHANNELS_SOFT
),
323 DECL(ALC_FORMAT_TYPE_SOFT
),
326 DECL(ALC_STEREO_SOFT
),
328 DECL(ALC_5POINT1_SOFT
),
329 DECL(ALC_6POINT1_SOFT
),
330 DECL(ALC_7POINT1_SOFT
),
331 DECL(ALC_BFORMAT3D_SOFT
),
334 DECL(ALC_UNSIGNED_BYTE_SOFT
),
335 DECL(ALC_SHORT_SOFT
),
336 DECL(ALC_UNSIGNED_SHORT_SOFT
),
338 DECL(ALC_UNSIGNED_INT_SOFT
),
339 DECL(ALC_FLOAT_SOFT
),
342 DECL(ALC_DONT_CARE_SOFT
),
343 DECL(ALC_HRTF_STATUS_SOFT
),
344 DECL(ALC_HRTF_DISABLED_SOFT
),
345 DECL(ALC_HRTF_ENABLED_SOFT
),
346 DECL(ALC_HRTF_DENIED_SOFT
),
347 DECL(ALC_HRTF_REQUIRED_SOFT
),
348 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
349 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
350 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
351 DECL(ALC_HRTF_SPECIFIER_SOFT
),
352 DECL(ALC_HRTF_ID_SOFT
),
354 DECL(ALC_AMBISONIC_LAYOUT_SOFT
),
355 DECL(ALC_AMBISONIC_SCALING_SOFT
),
356 DECL(ALC_AMBISONIC_ORDER_SOFT
),
362 DECL(ALC_OUTPUT_LIMITER_SOFT
),
365 DECL(ALC_INVALID_DEVICE
),
366 DECL(ALC_INVALID_CONTEXT
),
367 DECL(ALC_INVALID_ENUM
),
368 DECL(ALC_INVALID_VALUE
),
369 DECL(ALC_OUT_OF_MEMORY
),
377 DECL(AL_SOURCE_RELATIVE
),
378 DECL(AL_CONE_INNER_ANGLE
),
379 DECL(AL_CONE_OUTER_ANGLE
),
389 DECL(AL_ORIENTATION
),
390 DECL(AL_REFERENCE_DISTANCE
),
391 DECL(AL_ROLLOFF_FACTOR
),
392 DECL(AL_CONE_OUTER_GAIN
),
393 DECL(AL_MAX_DISTANCE
),
395 DECL(AL_SAMPLE_OFFSET
),
396 DECL(AL_BYTE_OFFSET
),
397 DECL(AL_SOURCE_TYPE
),
400 DECL(AL_UNDETERMINED
),
401 DECL(AL_METERS_PER_UNIT
),
402 DECL(AL_LOOP_POINTS_SOFT
),
403 DECL(AL_DIRECT_CHANNELS_SOFT
),
405 DECL(AL_DIRECT_FILTER
),
406 DECL(AL_AUXILIARY_SEND_FILTER
),
407 DECL(AL_AIR_ABSORPTION_FACTOR
),
408 DECL(AL_ROOM_ROLLOFF_FACTOR
),
409 DECL(AL_CONE_OUTER_GAINHF
),
410 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
412 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
414 DECL(AL_SOURCE_STATE
),
420 DECL(AL_BUFFERS_QUEUED
),
421 DECL(AL_BUFFERS_PROCESSED
),
423 DECL(AL_FORMAT_MONO8
),
424 DECL(AL_FORMAT_MONO16
),
425 DECL(AL_FORMAT_MONO_FLOAT32
),
426 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
427 DECL(AL_FORMAT_STEREO8
),
428 DECL(AL_FORMAT_STEREO16
),
429 DECL(AL_FORMAT_STEREO_FLOAT32
),
430 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
431 DECL(AL_FORMAT_MONO_IMA4
),
432 DECL(AL_FORMAT_STEREO_IMA4
),
433 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
434 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
435 DECL(AL_FORMAT_QUAD8_LOKI
),
436 DECL(AL_FORMAT_QUAD16_LOKI
),
437 DECL(AL_FORMAT_QUAD8
),
438 DECL(AL_FORMAT_QUAD16
),
439 DECL(AL_FORMAT_QUAD32
),
440 DECL(AL_FORMAT_51CHN8
),
441 DECL(AL_FORMAT_51CHN16
),
442 DECL(AL_FORMAT_51CHN32
),
443 DECL(AL_FORMAT_61CHN8
),
444 DECL(AL_FORMAT_61CHN16
),
445 DECL(AL_FORMAT_61CHN32
),
446 DECL(AL_FORMAT_71CHN8
),
447 DECL(AL_FORMAT_71CHN16
),
448 DECL(AL_FORMAT_71CHN32
),
449 DECL(AL_FORMAT_REAR8
),
450 DECL(AL_FORMAT_REAR16
),
451 DECL(AL_FORMAT_REAR32
),
452 DECL(AL_FORMAT_MONO_MULAW
),
453 DECL(AL_FORMAT_MONO_MULAW_EXT
),
454 DECL(AL_FORMAT_STEREO_MULAW
),
455 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
456 DECL(AL_FORMAT_QUAD_MULAW
),
457 DECL(AL_FORMAT_51CHN_MULAW
),
458 DECL(AL_FORMAT_61CHN_MULAW
),
459 DECL(AL_FORMAT_71CHN_MULAW
),
460 DECL(AL_FORMAT_REAR_MULAW
),
461 DECL(AL_FORMAT_MONO_ALAW_EXT
),
462 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
464 DECL(AL_FORMAT_BFORMAT2D_8
),
465 DECL(AL_FORMAT_BFORMAT2D_16
),
466 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
467 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
468 DECL(AL_FORMAT_BFORMAT3D_8
),
469 DECL(AL_FORMAT_BFORMAT3D_16
),
470 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
471 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
474 DECL(AL_MONO16_SOFT
),
475 DECL(AL_MONO32F_SOFT
),
476 DECL(AL_STEREO8_SOFT
),
477 DECL(AL_STEREO16_SOFT
),
478 DECL(AL_STEREO32F_SOFT
),
480 DECL(AL_QUAD16_SOFT
),
481 DECL(AL_QUAD32F_SOFT
),
483 DECL(AL_REAR16_SOFT
),
484 DECL(AL_REAR32F_SOFT
),
485 DECL(AL_5POINT1_8_SOFT
),
486 DECL(AL_5POINT1_16_SOFT
),
487 DECL(AL_5POINT1_32F_SOFT
),
488 DECL(AL_6POINT1_8_SOFT
),
489 DECL(AL_6POINT1_16_SOFT
),
490 DECL(AL_6POINT1_32F_SOFT
),
491 DECL(AL_7POINT1_8_SOFT
),
492 DECL(AL_7POINT1_16_SOFT
),
493 DECL(AL_7POINT1_32F_SOFT
),
494 DECL(AL_BFORMAT2D_8_SOFT
),
495 DECL(AL_BFORMAT2D_16_SOFT
),
496 DECL(AL_BFORMAT2D_32F_SOFT
),
497 DECL(AL_BFORMAT3D_8_SOFT
),
498 DECL(AL_BFORMAT3D_16_SOFT
),
499 DECL(AL_BFORMAT3D_32F_SOFT
),
502 DECL(AL_STEREO_SOFT
),
505 DECL(AL_5POINT1_SOFT
),
506 DECL(AL_6POINT1_SOFT
),
507 DECL(AL_7POINT1_SOFT
),
508 DECL(AL_BFORMAT2D_SOFT
),
509 DECL(AL_BFORMAT3D_SOFT
),
512 DECL(AL_UNSIGNED_BYTE_SOFT
),
514 DECL(AL_UNSIGNED_SHORT_SOFT
),
516 DECL(AL_UNSIGNED_INT_SOFT
),
518 DECL(AL_DOUBLE_SOFT
),
520 DECL(AL_UNSIGNED_BYTE3_SOFT
),
527 DECL(AL_INTERNAL_FORMAT_SOFT
),
528 DECL(AL_BYTE_LENGTH_SOFT
),
529 DECL(AL_SAMPLE_LENGTH_SOFT
),
530 DECL(AL_SEC_LENGTH_SOFT
),
531 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
532 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
534 DECL(AL_SOURCE_RADIUS
),
536 DECL(AL_STEREO_ANGLES
),
543 DECL(AL_INVALID_NAME
),
544 DECL(AL_INVALID_ENUM
),
545 DECL(AL_INVALID_VALUE
),
546 DECL(AL_INVALID_OPERATION
),
547 DECL(AL_OUT_OF_MEMORY
),
554 DECL(AL_DOPPLER_FACTOR
),
555 DECL(AL_DOPPLER_VELOCITY
),
556 DECL(AL_DISTANCE_MODEL
),
557 DECL(AL_SPEED_OF_SOUND
),
558 DECL(AL_SOURCE_DISTANCE_MODEL
),
559 DECL(AL_DEFERRED_UPDATES_SOFT
),
560 DECL(AL_GAIN_LIMIT_SOFT
),
562 DECL(AL_INVERSE_DISTANCE
),
563 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
564 DECL(AL_LINEAR_DISTANCE
),
565 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
566 DECL(AL_EXPONENT_DISTANCE
),
567 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
569 DECL(AL_FILTER_TYPE
),
570 DECL(AL_FILTER_NULL
),
571 DECL(AL_FILTER_LOWPASS
),
572 DECL(AL_FILTER_HIGHPASS
),
573 DECL(AL_FILTER_BANDPASS
),
575 DECL(AL_LOWPASS_GAIN
),
576 DECL(AL_LOWPASS_GAINHF
),
578 DECL(AL_HIGHPASS_GAIN
),
579 DECL(AL_HIGHPASS_GAINLF
),
581 DECL(AL_BANDPASS_GAIN
),
582 DECL(AL_BANDPASS_GAINHF
),
583 DECL(AL_BANDPASS_GAINLF
),
585 DECL(AL_EFFECT_TYPE
),
586 DECL(AL_EFFECT_NULL
),
587 DECL(AL_EFFECT_REVERB
),
588 DECL(AL_EFFECT_EAXREVERB
),
589 DECL(AL_EFFECT_CHORUS
),
590 DECL(AL_EFFECT_DISTORTION
),
591 DECL(AL_EFFECT_ECHO
),
592 DECL(AL_EFFECT_FLANGER
),
594 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
595 DECL(AL_EFFECT_VOCAL_MORPHER
),
596 DECL(AL_EFFECT_PITCH_SHIFTER
),
598 DECL(AL_EFFECT_RING_MODULATOR
),
600 DECL(AL_EFFECT_AUTOWAH
),
602 DECL(AL_EFFECT_COMPRESSOR
),
603 DECL(AL_EFFECT_EQUALIZER
),
604 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
605 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
607 DECL(AL_EFFECTSLOT_EFFECT
),
608 DECL(AL_EFFECTSLOT_GAIN
),
609 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
),
610 DECL(AL_EFFECTSLOT_NULL
),
612 DECL(AL_EAXREVERB_DENSITY
),
613 DECL(AL_EAXREVERB_DIFFUSION
),
614 DECL(AL_EAXREVERB_GAIN
),
615 DECL(AL_EAXREVERB_GAINHF
),
616 DECL(AL_EAXREVERB_GAINLF
),
617 DECL(AL_EAXREVERB_DECAY_TIME
),
618 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
619 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
620 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
621 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
622 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
623 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
624 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
625 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
626 DECL(AL_EAXREVERB_ECHO_TIME
),
627 DECL(AL_EAXREVERB_ECHO_DEPTH
),
628 DECL(AL_EAXREVERB_MODULATION_TIME
),
629 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
630 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
631 DECL(AL_EAXREVERB_HFREFERENCE
),
632 DECL(AL_EAXREVERB_LFREFERENCE
),
633 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
634 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
636 DECL(AL_REVERB_DENSITY
),
637 DECL(AL_REVERB_DIFFUSION
),
638 DECL(AL_REVERB_GAIN
),
639 DECL(AL_REVERB_GAINHF
),
640 DECL(AL_REVERB_DECAY_TIME
),
641 DECL(AL_REVERB_DECAY_HFRATIO
),
642 DECL(AL_REVERB_REFLECTIONS_GAIN
),
643 DECL(AL_REVERB_REFLECTIONS_DELAY
),
644 DECL(AL_REVERB_LATE_REVERB_GAIN
),
645 DECL(AL_REVERB_LATE_REVERB_DELAY
),
646 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
647 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
648 DECL(AL_REVERB_DECAY_HFLIMIT
),
650 DECL(AL_CHORUS_WAVEFORM
),
651 DECL(AL_CHORUS_PHASE
),
652 DECL(AL_CHORUS_RATE
),
653 DECL(AL_CHORUS_DEPTH
),
654 DECL(AL_CHORUS_FEEDBACK
),
655 DECL(AL_CHORUS_DELAY
),
657 DECL(AL_DISTORTION_EDGE
),
658 DECL(AL_DISTORTION_GAIN
),
659 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
660 DECL(AL_DISTORTION_EQCENTER
),
661 DECL(AL_DISTORTION_EQBANDWIDTH
),
664 DECL(AL_ECHO_LRDELAY
),
665 DECL(AL_ECHO_DAMPING
),
666 DECL(AL_ECHO_FEEDBACK
),
667 DECL(AL_ECHO_SPREAD
),
669 DECL(AL_FLANGER_WAVEFORM
),
670 DECL(AL_FLANGER_PHASE
),
671 DECL(AL_FLANGER_RATE
),
672 DECL(AL_FLANGER_DEPTH
),
673 DECL(AL_FLANGER_FEEDBACK
),
674 DECL(AL_FLANGER_DELAY
),
676 DECL(AL_RING_MODULATOR_FREQUENCY
),
677 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
678 DECL(AL_RING_MODULATOR_WAVEFORM
),
680 DECL(AL_COMPRESSOR_ONOFF
),
682 DECL(AL_EQUALIZER_LOW_GAIN
),
683 DECL(AL_EQUALIZER_LOW_CUTOFF
),
684 DECL(AL_EQUALIZER_MID1_GAIN
),
685 DECL(AL_EQUALIZER_MID1_CENTER
),
686 DECL(AL_EQUALIZER_MID1_WIDTH
),
687 DECL(AL_EQUALIZER_MID2_GAIN
),
688 DECL(AL_EQUALIZER_MID2_CENTER
),
689 DECL(AL_EQUALIZER_MID2_WIDTH
),
690 DECL(AL_EQUALIZER_HIGH_GAIN
),
691 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
693 DECL(AL_DEDICATED_GAIN
),
695 DECL(AL_NUM_RESAMPLERS_SOFT
),
696 DECL(AL_DEFAULT_RESAMPLER_SOFT
),
697 DECL(AL_SOURCE_RESAMPLER_SOFT
),
698 DECL(AL_RESAMPLER_NAME_SOFT
),
700 DECL(AL_SOURCE_SPATIALIZE_SOFT
),
705 static const ALCchar alcNoError
[] = "No Error";
706 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
707 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
708 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
709 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
710 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
713 /************************************************
715 ************************************************/
717 /* Enumerated device names */
718 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
720 static al_string alcAllDevicesList
;
721 static al_string alcCaptureDeviceList
;
723 /* Default is always the first in the list */
724 static ALCchar
*alcDefaultAllDevicesSpecifier
;
725 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
727 /* Default context extensions */
728 static const ALchar alExtList
[] =
729 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
730 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
731 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
732 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
733 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
734 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
735 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length "
736 "AL_SOFT_source_resampler AL_SOFT_source_spatialize";
738 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
740 /* Thread-local current context */
741 static altss_t LocalContext
;
742 /* Process-wide current context */
743 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
745 /* Mixing thread piority level */
750 enum LogLevel LogLevel
= LogWarning
;
752 enum LogLevel LogLevel
= LogError
;
755 /* Flag to trap ALC device errors */
756 static ALCboolean TrapALCError
= ALC_FALSE
;
758 /* One-time configuration init control */
759 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
761 /* Default effect that applies to sources that don't have an effect on send 0 */
762 static ALeffect DefaultEffect
;
764 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
767 static ALCboolean SuspendDefers
= ALC_TRUE
;
770 /************************************************
772 ************************************************/
773 static const ALCchar alcNoDeviceExtList
[] =
774 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
775 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
776 static const ALCchar alcExtensionList
[] =
777 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
778 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
779 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
780 "ALC_SOFT_loopback ALC_SOFT_output_limiter ALC_SOFT_pause_device";
781 static const ALCint alcMajorVersion
= 1;
782 static const ALCint alcMinorVersion
= 1;
784 static const ALCint alcEFXMajorVersion
= 1;
785 static const ALCint alcEFXMinorVersion
= 0;
788 /************************************************
790 ************************************************/
791 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
793 static almtx_t ListLock
;
794 static inline void LockLists(void)
796 int ret
= almtx_lock(&ListLock
);
797 assert(ret
== althrd_success
);
799 static inline void UnlockLists(void)
801 int ret
= almtx_unlock(&ListLock
);
802 assert(ret
== althrd_success
);
805 /************************************************
806 * Library initialization
807 ************************************************/
809 static void alc_init(void);
810 static void alc_deinit(void);
811 static void alc_deinit_safe(void);
813 #ifndef AL_LIBTYPE_STATIC
814 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
818 case DLL_PROCESS_ATTACH
:
819 /* Pin the DLL so we won't get unloaded until the process terminates */
820 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
821 (WCHAR
*)hModule
, &hModule
);
825 case DLL_THREAD_DETACH
:
828 case DLL_PROCESS_DETACH
:
837 #elif defined(_MSC_VER)
838 #pragma section(".CRT$XCU",read)
839 static void alc_constructor(void);
840 static void alc_destructor(void);
841 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
843 static void alc_constructor(void)
845 atexit(alc_destructor
);
849 static void alc_destructor(void)
853 #elif defined(HAVE_GCC_DESTRUCTOR)
854 static void alc_init(void) __attribute__((constructor
));
855 static void alc_deinit(void) __attribute__((destructor
));
857 #error "No static initialization available on this platform!"
860 #elif defined(HAVE_GCC_DESTRUCTOR)
862 static void alc_init(void) __attribute__((constructor
));
863 static void alc_deinit(void) __attribute__((destructor
));
866 #error "No global initialization available on this platform!"
869 static void ReleaseThreadCtx(void *ptr
);
870 static void alc_init(void)
877 AL_STRING_INIT(alcAllDevicesList
);
878 AL_STRING_INIT(alcCaptureDeviceList
);
880 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
881 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
884 str
= getenv("__ALSOFT_REVERSE_Z");
885 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
888 str
= getenv("__ALSOFT_REVERB_IGNORES_SOUND_SPEED");
889 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
890 OverrideReverbSpeedOfSound
= AL_TRUE
;
892 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
893 assert(ret
== althrd_success
);
895 ret
= almtx_init(&ListLock
, almtx_recursive
);
896 assert(ret
== althrd_success
);
901 static void alc_initconfig(void)
903 const char *devs
, *str
;
908 str
= getenv("ALSOFT_LOGLEVEL");
911 long lvl
= strtol(str
, NULL
, 0);
912 if(lvl
>= NoLog
&& lvl
<= LogRef
)
916 str
= getenv("ALSOFT_LOGFILE");
919 FILE *logfile
= al_fopen(str
, "wt");
920 if(logfile
) LogFile
= logfile
;
921 else ERR("Failed to open log file '%s'\n", str
);
924 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION
,
925 ALSOFT_GIT_COMMIT_HASH
, ALSOFT_GIT_BRANCH
);
930 if(BackendListSize
> 0)
931 len
+= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
932 for(i
= 1;i
< BackendListSize
;i
++)
933 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
934 TRACE("Supported backends: %s\n", buf
);
938 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
941 if(strcasecmp(str
, "ignore") == 0)
943 SuspendDefers
= ALC_FALSE
;
944 TRACE("Selected context suspend behavior, \"ignore\"\n");
947 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
951 #if defined(HAVE_SSE4_1)
952 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
953 #elif defined(HAVE_SSE3)
954 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
955 #elif defined(HAVE_SSE2)
956 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
957 #elif defined(HAVE_SSE)
958 capfilter
|= CPU_CAP_SSE
;
961 capfilter
|= CPU_CAP_NEON
;
963 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
965 if(strcasecmp(str
, "all") == 0)
970 const char *next
= str
;
974 while(isspace(str
[0]))
976 next
= strchr(str
, ',');
978 if(!str
[0] || str
[0] == ',')
981 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
982 while(len
> 0 && isspace(str
[len
-1]))
984 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
985 capfilter
&= ~CPU_CAP_SSE
;
986 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
987 capfilter
&= ~CPU_CAP_SSE2
;
988 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
989 capfilter
&= ~CPU_CAP_SSE3
;
990 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
991 capfilter
&= ~CPU_CAP_SSE4_1
;
992 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
993 capfilter
&= ~CPU_CAP_NEON
;
995 WARN("Invalid CPU extension \"%s\"\n", str
);
999 FillCPUCaps(capfilter
);
1006 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
1011 str
= getenv("ALSOFT_TRAP_ERROR");
1012 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1014 TrapALError
= AL_TRUE
;
1015 TrapALCError
= AL_TRUE
;
1019 str
= getenv("ALSOFT_TRAP_AL_ERROR");
1020 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1021 TrapALError
= AL_TRUE
;
1022 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
1024 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1025 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1026 TrapALCError
= ALC_TRUE
;
1027 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1030 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1031 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1033 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1035 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1036 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1040 const char *next
= devs
;
1041 int endlist
, delitem
;
1046 while(isspace(devs
[0]))
1048 next
= strchr(devs
, ',');
1050 delitem
= (devs
[0] == '-');
1051 if(devs
[0] == '-') devs
++;
1053 if(!devs
[0] || devs
[0] == ',')
1060 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1061 while(len
> 0 && isspace(devs
[len
-1]))
1063 for(n
= i
;n
< BackendListSize
;n
++)
1065 if(len
== strlen(BackendList
[n
].name
) &&
1066 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1070 for(;n
+1 < BackendListSize
;n
++)
1071 BackendList
[n
] = BackendList
[n
+1];
1076 struct BackendInfo Bkp
= BackendList
[n
];
1078 BackendList
[n
] = BackendList
[n
-1];
1079 BackendList
[n
] = Bkp
;
1089 BackendListSize
= i
;
1092 for(i
= 0;i
< BackendListSize
&& (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1094 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1095 if(!V0(factory
,init
)())
1097 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1101 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1102 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1104 PlaybackBackend
= BackendList
[i
];
1105 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1107 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1109 CaptureBackend
= BackendList
[i
];
1110 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1114 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1118 if(!PlaybackBackend
.name
)
1119 WARN("No playback backend available!\n");
1120 if(!CaptureBackend
.name
)
1121 WARN("No capture backend available!\n");
1123 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1126 const char *next
= str
;
1130 next
= strchr(str
, ',');
1132 if(!str
[0] || next
== str
)
1135 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1136 for(n
= 0;EffectList
[n
].name
;n
++)
1138 if(len
== strlen(EffectList
[n
].name
) &&
1139 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1140 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1145 InitEffectFactoryMap();
1147 InitEffect(&DefaultEffect
);
1148 str
= getenv("ALSOFT_DEFAULT_REVERB");
1149 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1150 LoadReverbPreset(str
, &DefaultEffect
);
1152 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1157 static JavaVM
*gJavaVM
;
1158 static pthread_key_t gJVMThreadKey
;
1160 static void CleanupJNIEnv(void* UNUSED(ptr
))
1162 JCALL0(gJavaVM
,DetachCurrentThread
)();
1165 void *Android_GetJNIEnv(void)
1169 WARN("gJavaVM is NULL!\n");
1173 /* http://developer.android.com/guide/practices/jni.html
1175 * All threads are Linux threads, scheduled by the kernel. They're usually
1176 * started from managed code (using Thread.start), but they can also be
1177 * created elsewhere and then attached to the JavaVM. For example, a thread
1178 * started with pthread_create can be attached with the JNI
1179 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1180 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1181 * Attaching a natively-created thread causes a java.lang.Thread object to
1182 * be constructed and added to the "main" ThreadGroup, making it visible to
1183 * the debugger. Calling AttachCurrentThread on an already-attached thread
1186 JNIEnv
*env
= pthread_getspecific(gJVMThreadKey
);
1189 int status
= JCALL(gJavaVM
,AttachCurrentThread
)(&env
, NULL
);
1192 ERR("Failed to attach current thread\n");
1195 pthread_setspecific(gJVMThreadKey
, env
);
1200 /* Automatically called by JNI. */
1201 JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM
*jvm
, void* UNUSED(reserved
))
1207 if(JCALL(gJavaVM
,GetEnv
)(&env
, JNI_VERSION_1_4
) != JNI_OK
)
1209 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1213 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1214 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1216 if((err
=pthread_key_create(&gJVMThreadKey
, CleanupJNIEnv
)) != 0)
1217 ERR("pthread_key_create failed: %d\n", err
);
1218 pthread_setspecific(gJVMThreadKey
, env
);
1219 return JNI_VERSION_1_4
;
1224 /************************************************
1225 * Library deinitialization
1226 ************************************************/
1227 static void alc_cleanup(void)
1231 AL_STRING_DEINIT(alcAllDevicesList
);
1232 AL_STRING_DEINIT(alcCaptureDeviceList
);
1234 free(alcDefaultAllDevicesSpecifier
);
1235 alcDefaultAllDevicesSpecifier
= NULL
;
1236 free(alcCaptureDefaultDeviceSpecifier
);
1237 alcCaptureDefaultDeviceSpecifier
= NULL
;
1239 if((dev
=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList
, NULL
)) != NULL
)
1244 } while((dev
=dev
->next
) != NULL
);
1245 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1248 DeinitEffectFactoryMap();
1251 static void alc_deinit_safe(void)
1259 almtx_destroy(&ListLock
);
1260 altss_delete(LocalContext
);
1262 if(LogFile
!= stderr
)
1267 static void alc_deinit(void)
1273 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1274 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1276 for(i
= 0;i
< BackendListSize
;i
++)
1278 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1279 V0(factory
,deinit
)();
1282 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1283 V0(factory
,deinit
)();
1290 /************************************************
1291 * Device enumeration
1292 ************************************************/
1293 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1295 ALCbackendFactory
*factory
;
1302 factory
= backendinfo
->getFactory();
1303 V(factory
,probe
)(type
);
1307 static void ProbeAllDevicesList(void)
1308 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1309 static void ProbeCaptureDeviceList(void)
1310 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1312 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1314 size_t len
= strlen(name
);
1316 alstr_append_range(devnames
, name
, name
+len
+1);
1318 void AppendAllDevicesList(const ALCchar
*name
)
1319 { AppendDevice(name
, &alcAllDevicesList
); }
1320 void AppendCaptureDeviceList(const ALCchar
*name
)
1321 { AppendDevice(name
, &alcCaptureDeviceList
); }
1324 /************************************************
1325 * Device format information
1326 ************************************************/
1327 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1331 case DevFmtByte
: return "Signed Byte";
1332 case DevFmtUByte
: return "Unsigned Byte";
1333 case DevFmtShort
: return "Signed Short";
1334 case DevFmtUShort
: return "Unsigned Short";
1335 case DevFmtInt
: return "Signed Int";
1336 case DevFmtUInt
: return "Unsigned Int";
1337 case DevFmtFloat
: return "Float";
1339 return "(unknown type)";
1341 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1345 case DevFmtMono
: return "Mono";
1346 case DevFmtStereo
: return "Stereo";
1347 case DevFmtQuad
: return "Quadraphonic";
1348 case DevFmtX51
: return "5.1 Surround";
1349 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1350 case DevFmtX61
: return "6.1 Surround";
1351 case DevFmtX71
: return "7.1 Surround";
1352 case DevFmtAmbi3D
: return "Ambisonic 3D";
1354 return "(unknown channels)";
1357 extern inline ALsizei
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
, ALsizei ambiorder
);
1358 ALsizei
BytesFromDevFmt(enum DevFmtType type
)
1362 case DevFmtByte
: return sizeof(ALbyte
);
1363 case DevFmtUByte
: return sizeof(ALubyte
);
1364 case DevFmtShort
: return sizeof(ALshort
);
1365 case DevFmtUShort
: return sizeof(ALushort
);
1366 case DevFmtInt
: return sizeof(ALint
);
1367 case DevFmtUInt
: return sizeof(ALuint
);
1368 case DevFmtFloat
: return sizeof(ALfloat
);
1372 ALsizei
ChannelsFromDevFmt(enum DevFmtChannels chans
, ALsizei ambiorder
)
1376 case DevFmtMono
: return 1;
1377 case DevFmtStereo
: return 2;
1378 case DevFmtQuad
: return 4;
1379 case DevFmtX51
: return 6;
1380 case DevFmtX51Rear
: return 6;
1381 case DevFmtX61
: return 7;
1382 case DevFmtX71
: return 8;
1383 case DevFmtAmbi3D
: return (ambiorder
>= 3) ? 16 :
1384 (ambiorder
== 2) ? 9 :
1385 (ambiorder
== 1) ? 4 : 1;
1390 static ALboolean
DecomposeDevFormat(ALenum format
, enum DevFmtChannels
*chans
,
1391 enum DevFmtType
*type
)
1393 static const struct {
1395 enum DevFmtChannels channels
;
1396 enum DevFmtType type
;
1398 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1399 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1400 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1402 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1403 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1404 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1406 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1407 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1408 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1410 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1411 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1412 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1414 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1415 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1416 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1418 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1419 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1420 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1424 for(i
= 0;i
< COUNTOF(list
);i
++)
1426 if(list
[i
].format
== format
)
1428 *chans
= list
[i
].channels
;
1429 *type
= list
[i
].type
;
1437 static ALCboolean
IsValidALCType(ALCenum type
)
1442 case ALC_UNSIGNED_BYTE_SOFT
:
1443 case ALC_SHORT_SOFT
:
1444 case ALC_UNSIGNED_SHORT_SOFT
:
1446 case ALC_UNSIGNED_INT_SOFT
:
1447 case ALC_FLOAT_SOFT
:
1453 static ALCboolean
IsValidALCChannels(ALCenum channels
)
1458 case ALC_STEREO_SOFT
:
1460 case ALC_5POINT1_SOFT
:
1461 case ALC_6POINT1_SOFT
:
1462 case ALC_7POINT1_SOFT
:
1463 case ALC_BFORMAT3D_SOFT
:
1469 static ALCboolean
IsValidAmbiLayout(ALCenum layout
)
1480 static ALCboolean
IsValidAmbiScaling(ALCenum scaling
)
1492 /************************************************
1493 * Miscellaneous ALC helpers
1494 ************************************************/
1496 void ALCdevice_Lock(ALCdevice
*device
)
1498 V0(device
->Backend
,lock
)();
1501 void ALCdevice_Unlock(ALCdevice
*device
)
1503 V0(device
->Backend
,unlock
)();
1507 /* SetDefaultWFXChannelOrder
1509 * Sets the default channel order used by WaveFormatEx.
1511 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1515 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1516 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1518 switch(device
->FmtChans
)
1521 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1524 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1525 device
->RealOut
.ChannelName
[1] = FrontRight
;
1528 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1529 device
->RealOut
.ChannelName
[1] = FrontRight
;
1530 device
->RealOut
.ChannelName
[2] = BackLeft
;
1531 device
->RealOut
.ChannelName
[3] = BackRight
;
1534 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1535 device
->RealOut
.ChannelName
[1] = FrontRight
;
1536 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1537 device
->RealOut
.ChannelName
[3] = LFE
;
1538 device
->RealOut
.ChannelName
[4] = SideLeft
;
1539 device
->RealOut
.ChannelName
[5] = SideRight
;
1542 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1543 device
->RealOut
.ChannelName
[1] = FrontRight
;
1544 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1545 device
->RealOut
.ChannelName
[3] = LFE
;
1546 device
->RealOut
.ChannelName
[4] = BackLeft
;
1547 device
->RealOut
.ChannelName
[5] = BackRight
;
1550 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1551 device
->RealOut
.ChannelName
[1] = FrontRight
;
1552 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1553 device
->RealOut
.ChannelName
[3] = LFE
;
1554 device
->RealOut
.ChannelName
[4] = BackCenter
;
1555 device
->RealOut
.ChannelName
[5] = SideLeft
;
1556 device
->RealOut
.ChannelName
[6] = SideRight
;
1559 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1560 device
->RealOut
.ChannelName
[1] = FrontRight
;
1561 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1562 device
->RealOut
.ChannelName
[3] = LFE
;
1563 device
->RealOut
.ChannelName
[4] = BackLeft
;
1564 device
->RealOut
.ChannelName
[5] = BackRight
;
1565 device
->RealOut
.ChannelName
[6] = SideLeft
;
1566 device
->RealOut
.ChannelName
[7] = SideRight
;
1569 device
->RealOut
.ChannelName
[0] = Aux0
;
1570 if(device
->AmbiOrder
> 0)
1572 device
->RealOut
.ChannelName
[1] = Aux1
;
1573 device
->RealOut
.ChannelName
[2] = Aux2
;
1574 device
->RealOut
.ChannelName
[3] = Aux3
;
1576 if(device
->AmbiOrder
> 1)
1578 device
->RealOut
.ChannelName
[4] = Aux4
;
1579 device
->RealOut
.ChannelName
[5] = Aux5
;
1580 device
->RealOut
.ChannelName
[6] = Aux6
;
1581 device
->RealOut
.ChannelName
[7] = Aux7
;
1582 device
->RealOut
.ChannelName
[8] = Aux8
;
1584 if(device
->AmbiOrder
> 2)
1586 device
->RealOut
.ChannelName
[9] = Aux9
;
1587 device
->RealOut
.ChannelName
[10] = Aux10
;
1588 device
->RealOut
.ChannelName
[11] = Aux11
;
1589 device
->RealOut
.ChannelName
[12] = Aux12
;
1590 device
->RealOut
.ChannelName
[13] = Aux13
;
1591 device
->RealOut
.ChannelName
[14] = Aux14
;
1592 device
->RealOut
.ChannelName
[15] = Aux15
;
1598 /* SetDefaultChannelOrder
1600 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1602 void SetDefaultChannelOrder(ALCdevice
*device
)
1606 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1607 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1609 switch(device
->FmtChans
)
1612 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1613 device
->RealOut
.ChannelName
[1] = FrontRight
;
1614 device
->RealOut
.ChannelName
[2] = BackLeft
;
1615 device
->RealOut
.ChannelName
[3] = BackRight
;
1616 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1617 device
->RealOut
.ChannelName
[5] = LFE
;
1620 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1621 device
->RealOut
.ChannelName
[1] = FrontRight
;
1622 device
->RealOut
.ChannelName
[2] = BackLeft
;
1623 device
->RealOut
.ChannelName
[3] = BackRight
;
1624 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1625 device
->RealOut
.ChannelName
[5] = LFE
;
1626 device
->RealOut
.ChannelName
[6] = SideLeft
;
1627 device
->RealOut
.ChannelName
[7] = SideRight
;
1630 /* Same as WFX order */
1637 SetDefaultWFXChannelOrder(device
);
1642 extern inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
);
1645 /* ALCcontext_DeferUpdates
1647 * Defers/suspends updates for the given context's listener and sources. This
1648 * does *NOT* stop mixing, but rather prevents certain property changes from
1651 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1653 ATOMIC_STORE_SEQ(&context
->DeferUpdates
, AL_TRUE
);
1656 /* ALCcontext_ProcessUpdates
1658 * Resumes update processing after being deferred.
1660 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1662 ReadLock(&context
->PropLock
);
1663 if(ATOMIC_EXCHANGE_SEQ(&context
->DeferUpdates
, AL_FALSE
))
1665 /* Tell the mixer to stop applying updates, then wait for any active
1666 * updating to finish, before providing updates.
1668 ATOMIC_STORE_SEQ(&context
->HoldUpdates
, AL_TRUE
);
1669 while((ATOMIC_LOAD(&context
->UpdateCount
, almemory_order_acquire
)&1) != 0)
1672 if(!ATOMIC_FLAG_TEST_AND_SET(&context
->PropsClean
, almemory_order_acq_rel
))
1673 UpdateContextProps(context
);
1674 if(!ATOMIC_FLAG_TEST_AND_SET(&context
->Listener
->PropsClean
, almemory_order_acq_rel
))
1675 UpdateListenerProps(context
);
1676 UpdateAllEffectSlotProps(context
);
1677 UpdateAllSourceProps(context
);
1679 /* Now with all updates declared, let the mixer continue applying them
1680 * so they all happen at once.
1682 ATOMIC_STORE_SEQ(&context
->HoldUpdates
, AL_FALSE
);
1684 ReadUnlock(&context
->PropLock
);
1690 * Stores the latest ALC device error
1692 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1694 WARN("Error generated on device %p, code 0x%04x\n", device
, errorCode
);
1698 /* DebugBreak() will cause an exception if there is no debugger */
1699 if(IsDebuggerPresent())
1701 #elif defined(SIGTRAP)
1707 ATOMIC_STORE_SEQ(&device
->LastError
, errorCode
);
1709 ATOMIC_STORE_SEQ(&LastNullDeviceError
, errorCode
);
1713 struct Compressor
*CreateDeviceLimiter(const ALCdevice
*device
)
1715 return CompressorInit(0.0f
, 0.0f
, AL_FALSE
, AL_TRUE
, 0.0f
, 0.0f
, 0.5f
, 2.0f
,
1716 0.0f
, -3.0f
, 3.0f
, device
->Frequency
);
1721 * Updates the device's base clock time with however many samples have been
1722 * done. This is used so frequency changes on the device don't cause the time
1723 * to jump forward or back. Must not be called while the device is running/
1726 static inline void UpdateClockBase(ALCdevice
*device
)
1728 IncrementRef(&device
->MixCount
);
1729 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1730 device
->SamplesDone
= 0;
1731 IncrementRef(&device
->MixCount
);
1734 /* UpdateDeviceParams
1736 * Updates device parameters according to the attribute list (caller is
1737 * responsible for holding the list lock).
1739 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1741 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1742 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1743 ALCenum gainLimiter
= device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
1744 const ALsizei old_sends
= device
->NumAuxSends
;
1745 ALsizei new_sends
= device
->NumAuxSends
;
1746 enum DevFmtChannels oldChans
;
1747 enum DevFmtType oldType
;
1748 ALboolean update_failed
;
1749 ALCsizei hrtf_id
= -1;
1750 ALCcontext
*context
;
1756 // Check for attributes
1757 if(device
->Type
== Loopback
)
1759 ALCsizei numMono
, numStereo
, numSends
;
1760 ALCenum alayout
= AL_NONE
;
1761 ALCenum ascale
= AL_NONE
;
1762 ALCenum schans
= AL_NONE
;
1763 ALCenum stype
= AL_NONE
;
1764 ALCsizei attrIdx
= 0;
1765 ALCsizei aorder
= 0;
1770 WARN("Missing attributes for loopback device\n");
1771 return ALC_INVALID_VALUE
;
1774 numMono
= device
->NumMonoSources
;
1775 numStereo
= device
->NumStereoSources
;
1776 numSends
= old_sends
;
1778 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1779 while(attrList
[attrIdx
])
1781 switch(attrList
[attrIdx
])
1783 case ALC_FORMAT_CHANNELS_SOFT
:
1784 schans
= attrList
[attrIdx
+ 1];
1785 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT
, schans
);
1786 if(!IsValidALCChannels(schans
))
1787 return ALC_INVALID_VALUE
;
1790 case ALC_FORMAT_TYPE_SOFT
:
1791 stype
= attrList
[attrIdx
+ 1];
1792 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT
, stype
);
1793 if(!IsValidALCType(stype
))
1794 return ALC_INVALID_VALUE
;
1798 freq
= attrList
[attrIdx
+ 1];
1799 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1800 if(freq
< MIN_OUTPUT_RATE
)
1801 return ALC_INVALID_VALUE
;
1804 case ALC_AMBISONIC_LAYOUT_SOFT
:
1805 alayout
= attrList
[attrIdx
+ 1];
1806 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT
, alayout
);
1807 if(!IsValidAmbiLayout(alayout
))
1808 return ALC_INVALID_VALUE
;
1811 case ALC_AMBISONIC_SCALING_SOFT
:
1812 ascale
= attrList
[attrIdx
+ 1];
1813 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT
, ascale
);
1814 if(!IsValidAmbiScaling(ascale
))
1815 return ALC_INVALID_VALUE
;
1818 case ALC_AMBISONIC_ORDER_SOFT
:
1819 aorder
= attrList
[attrIdx
+ 1];
1820 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT
, aorder
);
1821 if(aorder
< 1 || aorder
> MAX_AMBI_ORDER
)
1822 return ALC_INVALID_VALUE
;
1825 case ALC_MONO_SOURCES
:
1826 numMono
= attrList
[attrIdx
+ 1];
1827 TRACE_ATTR(ALC_MONO_SOURCES
, numMono
);
1828 numMono
= maxi(numMono
, 0);
1831 case ALC_STEREO_SOURCES
:
1832 numStereo
= attrList
[attrIdx
+ 1];
1833 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1834 numStereo
= maxi(numStereo
, 0);
1837 case ALC_MAX_AUXILIARY_SENDS
:
1838 numSends
= attrList
[attrIdx
+ 1];
1839 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1840 numSends
= clampi(numSends
, 0, MAX_SENDS
);
1844 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1845 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1846 hrtf_appreq
= Hrtf_Disable
;
1847 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1848 hrtf_appreq
= Hrtf_Enable
;
1850 hrtf_appreq
= Hrtf_Default
;
1853 case ALC_HRTF_ID_SOFT
:
1854 hrtf_id
= attrList
[attrIdx
+ 1];
1855 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1858 case ALC_OUTPUT_LIMITER_SOFT
:
1859 gainLimiter
= attrList
[attrIdx
+ 1];
1860 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT
, gainLimiter
);
1864 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList
[attrIdx
],
1865 attrList
[attrIdx
+ 1], attrList
[attrIdx
+ 1]);
1873 if(!schans
|| !stype
|| !freq
)
1875 WARN("Missing format for loopback device\n");
1876 return ALC_INVALID_VALUE
;
1878 if(schans
== ALC_BFORMAT3D_SOFT
&& (!alayout
|| !ascale
|| !aorder
))
1880 WARN("Missing ambisonic info for loopback device\n");
1881 return ALC_INVALID_VALUE
;
1884 if((device
->Flags
&DEVICE_RUNNING
))
1885 V0(device
->Backend
,stop
)();
1886 device
->Flags
&= ~DEVICE_RUNNING
;
1888 UpdateClockBase(device
);
1890 device
->Frequency
= freq
;
1891 device
->FmtChans
= schans
;
1892 device
->FmtType
= stype
;
1893 if(schans
== ALC_BFORMAT3D_SOFT
)
1895 device
->AmbiOrder
= aorder
;
1896 device
->AmbiLayout
= alayout
;
1897 device
->AmbiScale
= ascale
;
1900 if(numMono
> INT_MAX
-numStereo
)
1901 numMono
= INT_MAX
-numStereo
;
1902 numMono
+= numStereo
;
1903 if(ConfigValueInt(NULL
, NULL
, "sources", &numMono
))
1909 numMono
= maxi(numMono
, 256);
1910 numStereo
= mini(numStereo
, numMono
);
1911 numMono
-= numStereo
;
1912 device
->SourcesMax
= numMono
+ numStereo
;
1914 device
->NumMonoSources
= numMono
;
1915 device
->NumStereoSources
= numStereo
;
1917 if(ConfigValueInt(NULL
, NULL
, "sends", &new_sends
))
1918 new_sends
= mini(numSends
, clampi(new_sends
, 0, MAX_SENDS
));
1920 new_sends
= numSends
;
1922 else if(attrList
&& attrList
[0])
1924 ALCsizei numMono
, numStereo
, numSends
;
1925 ALCsizei attrIdx
= 0;
1928 /* If a context is already running on the device, stop playback so the
1929 * device attributes can be updated. */
1930 if((device
->Flags
&DEVICE_RUNNING
))
1931 V0(device
->Backend
,stop
)();
1932 device
->Flags
&= ~DEVICE_RUNNING
;
1934 UpdateClockBase(device
);
1936 freq
= device
->Frequency
;
1937 numMono
= device
->NumMonoSources
;
1938 numStereo
= device
->NumStereoSources
;
1939 numSends
= old_sends
;
1941 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1942 while(attrList
[attrIdx
])
1944 switch(attrList
[attrIdx
])
1947 freq
= attrList
[attrIdx
+ 1];
1948 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1949 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1952 case ALC_MONO_SOURCES
:
1953 numMono
= attrList
[attrIdx
+ 1];
1954 TRACE_ATTR(ALC_MONO_SOURCES
, numMono
);
1955 numMono
= maxi(numMono
, 0);
1958 case ALC_STEREO_SOURCES
:
1959 numStereo
= attrList
[attrIdx
+ 1];
1960 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1961 numStereo
= maxi(numStereo
, 0);
1964 case ALC_MAX_AUXILIARY_SENDS
:
1965 numSends
= attrList
[attrIdx
+ 1];
1966 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1967 numSends
= clampi(numSends
, 0, MAX_SENDS
);
1971 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1972 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1973 hrtf_appreq
= Hrtf_Disable
;
1974 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1975 hrtf_appreq
= Hrtf_Enable
;
1977 hrtf_appreq
= Hrtf_Default
;
1980 case ALC_HRTF_ID_SOFT
:
1981 hrtf_id
= attrList
[attrIdx
+ 1];
1982 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1985 case ALC_OUTPUT_LIMITER_SOFT
:
1986 gainLimiter
= attrList
[attrIdx
+ 1];
1987 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT
, gainLimiter
);
1991 TRACE("0x%04X = %d (0x%x)\n", attrList
[attrIdx
],
1992 attrList
[attrIdx
+ 1], attrList
[attrIdx
+ 1]);
2000 ConfigValueUInt(alstr_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
2001 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
2003 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
2005 /* SSE and Neon do best with the update size being a multiple of 4 */
2006 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
2007 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
2009 device
->Frequency
= freq
;
2011 if(numMono
> INT_MAX
-numStereo
)
2012 numMono
= INT_MAX
-numStereo
;
2013 numMono
+= numStereo
;
2014 if(ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "sources", &numMono
))
2020 numMono
= maxi(numMono
, 256);
2021 numStereo
= mini(numStereo
, numMono
);
2022 numMono
-= numStereo
;
2023 device
->SourcesMax
= numMono
+ numStereo
;
2025 device
->NumMonoSources
= numMono
;
2026 device
->NumStereoSources
= numStereo
;
2028 if(ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "sends", &new_sends
))
2029 new_sends
= mini(numSends
, clampi(new_sends
, 0, MAX_SENDS
));
2031 new_sends
= numSends
;
2034 if((device
->Flags
&DEVICE_RUNNING
))
2035 return ALC_NO_ERROR
;
2037 al_free(device
->Uhj_Encoder
);
2038 device
->Uhj_Encoder
= NULL
;
2040 al_free(device
->Bs2b
);
2041 device
->Bs2b
= NULL
;
2043 al_free(device
->ChannelDelay
[0].Buffer
);
2044 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
2046 device
->ChannelDelay
[i
].Length
= 0;
2047 device
->ChannelDelay
[i
].Buffer
= NULL
;
2050 al_free(device
->Dry
.Buffer
);
2051 device
->Dry
.Buffer
= NULL
;
2052 device
->Dry
.NumChannels
= 0;
2053 device
->FOAOut
.Buffer
= NULL
;
2054 device
->FOAOut
.NumChannels
= 0;
2055 device
->RealOut
.Buffer
= NULL
;
2056 device
->RealOut
.NumChannels
= 0;
2058 UpdateClockBase(device
);
2060 device
->DitherSeed
= DITHER_RNG_SEED
;
2062 /*************************************************************************
2063 * Update device format request if HRTF is requested
2065 device
->HrtfStatus
= ALC_HRTF_DISABLED_SOFT
;
2066 if(device
->Type
!= Loopback
)
2069 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
2071 if(strcasecmp(hrtf
, "true") == 0)
2072 hrtf_userreq
= Hrtf_Enable
;
2073 else if(strcasecmp(hrtf
, "false") == 0)
2074 hrtf_userreq
= Hrtf_Disable
;
2075 else if(strcasecmp(hrtf
, "auto") != 0)
2076 ERR("Unexpected hrtf value: %s\n", hrtf
);
2079 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
2081 struct Hrtf
*hrtf
= NULL
;
2082 if(VECTOR_SIZE(device
->HrtfList
) == 0)
2084 VECTOR_DEINIT(device
->HrtfList
);
2085 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
2087 if(VECTOR_SIZE(device
->HrtfList
) > 0)
2089 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->HrtfList
))
2090 hrtf
= GetLoadedHrtf(VECTOR_ELEM(device
->HrtfList
, hrtf_id
).hrtf
);
2092 hrtf
= GetLoadedHrtf(VECTOR_ELEM(device
->HrtfList
, 0).hrtf
);
2097 device
->FmtChans
= DevFmtStereo
;
2098 device
->Frequency
= hrtf
->sampleRate
;
2099 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
2100 if(device
->HrtfHandle
)
2101 Hrtf_DecRef(device
->HrtfHandle
);
2102 device
->HrtfHandle
= hrtf
;
2106 hrtf_userreq
= Hrtf_Default
;
2107 hrtf_appreq
= Hrtf_Disable
;
2108 device
->HrtfStatus
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2113 oldFreq
= device
->Frequency
;
2114 oldChans
= device
->FmtChans
;
2115 oldType
= device
->FmtType
;
2117 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2118 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
2119 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
2120 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
2121 device
->UpdateSize
, device
->NumUpdates
2124 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
2125 return ALC_INVALID_DEVICE
;
2127 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
2129 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
2130 DevFmtChannelsString(device
->FmtChans
));
2131 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
2133 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
2135 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
2136 DevFmtTypeString(device
->FmtType
));
2137 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
2139 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
2141 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
2142 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
2145 if((device
->UpdateSize
&3) != 0)
2147 if((CPUCapFlags
&CPU_CAP_SSE
))
2148 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2149 if((CPUCapFlags
&CPU_CAP_NEON
))
2150 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2153 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2154 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
2155 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
2158 aluInitRenderer(device
, hrtf_id
, hrtf_appreq
, hrtf_userreq
);
2159 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device
->Dry
.NumChannels
,
2160 device
->FOAOut
.NumChannels
, device
->RealOut
.NumChannels
);
2162 /* Allocate extra channels for any post-filter output. */
2163 size
= (device
->Dry
.NumChannels
+ device
->FOAOut
.NumChannels
+
2164 device
->RealOut
.NumChannels
)*sizeof(device
->Dry
.Buffer
[0]);
2166 TRACE("Allocating "SZFMT
" channels, "SZFMT
" bytes\n", size
/sizeof(device
->Dry
.Buffer
[0]), size
);
2167 device
->Dry
.Buffer
= al_calloc(16, size
);
2168 if(!device
->Dry
.Buffer
)
2170 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2171 return ALC_INVALID_DEVICE
;
2174 if(device
->RealOut
.NumChannels
!= 0)
2175 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
+
2176 device
->FOAOut
.NumChannels
;
2179 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2180 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2183 if(device
->FOAOut
.NumChannels
!= 0)
2184 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2187 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
;
2188 device
->FOAOut
.NumChannels
= device
->Dry
.NumChannels
;
2191 device
->NumAuxSends
= new_sends
;
2192 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2193 device
->SourcesMax
, device
->NumMonoSources
, device
->NumStereoSources
,
2194 device
->AuxiliaryEffectSlotMax
, device
->NumAuxSends
);
2196 device
->DitherDepth
= 0.0f
;
2197 if(GetConfigValueBool(alstr_get_cstr(device
->DeviceName
), NULL
, "dither", 1))
2200 ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "dither-depth", &depth
);
2203 switch(device
->FmtType
)
2221 device
->DitherDepth
= (depth
> 0) ? powf(2.0f
, (ALfloat
)(depth
-1)) : 0.0f
;
2223 if(!(device
->DitherDepth
> 0.0f
))
2224 TRACE("Dithering disabled\n");
2226 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device
->DitherDepth
)+1.0f
,
2227 device
->DitherDepth
);
2229 if(ConfigValueBool(alstr_get_cstr(device
->DeviceName
), NULL
, "output-limiter", &val
))
2230 gainLimiter
= val
? ALC_TRUE
: ALC_FALSE
;
2231 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2232 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2235 if(gainLimiter
!= ALC_FALSE
)
2237 if(!device
->Limiter
|| device
->Frequency
!= GetCompressorSampleRate(device
->Limiter
))
2239 al_free(device
->Limiter
);
2240 device
->Limiter
= CreateDeviceLimiter(device
);
2245 al_free(device
->Limiter
);
2246 device
->Limiter
= NULL
;
2248 TRACE("Output limiter %s\n", device
->Limiter
? "enabled" : "disabled");
2250 /* Need to delay returning failure until replacement Send arrays have been
2251 * allocated with the appropriate size.
2253 update_failed
= AL_FALSE
;
2255 context
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
2260 if(context
->DefaultSlot
)
2262 ALeffectslot
*slot
= context
->DefaultSlot
;
2263 ALeffectState
*state
= slot
->Effect
.State
;
2265 state
->OutBuffer
= device
->Dry
.Buffer
;
2266 state
->OutChannels
= device
->Dry
.NumChannels
;
2267 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2268 update_failed
= AL_TRUE
;
2270 UpdateEffectSlotProps(slot
);
2273 WriteLock(&context
->PropLock
);
2274 LockUIntMapRead(&context
->EffectSlotMap
);
2275 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2277 ALeffectslot
*slot
= context
->EffectSlotMap
.values
[pos
];
2278 ALeffectState
*state
= slot
->Effect
.State
;
2280 state
->OutBuffer
= device
->Dry
.Buffer
;
2281 state
->OutChannels
= device
->Dry
.NumChannels
;
2282 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2283 update_failed
= AL_TRUE
;
2285 UpdateEffectSlotProps(slot
);
2287 UnlockUIntMapRead(&context
->EffectSlotMap
);
2289 LockUIntMapRead(&context
->SourceMap
);
2290 RelimitUIntMapNoLock(&context
->SourceMap
, device
->SourcesMax
);
2291 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2293 ALsource
*source
= context
->SourceMap
.values
[pos
];
2295 if(old_sends
!= device
->NumAuxSends
)
2297 ALvoid
*sends
= al_calloc(16, device
->NumAuxSends
*sizeof(source
->Send
[0]));
2300 memcpy(sends
, source
->Send
,
2301 mini(device
->NumAuxSends
, old_sends
)*sizeof(source
->Send
[0])
2303 for(s
= device
->NumAuxSends
;s
< old_sends
;s
++)
2305 if(source
->Send
[s
].Slot
)
2306 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2307 source
->Send
[s
].Slot
= NULL
;
2309 al_free(source
->Send
);
2310 source
->Send
= sends
;
2311 for(s
= old_sends
;s
< device
->NumAuxSends
;s
++)
2313 source
->Send
[s
].Slot
= NULL
;
2314 source
->Send
[s
].Gain
= 1.0f
;
2315 source
->Send
[s
].GainHF
= 1.0f
;
2316 source
->Send
[s
].HFReference
= LOWPASSFREQREF
;
2317 source
->Send
[s
].GainLF
= 1.0f
;
2318 source
->Send
[s
].LFReference
= HIGHPASSFREQREF
;
2322 ATOMIC_FLAG_CLEAR(&source
->PropsClean
, almemory_order_release
);
2324 AllocateVoices(context
, context
->MaxVoices
, old_sends
);
2325 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2327 ALvoice
*voice
= context
->Voices
[pos
];
2328 struct ALvoiceProps
*props
;
2330 /* Clear any pre-existing voice property structs, in case the
2331 * number of auxiliary sends changed. Active sources will have
2332 * updates respecified in UpdateAllSourceProps.
2334 props
= ATOMIC_EXCHANGE_PTR(&voice
->Update
, NULL
, almemory_order_relaxed
);
2337 props
= ATOMIC_EXCHANGE_PTR(&voice
->FreeList
, NULL
, almemory_order_relaxed
);
2340 struct ALvoiceProps
*next
= ATOMIC_LOAD(&props
->next
, almemory_order_relaxed
);
2345 if(ATOMIC_LOAD(&voice
->Source
, almemory_order_acquire
) == NULL
)
2348 if(device
->AvgSpeakerDist
> 0.0f
)
2350 /* Reinitialize the NFC filters for new parameters. */
2351 ALfloat w1
= SPEEDOFSOUNDMETRESPERSEC
/
2352 (device
->AvgSpeakerDist
* device
->Frequency
);
2353 for(i
= 0;i
< voice
->NumChannels
;i
++)
2355 NfcFilterCreate1(&voice
->Direct
.Params
[i
].NFCtrlFilter
[0], 0.0f
, w1
);
2356 NfcFilterCreate2(&voice
->Direct
.Params
[i
].NFCtrlFilter
[1], 0.0f
, w1
);
2357 NfcFilterCreate3(&voice
->Direct
.Params
[i
].NFCtrlFilter
[2], 0.0f
, w1
);
2361 UnlockUIntMapRead(&context
->SourceMap
);
2363 ATOMIC_FLAG_TEST_AND_SET(&context
->PropsClean
, almemory_order_release
);
2364 UpdateContextProps(context
);
2365 ATOMIC_FLAG_TEST_AND_SET(&context
->Listener
->PropsClean
, almemory_order_release
);
2366 UpdateListenerProps(context
);
2367 UpdateAllSourceProps(context
);
2368 WriteUnlock(&context
->PropLock
);
2370 context
= context
->next
;
2374 return ALC_INVALID_DEVICE
;
2376 if(!(device
->Flags
&DEVICE_PAUSED
))
2378 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2379 return ALC_INVALID_DEVICE
;
2380 device
->Flags
|= DEVICE_RUNNING
;
2383 return ALC_NO_ERROR
;
2388 * Frees the device structure, and destroys any objects the app failed to
2389 * delete. Called once there's no more references on the device.
2391 static ALCvoid
FreeDevice(ALCdevice
*device
)
2395 TRACE("%p\n", device
);
2397 V0(device
->Backend
,close
)();
2398 DELETE_OBJ(device
->Backend
);
2399 device
->Backend
= NULL
;
2401 almtx_destroy(&device
->BackendLock
);
2403 if(device
->BufferMap
.size
> 0)
2405 WARN("(%p) Deleting %d Buffer%s\n", device
, device
->BufferMap
.size
,
2406 (device
->BufferMap
.size
==1)?"":"s");
2407 ReleaseALBuffers(device
);
2409 ResetUIntMap(&device
->BufferMap
);
2411 if(device
->EffectMap
.size
> 0)
2413 WARN("(%p) Deleting %d Effect%s\n", device
, device
->EffectMap
.size
,
2414 (device
->EffectMap
.size
==1)?"":"s");
2415 ReleaseALEffects(device
);
2417 ResetUIntMap(&device
->EffectMap
);
2419 if(device
->FilterMap
.size
> 0)
2421 WARN("(%p) Deleting %d Filter%s\n", device
, device
->FilterMap
.size
,
2422 (device
->FilterMap
.size
==1)?"":"s");
2423 ReleaseALFilters(device
);
2425 ResetUIntMap(&device
->FilterMap
);
2427 AL_STRING_DEINIT(device
->HrtfName
);
2428 FreeHrtfList(&device
->HrtfList
);
2429 if(device
->HrtfHandle
)
2430 Hrtf_DecRef(device
->HrtfHandle
);
2431 device
->HrtfHandle
= NULL
;
2432 al_free(device
->Hrtf
);
2433 device
->Hrtf
= NULL
;
2435 al_free(device
->Bs2b
);
2436 device
->Bs2b
= NULL
;
2438 al_free(device
->Uhj_Encoder
);
2439 device
->Uhj_Encoder
= NULL
;
2441 bformatdec_free(device
->AmbiDecoder
);
2442 device
->AmbiDecoder
= NULL
;
2444 ambiup_free(device
->AmbiUp
);
2445 device
->AmbiUp
= NULL
;
2447 al_free(device
->Stablizer
);
2448 device
->Stablizer
= NULL
;
2450 al_free(device
->Limiter
);
2451 device
->Limiter
= NULL
;
2453 al_free(device
->ChannelDelay
[0].Buffer
);
2454 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
2456 device
->ChannelDelay
[i
].Gain
= 1.0f
;
2457 device
->ChannelDelay
[i
].Length
= 0;
2458 device
->ChannelDelay
[i
].Buffer
= NULL
;
2461 AL_STRING_DEINIT(device
->DeviceName
);
2463 al_free(device
->Dry
.Buffer
);
2464 device
->Dry
.Buffer
= NULL
;
2465 device
->Dry
.NumChannels
= 0;
2466 device
->FOAOut
.Buffer
= NULL
;
2467 device
->FOAOut
.NumChannels
= 0;
2468 device
->RealOut
.Buffer
= NULL
;
2469 device
->RealOut
.NumChannels
= 0;
2475 void ALCdevice_IncRef(ALCdevice
*device
)
2478 ref
= IncrementRef(&device
->ref
);
2479 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2482 void ALCdevice_DecRef(ALCdevice
*device
)
2485 ref
= DecrementRef(&device
->ref
);
2486 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2487 if(ref
== 0) FreeDevice(device
);
2492 * Checks if the device handle is valid, and increments its ref count if so.
2494 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2496 ALCdevice
*tmpDevice
;
2499 tmpDevice
= ATOMIC_LOAD_SEQ(&DeviceList
);
2502 if(tmpDevice
== *device
)
2504 ALCdevice_IncRef(tmpDevice
);
2508 tmpDevice
= tmpDevice
->next
;
2519 * Initializes context fields
2521 static ALvoid
InitContext(ALCcontext
*Context
)
2523 ALlistener
*listener
= Context
->Listener
;
2524 struct ALeffectslotArray
*auxslots
;
2526 //Initialise listener
2527 listener
->Gain
= 1.0f
;
2528 listener
->Position
[0] = 0.0f
;
2529 listener
->Position
[1] = 0.0f
;
2530 listener
->Position
[2] = 0.0f
;
2531 listener
->Velocity
[0] = 0.0f
;
2532 listener
->Velocity
[1] = 0.0f
;
2533 listener
->Velocity
[2] = 0.0f
;
2534 listener
->Forward
[0] = 0.0f
;
2535 listener
->Forward
[1] = 0.0f
;
2536 listener
->Forward
[2] = -1.0f
;
2537 listener
->Up
[0] = 0.0f
;
2538 listener
->Up
[1] = 1.0f
;
2539 listener
->Up
[2] = 0.0f
;
2540 ATOMIC_FLAG_TEST_AND_SET(&listener
->PropsClean
, almemory_order_relaxed
);
2542 ATOMIC_INIT(&listener
->Update
, NULL
);
2543 ATOMIC_INIT(&listener
->FreeList
, NULL
);
2546 InitRef(&Context
->UpdateCount
, 0);
2547 ATOMIC_INIT(&Context
->HoldUpdates
, AL_FALSE
);
2548 Context
->GainBoost
= 1.0f
;
2549 RWLockInit(&Context
->PropLock
);
2550 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2551 InitUIntMap(&Context
->SourceMap
, Context
->Device
->SourcesMax
);
2552 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2554 if(Context
->DefaultSlot
)
2556 auxslots
= al_calloc(DEF_ALIGN
, FAM_SIZE(struct ALeffectslotArray
, slot
, 1));
2557 auxslots
->count
= 1;
2558 auxslots
->slot
[0] = Context
->DefaultSlot
;
2562 auxslots
= al_calloc(DEF_ALIGN
, sizeof(struct ALeffectslotArray
));
2563 auxslots
->count
= 0;
2565 ATOMIC_INIT(&Context
->ActiveAuxSlots
, auxslots
);
2568 Context
->DistanceModel
= DefaultDistanceModel
;
2569 Context
->SourceDistanceModel
= AL_FALSE
;
2570 Context
->DopplerFactor
= 1.0f
;
2571 Context
->DopplerVelocity
= 1.0f
;
2572 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2573 Context
->MetersPerUnit
= AL_DEFAULT_METERS_PER_UNIT
;
2574 ATOMIC_FLAG_TEST_AND_SET(&Context
->PropsClean
, almemory_order_relaxed
);
2575 ATOMIC_INIT(&Context
->DeferUpdates
, AL_FALSE
);
2577 ATOMIC_INIT(&Context
->Update
, NULL
);
2578 ATOMIC_INIT(&Context
->FreeList
, NULL
);
2580 Context
->ExtensionList
= alExtList
;
2583 aluMatrixfSet(&listener
->Params
.Matrix
,
2584 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2585 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2586 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2587 0.0f
, 0.0f
, 0.0f
, 1.0f
2589 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2590 listener
->Params
.Gain
= listener
->Gain
;
2591 listener
->Params
.MetersPerUnit
= Context
->MetersPerUnit
;
2592 listener
->Params
.DopplerFactor
= Context
->DopplerFactor
;
2593 listener
->Params
.SpeedOfSound
= Context
->SpeedOfSound
* Context
->DopplerVelocity
;
2594 listener
->Params
.ReverbSpeedOfSound
= listener
->Params
.SpeedOfSound
*
2595 listener
->Params
.MetersPerUnit
;
2601 * Cleans up the context, and destroys any remaining objects the app failed to
2602 * delete. Called once there's no more references on the context.
2604 static void FreeContext(ALCcontext
*context
)
2606 ALlistener
*listener
= context
->Listener
;
2607 struct ALeffectslotArray
*auxslots
;
2608 struct ALlistenerProps
*lprops
;
2609 struct ALcontextProps
*cprops
;
2613 TRACE("%p\n", context
);
2615 if((cprops
=ATOMIC_LOAD(&context
->Update
, almemory_order_acquire
)) != NULL
)
2617 TRACE("Freed unapplied context update %p\n", cprops
);
2621 cprops
= ATOMIC_LOAD(&context
->FreeList
, almemory_order_acquire
);
2624 struct ALcontextProps
*next
= ATOMIC_LOAD(&cprops
->next
, almemory_order_acquire
);
2629 TRACE("Freed "SZFMT
" context property object%s\n", count
, (count
==1)?"":"s");
2631 if(context
->DefaultSlot
)
2633 DeinitEffectSlot(context
->DefaultSlot
);
2634 context
->DefaultSlot
= NULL
;
2637 auxslots
= ATOMIC_EXCHANGE_PTR(&context
->ActiveAuxSlots
, NULL
, almemory_order_relaxed
);
2640 if(context
->SourceMap
.size
> 0)
2642 WARN("(%p) Deleting %d Source%s\n", context
, context
->SourceMap
.size
,
2643 (context
->SourceMap
.size
==1)?"":"s");
2644 ReleaseALSources(context
);
2646 ResetUIntMap(&context
->SourceMap
);
2648 if(context
->EffectSlotMap
.size
> 0)
2650 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context
, context
->EffectSlotMap
.size
,
2651 (context
->EffectSlotMap
.size
==1)?"":"s");
2652 ReleaseALAuxiliaryEffectSlots(context
);
2654 ResetUIntMap(&context
->EffectSlotMap
);
2656 for(i
= 0;i
< context
->VoiceCount
;i
++)
2657 DeinitVoice(context
->Voices
[i
]);
2658 al_free(context
->Voices
);
2659 context
->Voices
= NULL
;
2660 context
->VoiceCount
= 0;
2661 context
->MaxVoices
= 0;
2663 if((lprops
=ATOMIC_LOAD(&listener
->Update
, almemory_order_acquire
)) != NULL
)
2665 TRACE("Freed unapplied listener update %p\n", lprops
);
2669 lprops
= ATOMIC_LOAD(&listener
->FreeList
, almemory_order_acquire
);
2672 struct ALlistenerProps
*next
= ATOMIC_LOAD(&lprops
->next
, almemory_order_acquire
);
2677 TRACE("Freed "SZFMT
" listener property object%s\n", count
, (count
==1)?"":"s");
2679 ALCdevice_DecRef(context
->Device
);
2680 context
->Device
= NULL
;
2682 //Invalidate context
2683 memset(context
, 0, sizeof(ALCcontext
));
2689 * Removes the context reference from the given device and removes it from
2690 * being current on the running thread or globally. Returns true if other
2691 * contexts still exist on the device.
2693 static bool ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2695 ALCcontext
*origctx
, *newhead
;
2698 if(altss_get(LocalContext
) == context
)
2700 WARN("%p released while current on thread\n", context
);
2701 altss_set(LocalContext
, NULL
);
2702 ALCcontext_DecRef(context
);
2706 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext
, &origctx
, NULL
))
2707 ALCcontext_DecRef(context
);
2709 ALCdevice_Lock(device
);
2711 newhead
= context
->next
;
2712 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device
->ContextList
, &origctx
, newhead
))
2714 ALCcontext
*volatile*list
= &origctx
->next
;
2717 if(*list
== context
)
2719 *list
= (*list
)->next
;
2722 list
= &(*list
)->next
;
2727 ALCdevice_Unlock(device
);
2729 ALCcontext_DecRef(context
);
2733 void ALCcontext_IncRef(ALCcontext
*context
)
2735 uint ref
= IncrementRef(&context
->ref
);
2736 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2739 void ALCcontext_DecRef(ALCcontext
*context
)
2741 uint ref
= DecrementRef(&context
->ref
);
2742 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2743 if(ref
== 0) FreeContext(context
);
2746 static void ReleaseThreadCtx(void *ptr
)
2748 ALCcontext
*context
= ptr
;
2749 uint ref
= DecrementRef(&context
->ref
);
2750 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2751 ERR("Context %p current for thread being destroyed, possible leak!\n", context
);
2756 * Checks that the given context is valid, and increments its reference count.
2758 static ALCboolean
VerifyContext(ALCcontext
**context
)
2763 dev
= ATOMIC_LOAD_SEQ(&DeviceList
);
2766 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
, almemory_order_acquire
);
2771 ALCcontext_IncRef(ctx
);
2788 * Returns the currently active context for this thread, and adds a reference
2789 * without locking it.
2791 ALCcontext
*GetContextRef(void)
2793 ALCcontext
*context
;
2795 context
= altss_get(LocalContext
);
2797 ALCcontext_IncRef(context
);
2801 context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
2803 ALCcontext_IncRef(context
);
2811 void AllocateVoices(ALCcontext
*context
, ALsizei num_voices
, ALsizei old_sends
)
2813 ALCdevice
*device
= context
->Device
;
2814 ALsizei num_sends
= device
->NumAuxSends
;
2815 struct ALvoiceProps
*props
;
2816 size_t sizeof_props
;
2817 size_t sizeof_voice
;
2823 if(num_voices
== context
->MaxVoices
&& num_sends
== old_sends
)
2826 /* Allocate the voice pointers, voices, and the voices' stored source
2827 * property set (including the dynamically-sized Send[] array) in one
2830 sizeof_voice
= RoundUp(FAM_SIZE(ALvoice
, Send
, num_sends
), 16);
2831 sizeof_props
= RoundUp(FAM_SIZE(struct ALvoiceProps
, Send
, num_sends
), 16);
2832 size
= sizeof(ALvoice
*) + sizeof_voice
+ sizeof_props
;
2834 voices
= al_calloc(16, RoundUp(size
*num_voices
, 16));
2835 /* The voice and property objects are stored interleaved since they're
2838 voice
= (ALvoice
*)((char*)voices
+ RoundUp(num_voices
*sizeof(ALvoice
*), 16));
2839 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2843 const ALsizei v_count
= mini(context
->VoiceCount
, num_voices
);
2844 const ALsizei s_count
= mini(old_sends
, num_sends
);
2846 for(;v
< v_count
;v
++)
2848 ALvoice
*old_voice
= context
->Voices
[v
];
2851 /* Copy the old voice data and source property set to the new
2854 *voice
= *old_voice
;
2855 for(i
= 0;i
< s_count
;i
++)
2856 voice
->Send
[i
] = old_voice
->Send
[i
];
2857 *props
= *(old_voice
->Props
);
2858 for(i
= 0;i
< s_count
;i
++)
2859 props
->Send
[i
] = old_voice
->Props
->Send
[i
];
2861 /* Set this voice's property set pointer and voice reference. */
2862 voice
->Props
= props
;
2865 /* Increment pointers to the next storage space. */
2866 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2867 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2869 /* Deinit any left over voices that weren't copied over to the new
2870 * array. NOTE: If this does anything, v equals num_voices and
2871 * num_voices is less than VoiceCount, so the following loop won't do
2874 for(;v
< context
->VoiceCount
;v
++)
2875 DeinitVoice(context
->Voices
[v
]);
2877 /* Finish setting the voices' property set pointers and references. */
2878 for(;v
< num_voices
;v
++)
2880 ATOMIC_INIT(&voice
->Update
, NULL
);
2881 ATOMIC_INIT(&voice
->FreeList
, NULL
);
2883 voice
->Props
= props
;
2886 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2887 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2890 al_free(context
->Voices
);
2891 context
->Voices
= voices
;
2892 context
->MaxVoices
= num_voices
;
2893 context
->VoiceCount
= mini(context
->VoiceCount
, num_voices
);
2897 /************************************************
2898 * Standard ALC functions
2899 ************************************************/
2903 * Return last ALC generated error code for the given device
2905 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2909 if(VerifyDevice(&device
))
2911 errorCode
= ATOMIC_EXCHANGE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
2912 ALCdevice_DecRef(device
);
2915 errorCode
= ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError
, ALC_NO_ERROR
);
2921 /* alcSuspendContext
2923 * Suspends updates for the given context
2925 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2930 if(!VerifyContext(&context
))
2931 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2934 ALCcontext_DeferUpdates(context
);
2935 ALCcontext_DecRef(context
);
2939 /* alcProcessContext
2941 * Resumes processing updates for the given context
2943 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2948 if(!VerifyContext(&context
))
2949 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2952 ALCcontext_ProcessUpdates(context
);
2953 ALCcontext_DecRef(context
);
2960 * Returns information about the device, and error strings
2962 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2964 const ALCchar
*value
= NULL
;
2972 case ALC_INVALID_ENUM
:
2973 value
= alcErrInvalidEnum
;
2976 case ALC_INVALID_VALUE
:
2977 value
= alcErrInvalidValue
;
2980 case ALC_INVALID_DEVICE
:
2981 value
= alcErrInvalidDevice
;
2984 case ALC_INVALID_CONTEXT
:
2985 value
= alcErrInvalidContext
;
2988 case ALC_OUT_OF_MEMORY
:
2989 value
= alcErrOutOfMemory
;
2992 case ALC_DEVICE_SPECIFIER
:
2993 value
= alcDefaultName
;
2996 case ALC_ALL_DEVICES_SPECIFIER
:
2997 if(VerifyDevice(&Device
))
2999 value
= alstr_get_cstr(Device
->DeviceName
);
3000 ALCdevice_DecRef(Device
);
3004 ProbeAllDevicesList();
3005 value
= alstr_get_cstr(alcAllDevicesList
);
3009 case ALC_CAPTURE_DEVICE_SPECIFIER
:
3010 if(VerifyDevice(&Device
))
3012 value
= alstr_get_cstr(Device
->DeviceName
);
3013 ALCdevice_DecRef(Device
);
3017 ProbeCaptureDeviceList();
3018 value
= alstr_get_cstr(alcCaptureDeviceList
);
3022 /* Default devices are always first in the list */
3023 case ALC_DEFAULT_DEVICE_SPECIFIER
:
3024 value
= alcDefaultName
;
3027 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
3028 if(alstr_empty(alcAllDevicesList
))
3029 ProbeAllDevicesList();
3031 VerifyDevice(&Device
);
3033 free(alcDefaultAllDevicesSpecifier
);
3034 alcDefaultAllDevicesSpecifier
= strdup(alstr_get_cstr(alcAllDevicesList
));
3035 if(!alcDefaultAllDevicesSpecifier
)
3036 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
3038 value
= alcDefaultAllDevicesSpecifier
;
3039 if(Device
) ALCdevice_DecRef(Device
);
3042 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
3043 if(alstr_empty(alcCaptureDeviceList
))
3044 ProbeCaptureDeviceList();
3046 VerifyDevice(&Device
);
3048 free(alcCaptureDefaultDeviceSpecifier
);
3049 alcCaptureDefaultDeviceSpecifier
= strdup(alstr_get_cstr(alcCaptureDeviceList
));
3050 if(!alcCaptureDefaultDeviceSpecifier
)
3051 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
3053 value
= alcCaptureDefaultDeviceSpecifier
;
3054 if(Device
) ALCdevice_DecRef(Device
);
3057 case ALC_EXTENSIONS
:
3058 if(!VerifyDevice(&Device
))
3059 value
= alcNoDeviceExtList
;
3062 value
= alcExtensionList
;
3063 ALCdevice_DecRef(Device
);
3067 case ALC_HRTF_SPECIFIER_SOFT
:
3068 if(!VerifyDevice(&Device
))
3069 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3072 almtx_lock(&Device
->BackendLock
);
3073 value
= (Device
->HrtfHandle
? alstr_get_cstr(Device
->HrtfName
) : "");
3074 almtx_unlock(&Device
->BackendLock
);
3075 ALCdevice_DecRef(Device
);
3080 VerifyDevice(&Device
);
3081 alcSetError(Device
, ALC_INVALID_ENUM
);
3082 if(Device
) ALCdevice_DecRef(Device
);
3090 static inline ALCsizei
NumAttrsForDevice(ALCdevice
*device
)
3092 if(device
->Type
== Loopback
&& device
->FmtChans
== DevFmtAmbi3D
)
3097 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3101 if(size
<= 0 || values
== NULL
)
3103 alcSetError(device
, ALC_INVALID_VALUE
);
3111 case ALC_MAJOR_VERSION
:
3112 values
[0] = alcMajorVersion
;
3114 case ALC_MINOR_VERSION
:
3115 values
[0] = alcMinorVersion
;
3118 case ALC_ATTRIBUTES_SIZE
:
3119 case ALC_ALL_ATTRIBUTES
:
3123 case ALC_MONO_SOURCES
:
3124 case ALC_STEREO_SOURCES
:
3125 case ALC_CAPTURE_SAMPLES
:
3126 case ALC_FORMAT_CHANNELS_SOFT
:
3127 case ALC_FORMAT_TYPE_SOFT
:
3128 case ALC_AMBISONIC_LAYOUT_SOFT
:
3129 case ALC_AMBISONIC_SCALING_SOFT
:
3130 case ALC_AMBISONIC_ORDER_SOFT
:
3131 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3135 alcSetError(NULL
, ALC_INVALID_ENUM
);
3141 if(device
->Type
== Capture
)
3145 case ALC_CAPTURE_SAMPLES
:
3146 almtx_lock(&device
->BackendLock
);
3147 values
[0] = V0(device
->Backend
,availableSamples
)();
3148 almtx_unlock(&device
->BackendLock
);
3152 values
[0] = device
->Connected
;
3156 alcSetError(device
, ALC_INVALID_ENUM
);
3165 case ALC_MAJOR_VERSION
:
3166 values
[0] = alcMajorVersion
;
3169 case ALC_MINOR_VERSION
:
3170 values
[0] = alcMinorVersion
;
3173 case ALC_EFX_MAJOR_VERSION
:
3174 values
[0] = alcEFXMajorVersion
;
3177 case ALC_EFX_MINOR_VERSION
:
3178 values
[0] = alcEFXMinorVersion
;
3181 case ALC_ATTRIBUTES_SIZE
:
3182 values
[0] = NumAttrsForDevice(device
);
3185 case ALC_ALL_ATTRIBUTES
:
3186 if(size
< NumAttrsForDevice(device
))
3188 alcSetError(device
, ALC_INVALID_VALUE
);
3193 almtx_lock(&device
->BackendLock
);
3194 values
[i
++] = ALC_FREQUENCY
;
3195 values
[i
++] = device
->Frequency
;
3197 if(device
->Type
!= Loopback
)
3199 values
[i
++] = ALC_REFRESH
;
3200 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3202 values
[i
++] = ALC_SYNC
;
3203 values
[i
++] = ALC_FALSE
;
3207 if(device
->FmtChans
== DevFmtAmbi3D
)
3209 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3210 values
[i
++] = device
->AmbiLayout
;
3212 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3213 values
[i
++] = device
->AmbiScale
;
3215 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3216 values
[i
++] = device
->AmbiOrder
;
3219 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3220 values
[i
++] = device
->FmtChans
;
3222 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3223 values
[i
++] = device
->FmtType
;
3226 values
[i
++] = ALC_MONO_SOURCES
;
3227 values
[i
++] = device
->NumMonoSources
;
3229 values
[i
++] = ALC_STEREO_SOURCES
;
3230 values
[i
++] = device
->NumStereoSources
;
3232 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3233 values
[i
++] = device
->NumAuxSends
;
3235 values
[i
++] = ALC_HRTF_SOFT
;
3236 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3238 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3239 values
[i
++] = device
->HrtfStatus
;
3241 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3242 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3243 almtx_unlock(&device
->BackendLock
);
3249 values
[0] = device
->Frequency
;
3253 if(device
->Type
== Loopback
)
3255 alcSetError(device
, ALC_INVALID_DEVICE
);
3258 almtx_lock(&device
->BackendLock
);
3259 values
[0] = device
->Frequency
/ device
->UpdateSize
;
3260 almtx_unlock(&device
->BackendLock
);
3264 if(device
->Type
== Loopback
)
3266 alcSetError(device
, ALC_INVALID_DEVICE
);
3269 values
[0] = ALC_FALSE
;
3272 case ALC_FORMAT_CHANNELS_SOFT
:
3273 if(device
->Type
!= Loopback
)
3275 alcSetError(device
, ALC_INVALID_DEVICE
);
3278 values
[0] = device
->FmtChans
;
3281 case ALC_FORMAT_TYPE_SOFT
:
3282 if(device
->Type
!= Loopback
)
3284 alcSetError(device
, ALC_INVALID_DEVICE
);
3287 values
[0] = device
->FmtType
;
3290 case ALC_AMBISONIC_LAYOUT_SOFT
:
3291 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3293 alcSetError(device
, ALC_INVALID_DEVICE
);
3296 values
[0] = device
->AmbiLayout
;
3299 case ALC_AMBISONIC_SCALING_SOFT
:
3300 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3302 alcSetError(device
, ALC_INVALID_DEVICE
);
3305 values
[0] = device
->AmbiScale
;
3308 case ALC_AMBISONIC_ORDER_SOFT
:
3309 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3311 alcSetError(device
, ALC_INVALID_DEVICE
);
3314 values
[0] = device
->AmbiOrder
;
3317 case ALC_MONO_SOURCES
:
3318 values
[0] = device
->NumMonoSources
;
3321 case ALC_STEREO_SOURCES
:
3322 values
[0] = device
->NumStereoSources
;
3325 case ALC_MAX_AUXILIARY_SENDS
:
3326 values
[0] = device
->NumAuxSends
;
3330 values
[0] = device
->Connected
;
3334 values
[0] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3337 case ALC_HRTF_STATUS_SOFT
:
3338 values
[0] = device
->HrtfStatus
;
3341 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
3342 almtx_lock(&device
->BackendLock
);
3343 FreeHrtfList(&device
->HrtfList
);
3344 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
3345 values
[0] = (ALCint
)VECTOR_SIZE(device
->HrtfList
);
3346 almtx_unlock(&device
->BackendLock
);
3349 case ALC_OUTPUT_LIMITER_SOFT
:
3350 values
[0] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3354 alcSetError(device
, ALC_INVALID_ENUM
);
3362 * Returns information about the device and the version of OpenAL
3364 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3366 VerifyDevice(&device
);
3367 if(size
<= 0 || values
== NULL
)
3368 alcSetError(device
, ALC_INVALID_VALUE
);
3370 GetIntegerv(device
, param
, size
, values
);
3371 if(device
) ALCdevice_DecRef(device
);
3374 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
3379 VerifyDevice(&device
);
3380 if(size
<= 0 || values
== NULL
)
3381 alcSetError(device
, ALC_INVALID_VALUE
);
3382 else if(!device
|| device
->Type
== Capture
)
3384 ivals
= malloc(size
* sizeof(ALCint
));
3385 size
= GetIntegerv(device
, pname
, size
, ivals
);
3386 for(i
= 0;i
< size
;i
++)
3387 values
[i
] = ivals
[i
];
3390 else /* render device */
3399 case ALC_ATTRIBUTES_SIZE
:
3400 *values
= NumAttrsForDevice(device
)+4;
3403 case ALC_ALL_ATTRIBUTES
:
3404 if(size
< NumAttrsForDevice(device
)+4)
3405 alcSetError(device
, ALC_INVALID_VALUE
);
3409 almtx_lock(&device
->BackendLock
);
3410 values
[i
++] = ALC_FREQUENCY
;
3411 values
[i
++] = device
->Frequency
;
3413 if(device
->Type
!= Loopback
)
3415 values
[i
++] = ALC_REFRESH
;
3416 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3418 values
[i
++] = ALC_SYNC
;
3419 values
[i
++] = ALC_FALSE
;
3423 if(device
->FmtChans
== DevFmtAmbi3D
)
3425 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3426 values
[i
++] = device
->AmbiLayout
;
3428 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3429 values
[i
++] = device
->AmbiScale
;
3431 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3432 values
[i
++] = device
->AmbiOrder
;
3435 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3436 values
[i
++] = device
->FmtChans
;
3438 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3439 values
[i
++] = device
->FmtType
;
3442 values
[i
++] = ALC_MONO_SOURCES
;
3443 values
[i
++] = device
->NumMonoSources
;
3445 values
[i
++] = ALC_STEREO_SOURCES
;
3446 values
[i
++] = device
->NumStereoSources
;
3448 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3449 values
[i
++] = device
->NumAuxSends
;
3451 values
[i
++] = ALC_HRTF_SOFT
;
3452 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3454 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3455 values
[i
++] = device
->HrtfStatus
;
3457 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3458 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3460 clock
= V0(device
->Backend
,getClockLatency
)();
3461 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3462 values
[i
++] = clock
.ClockTime
;
3464 values
[i
++] = ALC_DEVICE_LATENCY_SOFT
;
3465 values
[i
++] = clock
.Latency
;
3466 almtx_unlock(&device
->BackendLock
);
3472 case ALC_DEVICE_CLOCK_SOFT
:
3473 almtx_lock(&device
->BackendLock
);
3475 while(((refcount
=ReadRef(&device
->MixCount
))&1) != 0)
3477 basecount
= device
->ClockBase
;
3478 samplecount
= device
->SamplesDone
;
3479 } while(refcount
!= ReadRef(&device
->MixCount
));
3480 *values
= basecount
+ (samplecount
*DEVICE_CLOCK_RES
/device
->Frequency
);
3481 almtx_unlock(&device
->BackendLock
);
3484 case ALC_DEVICE_LATENCY_SOFT
:
3485 almtx_lock(&device
->BackendLock
);
3486 clock
= V0(device
->Backend
,getClockLatency
)();
3487 almtx_unlock(&device
->BackendLock
);
3488 *values
= clock
.Latency
;
3491 case ALC_DEVICE_CLOCK_LATENCY_SOFT
:
3493 alcSetError(device
, ALC_INVALID_VALUE
);
3496 almtx_lock(&device
->BackendLock
);
3497 clock
= V0(device
->Backend
,getClockLatency
)();
3498 almtx_unlock(&device
->BackendLock
);
3499 values
[0] = clock
.ClockTime
;
3500 values
[1] = clock
.Latency
;
3505 ivals
= malloc(size
* sizeof(ALCint
));
3506 size
= GetIntegerv(device
, pname
, size
, ivals
);
3507 for(i
= 0;i
< size
;i
++)
3508 values
[i
] = ivals
[i
];
3514 ALCdevice_DecRef(device
);
3518 /* alcIsExtensionPresent
3520 * Determines if there is support for a particular extension
3522 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3524 ALCboolean bResult
= ALC_FALSE
;
3526 VerifyDevice(&device
);
3529 alcSetError(device
, ALC_INVALID_VALUE
);
3532 size_t len
= strlen(extName
);
3533 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3536 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3537 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3542 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3546 } while(isspace(*ptr
));
3551 ALCdevice_DecRef(device
);
3556 /* alcGetProcAddress
3558 * Retrieves the function address for a particular extension function
3560 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3562 ALCvoid
*ptr
= NULL
;
3566 VerifyDevice(&device
);
3567 alcSetError(device
, ALC_INVALID_VALUE
);
3568 if(device
) ALCdevice_DecRef(device
);
3573 for(i
= 0;i
< COUNTOF(alcFunctions
);i
++)
3575 if(strcmp(alcFunctions
[i
].funcName
, funcName
) == 0)
3577 ptr
= alcFunctions
[i
].address
;
3589 * Get the value for a particular ALC enumeration name
3591 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3597 VerifyDevice(&device
);
3598 alcSetError(device
, ALC_INVALID_VALUE
);
3599 if(device
) ALCdevice_DecRef(device
);
3604 for(i
= 0;i
< COUNTOF(alcEnumerations
);i
++)
3606 if(strcmp(alcEnumerations
[i
].enumName
, enumName
) == 0)
3608 val
= alcEnumerations
[i
].value
;
3620 * Create and attach a context to the given device.
3622 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3624 ALCcontext
*ALContext
;
3628 /* Explicitly hold the list lock while taking the BackendLock in case the
3629 * device is asynchronously destropyed, to ensure this new context is
3630 * properly cleaned up after being made.
3633 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3636 alcSetError(device
, ALC_INVALID_DEVICE
);
3637 if(device
) ALCdevice_DecRef(device
);
3640 almtx_lock(&device
->BackendLock
);
3643 ATOMIC_STORE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
3645 if(device
->Type
== Playback
&& DefaultEffect
.type
!= AL_EFFECT_NULL
)
3646 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
)+sizeof(ALeffectslot
));
3648 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3651 almtx_unlock(&device
->BackendLock
);
3653 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3654 ALCdevice_DecRef(device
);
3658 InitRef(&ALContext
->ref
, 1);
3659 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3660 ALContext
->DefaultSlot
= NULL
;
3662 ALContext
->Voices
= NULL
;
3663 ALContext
->VoiceCount
= 0;
3664 ALContext
->MaxVoices
= 0;
3665 ATOMIC_INIT(&ALContext
->ActiveAuxSlots
, NULL
);
3666 ALContext
->Device
= device
;
3668 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3670 almtx_unlock(&device
->BackendLock
);
3675 alcSetError(device
, err
);
3676 if(err
== ALC_INVALID_DEVICE
)
3678 V0(device
->Backend
,lock
)();
3679 aluHandleDisconnect(device
);
3680 V0(device
->Backend
,unlock
)();
3682 ALCdevice_DecRef(device
);
3685 AllocateVoices(ALContext
, 256, device
->NumAuxSends
);
3687 if(DefaultEffect
.type
!= AL_EFFECT_NULL
&& device
->Type
== Playback
)
3689 ALContext
->DefaultSlot
= (ALeffectslot
*)(ALContext
->_listener_mem
+ sizeof(ALlistener
));
3690 if(InitEffectSlot(ALContext
->DefaultSlot
) == AL_NO_ERROR
)
3691 aluInitEffectPanning(ALContext
->DefaultSlot
);
3694 ALContext
->DefaultSlot
= NULL
;
3695 ERR("Failed to initialize the default effect slot\n");
3699 ALCdevice_IncRef(ALContext
->Device
);
3700 InitContext(ALContext
);
3702 if(ConfigValueFloat(alstr_get_cstr(device
->DeviceName
), NULL
, "volume-adjust", &valf
))
3705 ERR("volume-adjust must be finite: %f\n", valf
);
3708 ALfloat db
= clampf(valf
, -24.0f
, 24.0f
);
3710 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf
, 24.0f
);
3711 ALContext
->GainBoost
= powf(10.0f
, db
/20.0f
);
3712 TRACE("volume-adjust gain: %f\n", ALContext
->GainBoost
);
3715 UpdateListenerProps(ALContext
);
3718 ALCcontext
*head
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
3720 ALContext
->next
= head
;
3721 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device
->ContextList
, &head
,
3724 almtx_unlock(&device
->BackendLock
);
3726 if(ALContext
->DefaultSlot
)
3728 if(InitializeEffect(device
, ALContext
->DefaultSlot
, &DefaultEffect
) == AL_NO_ERROR
)
3729 UpdateEffectSlotProps(ALContext
->DefaultSlot
);
3731 ERR("Failed to initialize the default effect\n");
3734 ALCdevice_DecRef(device
);
3736 TRACE("Created context %p\n", ALContext
);
3740 /* alcDestroyContext
3742 * Remove a context from its device
3744 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3749 if(!VerifyContext(&context
))
3752 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3756 Device
= context
->Device
;
3759 almtx_lock(&Device
->BackendLock
);
3760 if(!ReleaseContext(context
, Device
))
3762 V0(Device
->Backend
,stop
)();
3763 Device
->Flags
&= ~DEVICE_RUNNING
;
3765 almtx_unlock(&Device
->BackendLock
);
3769 ALCcontext_DecRef(context
);
3773 /* alcGetCurrentContext
3775 * Returns the currently active context on the calling thread
3777 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3779 ALCcontext
*Context
= altss_get(LocalContext
);
3780 if(!Context
) Context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
3784 /* alcGetThreadContext
3786 * Returns the currently active thread-local context
3788 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3790 return altss_get(LocalContext
);
3794 /* alcMakeContextCurrent
3796 * Makes the given context the active process-wide context, and removes the
3797 * thread-local context for the calling thread.
3799 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3801 /* context must be valid or NULL */
3802 if(context
&& !VerifyContext(&context
))
3804 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3807 /* context's reference count is already incremented */
3808 context
= ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext
, context
);
3809 if(context
) ALCcontext_DecRef(context
);
3811 if((context
=altss_get(LocalContext
)) != NULL
)
3813 altss_set(LocalContext
, NULL
);
3814 ALCcontext_DecRef(context
);
3820 /* alcSetThreadContext
3822 * Makes the given context the active context for the current thread
3824 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3828 /* context must be valid or NULL */
3829 if(context
&& !VerifyContext(&context
))
3831 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3834 /* context's reference count is already incremented */
3835 old
= altss_get(LocalContext
);
3836 altss_set(LocalContext
, context
);
3837 if(old
) ALCcontext_DecRef(old
);
3843 /* alcGetContextsDevice
3845 * Returns the device that a particular context is attached to
3847 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3851 if(!VerifyContext(&Context
))
3853 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3856 Device
= Context
->Device
;
3857 ALCcontext_DecRef(Context
);
3865 * Opens the named device.
3867 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3869 ALCbackendFactory
*factory
;
3877 if(!PlaybackBackend
.name
)
3879 alcSetError(NULL
, ALC_INVALID_VALUE
);
3883 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3885 /* Some old Windows apps hardcode these expecting OpenAL to use a
3886 * specific audio API, even when they're not enumerated. Creative's
3887 * router effectively ignores them too.
3889 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3890 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3895 device
= al_calloc(16, sizeof(ALCdevice
));
3898 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3903 InitRef(&device
->ref
, 1);
3904 device
->Connected
= ALC_TRUE
;
3905 device
->Type
= Playback
;
3906 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3909 device
->Bs2b
= NULL
;
3910 device
->Uhj_Encoder
= NULL
;
3911 device
->Hrtf
= NULL
;
3912 device
->HrtfHandle
= NULL
;
3913 VECTOR_INIT(device
->HrtfList
);
3914 AL_STRING_INIT(device
->HrtfName
);
3915 device
->Render_Mode
= NormalRender
;
3916 AL_STRING_INIT(device
->DeviceName
);
3917 device
->Dry
.Buffer
= NULL
;
3918 device
->Dry
.NumChannels
= 0;
3919 device
->FOAOut
.Buffer
= NULL
;
3920 device
->FOAOut
.NumChannels
= 0;
3921 device
->RealOut
.Buffer
= NULL
;
3922 device
->RealOut
.NumChannels
= 0;
3923 device
->Limiter
= NULL
;
3924 device
->AvgSpeakerDist
= 0.0f
;
3926 ATOMIC_INIT(&device
->ContextList
, NULL
);
3928 device
->ClockBase
= 0;
3929 device
->SamplesDone
= 0;
3931 device
->SourcesMax
= 256;
3932 device
->AuxiliaryEffectSlotMax
= 64;
3933 device
->NumAuxSends
= DEFAULT_SENDS
;
3935 InitUIntMap(&device
->BufferMap
, INT_MAX
);
3936 InitUIntMap(&device
->EffectMap
, INT_MAX
);
3937 InitUIntMap(&device
->FilterMap
, INT_MAX
);
3939 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
3941 device
->ChannelDelay
[i
].Gain
= 1.0f
;
3942 device
->ChannelDelay
[i
].Length
= 0;
3943 device
->ChannelDelay
[i
].Buffer
= NULL
;
3947 device
->FmtChans
= DevFmtChannelsDefault
;
3948 device
->FmtType
= DevFmtTypeDefault
;
3949 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3950 device
->IsHeadphones
= AL_FALSE
;
3951 device
->AmbiLayout
= AmbiLayout_Default
;
3952 device
->AmbiScale
= AmbiNorm_Default
;
3953 device
->NumUpdates
= 3;
3954 device
->UpdateSize
= 1024;
3956 factory
= PlaybackBackend
.getFactory();
3957 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3958 if(!device
->Backend
)
3961 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3966 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3968 static const struct {
3969 const char name
[16];
3970 enum DevFmtChannels chans
;
3973 { "mono", DevFmtMono
, 0 },
3974 { "stereo", DevFmtStereo
, 0 },
3975 { "quad", DevFmtQuad
, 0 },
3976 { "surround51", DevFmtX51
, 0 },
3977 { "surround61", DevFmtX61
, 0 },
3978 { "surround71", DevFmtX71
, 0 },
3979 { "surround51rear", DevFmtX51Rear
, 0 },
3980 { "ambi1", DevFmtAmbi3D
, 1 },
3981 { "ambi2", DevFmtAmbi3D
, 2 },
3982 { "ambi3", DevFmtAmbi3D
, 3 },
3986 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3988 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3990 device
->FmtChans
= chanlist
[i
].chans
;
3991 device
->AmbiOrder
= chanlist
[i
].order
;
3992 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3996 if(i
== COUNTOF(chanlist
))
3997 ERR("Unsupported channels: %s\n", fmt
);
3999 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
4001 static const struct {
4002 const char name
[16];
4003 enum DevFmtType type
;
4005 { "int8", DevFmtByte
},
4006 { "uint8", DevFmtUByte
},
4007 { "int16", DevFmtShort
},
4008 { "uint16", DevFmtUShort
},
4009 { "int32", DevFmtInt
},
4010 { "uint32", DevFmtUInt
},
4011 { "float32", DevFmtFloat
},
4015 for(i
= 0;i
< COUNTOF(typelist
);i
++)
4017 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
4019 device
->FmtType
= typelist
[i
].type
;
4020 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
4024 if(i
== COUNTOF(typelist
))
4025 ERR("Unsupported sample-type: %s\n", fmt
);
4028 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
4030 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4031 if(device
->Frequency
< MIN_OUTPUT_RATE
)
4032 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
4033 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
4036 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
4037 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
4039 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
4040 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
4041 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
4042 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
4044 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
4045 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4047 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4048 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4050 if(ConfigValueInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
))
4051 device
->NumAuxSends
= clampi(
4052 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4055 device
->NumStereoSources
= 1;
4056 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4058 // Find a playback device to open
4059 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4061 DELETE_OBJ(device
->Backend
);
4063 alcSetError(NULL
, err
);
4066 almtx_init(&device
->BackendLock
, almtx_plain
);
4068 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "ambi-format", &fmt
))
4070 if(strcasecmp(fmt
, "fuma") == 0)
4072 device
->AmbiLayout
= AmbiLayout_FuMa
;
4073 device
->AmbiScale
= AmbiNorm_FuMa
;
4075 else if(strcasecmp(fmt
, "acn+sn3d") == 0)
4077 device
->AmbiLayout
= AmbiLayout_ACN
;
4078 device
->AmbiScale
= AmbiNorm_SN3D
;
4080 else if(strcasecmp(fmt
, "acn+n3d") == 0)
4082 device
->AmbiLayout
= AmbiLayout_ACN
;
4083 device
->AmbiScale
= AmbiNorm_N3D
;
4086 ERR("Unsupported ambi-format: %s\n", fmt
);
4089 device
->Limiter
= CreateDeviceLimiter(device
);
4092 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4094 device
->next
= head
;
4095 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4098 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4104 * Closes the given device.
4106 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
4108 ALCdevice
*iter
, *origdev
;
4112 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4116 } while((iter
=iter
->next
) != NULL
);
4117 if(!iter
|| iter
->Type
== Capture
)
4119 alcSetError(iter
, ALC_INVALID_DEVICE
);
4123 almtx_lock(&device
->BackendLock
);
4126 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4128 ALCdevice
*volatile*list
= &origdev
->next
;
4133 *list
= (*list
)->next
;
4136 list
= &(*list
)->next
;
4141 ctx
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
4144 ALCcontext
*next
= ctx
->next
;
4145 WARN("Releasing context %p\n", ctx
);
4146 ReleaseContext(ctx
, device
);
4149 if((device
->Flags
&DEVICE_RUNNING
))
4150 V0(device
->Backend
,stop
)();
4151 device
->Flags
&= ~DEVICE_RUNNING
;
4152 almtx_unlock(&device
->BackendLock
);
4154 ALCdevice_DecRef(device
);
4160 /************************************************
4161 * ALC capture functions
4162 ************************************************/
4163 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
4165 ALCbackendFactory
*factory
;
4166 ALCdevice
*device
= NULL
;
4172 if(!CaptureBackend
.name
)
4174 alcSetError(NULL
, ALC_INVALID_VALUE
);
4180 alcSetError(NULL
, ALC_INVALID_VALUE
);
4184 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
4187 device
= al_calloc(16, sizeof(ALCdevice
));
4190 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4195 InitRef(&device
->ref
, 1);
4196 device
->Connected
= ALC_TRUE
;
4197 device
->Type
= Capture
;
4199 device
->Hrtf
= NULL
;
4200 device
->HrtfHandle
= NULL
;
4201 VECTOR_INIT(device
->HrtfList
);
4202 AL_STRING_INIT(device
->HrtfName
);
4204 AL_STRING_INIT(device
->DeviceName
);
4205 device
->Dry
.Buffer
= NULL
;
4206 device
->Dry
.NumChannels
= 0;
4207 device
->FOAOut
.Buffer
= NULL
;
4208 device
->FOAOut
.NumChannels
= 0;
4209 device
->RealOut
.Buffer
= NULL
;
4210 device
->RealOut
.NumChannels
= 0;
4212 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4213 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4214 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4216 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4218 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4219 device
->ChannelDelay
[i
].Length
= 0;
4220 device
->ChannelDelay
[i
].Buffer
= NULL
;
4223 factory
= CaptureBackend
.getFactory();
4224 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
4225 if(!device
->Backend
)
4228 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4232 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4233 device
->Frequency
= frequency
;
4235 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
4236 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
4239 alcSetError(NULL
, ALC_INVALID_ENUM
);
4242 device
->IsHeadphones
= AL_FALSE
;
4243 device
->AmbiOrder
= 0;
4244 device
->AmbiLayout
= AmbiLayout_Default
;
4245 device
->AmbiScale
= AmbiNorm_Default
;
4247 device
->UpdateSize
= samples
;
4248 device
->NumUpdates
= 1;
4250 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4251 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
4252 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
4254 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4257 alcSetError(NULL
, err
);
4260 almtx_init(&device
->BackendLock
, almtx_plain
);
4263 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4265 device
->next
= head
;
4266 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4269 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4273 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
4275 ALCdevice
*iter
, *origdev
;
4278 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4282 } while((iter
=iter
->next
) != NULL
);
4283 if(!iter
|| iter
->Type
!= Capture
)
4285 alcSetError(iter
, ALC_INVALID_DEVICE
);
4291 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4293 ALCdevice
*volatile*list
= &origdev
->next
;
4298 *list
= (*list
)->next
;
4301 list
= &(*list
)->next
;
4306 ALCdevice_DecRef(device
);
4311 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
4313 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4314 alcSetError(device
, ALC_INVALID_DEVICE
);
4317 almtx_lock(&device
->BackendLock
);
4318 if(!device
->Connected
)
4319 alcSetError(device
, ALC_INVALID_DEVICE
);
4320 else if(!(device
->Flags
&DEVICE_RUNNING
))
4322 if(V0(device
->Backend
,start
)())
4323 device
->Flags
|= DEVICE_RUNNING
;
4326 aluHandleDisconnect(device
);
4327 alcSetError(device
, ALC_INVALID_DEVICE
);
4330 almtx_unlock(&device
->BackendLock
);
4333 if(device
) ALCdevice_DecRef(device
);
4336 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
4338 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4339 alcSetError(device
, ALC_INVALID_DEVICE
);
4342 almtx_lock(&device
->BackendLock
);
4343 if((device
->Flags
&DEVICE_RUNNING
))
4344 V0(device
->Backend
,stop
)();
4345 device
->Flags
&= ~DEVICE_RUNNING
;
4346 almtx_unlock(&device
->BackendLock
);
4349 if(device
) ALCdevice_DecRef(device
);
4352 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4354 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4355 alcSetError(device
, ALC_INVALID_DEVICE
);
4358 ALCenum err
= ALC_INVALID_VALUE
;
4360 almtx_lock(&device
->BackendLock
);
4361 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
4362 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
4363 almtx_unlock(&device
->BackendLock
);
4365 if(err
!= ALC_NO_ERROR
)
4366 alcSetError(device
, err
);
4368 if(device
) ALCdevice_DecRef(device
);
4372 /************************************************
4373 * ALC loopback functions
4374 ************************************************/
4376 /* alcLoopbackOpenDeviceSOFT
4378 * Open a loopback device, for manual rendering.
4380 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
4382 ALCbackendFactory
*factory
;
4388 /* Make sure the device name, if specified, is us. */
4389 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
4391 alcSetError(NULL
, ALC_INVALID_VALUE
);
4395 device
= al_calloc(16, sizeof(ALCdevice
));
4398 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4403 InitRef(&device
->ref
, 1);
4404 device
->Connected
= ALC_TRUE
;
4405 device
->Type
= Loopback
;
4406 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
4409 device
->Hrtf
= NULL
;
4410 device
->HrtfHandle
= NULL
;
4411 VECTOR_INIT(device
->HrtfList
);
4412 AL_STRING_INIT(device
->HrtfName
);
4413 device
->Bs2b
= NULL
;
4414 device
->Uhj_Encoder
= NULL
;
4415 device
->Render_Mode
= NormalRender
;
4416 AL_STRING_INIT(device
->DeviceName
);
4417 device
->Dry
.Buffer
= NULL
;
4418 device
->Dry
.NumChannels
= 0;
4419 device
->FOAOut
.Buffer
= NULL
;
4420 device
->FOAOut
.NumChannels
= 0;
4421 device
->RealOut
.Buffer
= NULL
;
4422 device
->RealOut
.NumChannels
= 0;
4423 device
->Limiter
= NULL
;
4424 device
->AvgSpeakerDist
= 0.0f
;
4426 ATOMIC_INIT(&device
->ContextList
, NULL
);
4428 device
->ClockBase
= 0;
4429 device
->SamplesDone
= 0;
4431 device
->SourcesMax
= 256;
4432 device
->AuxiliaryEffectSlotMax
= 64;
4433 device
->NumAuxSends
= DEFAULT_SENDS
;
4435 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4436 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4437 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4439 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4441 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4442 device
->ChannelDelay
[i
].Length
= 0;
4443 device
->ChannelDelay
[i
].Buffer
= NULL
;
4446 factory
= ALCloopbackFactory_getFactory();
4447 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
4448 if(!device
->Backend
)
4451 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4454 almtx_init(&device
->BackendLock
, almtx_plain
);
4457 device
->NumUpdates
= 0;
4458 device
->UpdateSize
= 0;
4460 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
4461 device
->FmtChans
= DevFmtChannelsDefault
;
4462 device
->FmtType
= DevFmtTypeDefault
;
4463 device
->IsHeadphones
= AL_FALSE
;
4464 device
->AmbiLayout
= AmbiLayout_Default
;
4465 device
->AmbiScale
= AmbiNorm_Default
;
4467 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
4468 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4470 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4471 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4473 if(ConfigValueInt(NULL
, NULL
, "sends", &device
->NumAuxSends
))
4474 device
->NumAuxSends
= clampi(
4475 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4478 device
->NumStereoSources
= 1;
4479 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4481 // Open the "backend"
4482 V(device
->Backend
,open
)("Loopback");
4484 device
->Limiter
= CreateDeviceLimiter(device
);
4487 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4489 device
->next
= head
;
4490 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4493 TRACE("Created device %p\n", device
);
4497 /* alcIsRenderFormatSupportedSOFT
4499 * Determines if the loopback device supports the given format for rendering.
4501 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
4503 ALCboolean ret
= ALC_FALSE
;
4505 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4506 alcSetError(device
, ALC_INVALID_DEVICE
);
4508 alcSetError(device
, ALC_INVALID_VALUE
);
4511 if(IsValidALCType(type
) && IsValidALCChannels(channels
) && freq
>= MIN_OUTPUT_RATE
)
4514 if(device
) ALCdevice_DecRef(device
);
4519 /* alcRenderSamplesSOFT
4521 * Renders some samples into a buffer, using the format last set by the
4522 * attributes given to alcCreateContext.
4524 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4526 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4527 alcSetError(device
, ALC_INVALID_DEVICE
);
4528 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
4529 alcSetError(device
, ALC_INVALID_VALUE
);
4532 V0(device
->Backend
,lock
)();
4533 aluMixData(device
, buffer
, samples
);
4534 V0(device
->Backend
,unlock
)();
4536 if(device
) ALCdevice_DecRef(device
);
4540 /************************************************
4541 * ALC loopback2 functions
4542 ************************************************/
4544 ALC_API ALCboolean ALC_APIENTRY
alcIsAmbisonicFormatSupportedSOFT(ALCdevice
*device
, ALCenum layout
, ALCenum scaling
, ALsizei order
)
4546 ALCboolean ret
= ALC_FALSE
;
4548 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4549 alcSetError(device
, ALC_INVALID_DEVICE
);
4551 alcSetError(device
, ALC_INVALID_VALUE
);
4554 if(IsValidAmbiLayout(layout
) && IsValidAmbiScaling(scaling
) && order
<= MAX_AMBI_ORDER
)
4557 if(device
) ALCdevice_DecRef(device
);
4562 /************************************************
4563 * ALC DSP pause/resume functions
4564 ************************************************/
4566 /* alcDevicePauseSOFT
4568 * Pause the DSP to stop audio processing.
4570 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
4572 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4573 alcSetError(device
, ALC_INVALID_DEVICE
);
4576 almtx_lock(&device
->BackendLock
);
4577 if((device
->Flags
&DEVICE_RUNNING
))
4578 V0(device
->Backend
,stop
)();
4579 device
->Flags
&= ~DEVICE_RUNNING
;
4580 device
->Flags
|= DEVICE_PAUSED
;
4581 almtx_unlock(&device
->BackendLock
);
4583 if(device
) ALCdevice_DecRef(device
);
4586 /* alcDeviceResumeSOFT
4588 * Resume the DSP to restart audio processing.
4590 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
4592 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4593 alcSetError(device
, ALC_INVALID_DEVICE
);
4596 almtx_lock(&device
->BackendLock
);
4597 if((device
->Flags
&DEVICE_PAUSED
))
4599 device
->Flags
&= ~DEVICE_PAUSED
;
4600 if(ATOMIC_LOAD_SEQ(&device
->ContextList
) != NULL
)
4602 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4603 device
->Flags
|= DEVICE_RUNNING
;
4606 alcSetError(device
, ALC_INVALID_DEVICE
);
4607 V0(device
->Backend
,lock
)();
4608 aluHandleDisconnect(device
);
4609 V0(device
->Backend
,unlock
)();
4613 almtx_unlock(&device
->BackendLock
);
4615 if(device
) ALCdevice_DecRef(device
);
4619 /************************************************
4620 * ALC HRTF functions
4621 ************************************************/
4623 /* alcGetStringiSOFT
4625 * Gets a string parameter at the given index.
4627 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4629 const ALCchar
*str
= NULL
;
4631 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4632 alcSetError(device
, ALC_INVALID_DEVICE
);
4633 else switch(paramName
)
4635 case ALC_HRTF_SPECIFIER_SOFT
:
4636 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->HrtfList
))
4637 str
= alstr_get_cstr(VECTOR_ELEM(device
->HrtfList
, index
).name
);
4639 alcSetError(device
, ALC_INVALID_VALUE
);
4643 alcSetError(device
, ALC_INVALID_ENUM
);
4646 if(device
) ALCdevice_DecRef(device
);
4651 /* alcResetDeviceSOFT
4653 * Resets the given device output, using the specified attribute list.
4655 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4660 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4663 alcSetError(device
, ALC_INVALID_DEVICE
);
4664 if(device
) ALCdevice_DecRef(device
);
4667 almtx_lock(&device
->BackendLock
);
4670 err
= UpdateDeviceParams(device
, attribs
);
4671 almtx_unlock(&device
->BackendLock
);
4673 if(err
!= ALC_NO_ERROR
)
4675 alcSetError(device
, err
);
4676 if(err
== ALC_INVALID_DEVICE
)
4678 V0(device
->Backend
,lock
)();
4679 aluHandleDisconnect(device
);
4680 V0(device
->Backend
,unlock
)();
4682 ALCdevice_DecRef(device
);
4685 ALCdevice_DecRef(device
);