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 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
889 assert(ret
== althrd_success
);
891 ret
= almtx_init(&ListLock
, almtx_recursive
);
892 assert(ret
== althrd_success
);
897 static void alc_initconfig(void)
899 const char *devs
, *str
;
904 str
= getenv("ALSOFT_LOGLEVEL");
907 long lvl
= strtol(str
, NULL
, 0);
908 if(lvl
>= NoLog
&& lvl
<= LogRef
)
912 str
= getenv("ALSOFT_LOGFILE");
915 FILE *logfile
= al_fopen(str
, "wt");
916 if(logfile
) LogFile
= logfile
;
917 else ERR("Failed to open log file '%s'\n", str
);
920 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION
,
921 ALSOFT_GIT_COMMIT_HASH
, ALSOFT_GIT_BRANCH
);
926 if(BackendListSize
> 0)
927 len
+= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
928 for(i
= 1;i
< BackendListSize
;i
++)
929 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
930 TRACE("Supported backends: %s\n", buf
);
934 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
937 if(strcasecmp(str
, "ignore") == 0)
939 SuspendDefers
= ALC_FALSE
;
940 TRACE("Selected context suspend behavior, \"ignore\"\n");
943 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
947 #if defined(HAVE_SSE4_1)
948 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
949 #elif defined(HAVE_SSE3)
950 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
951 #elif defined(HAVE_SSE2)
952 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
953 #elif defined(HAVE_SSE)
954 capfilter
|= CPU_CAP_SSE
;
957 capfilter
|= CPU_CAP_NEON
;
959 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
961 if(strcasecmp(str
, "all") == 0)
966 const char *next
= str
;
970 while(isspace(str
[0]))
972 next
= strchr(str
, ',');
974 if(!str
[0] || str
[0] == ',')
977 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
978 while(len
> 0 && isspace(str
[len
-1]))
980 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
981 capfilter
&= ~CPU_CAP_SSE
;
982 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
983 capfilter
&= ~CPU_CAP_SSE2
;
984 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
985 capfilter
&= ~CPU_CAP_SSE3
;
986 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
987 capfilter
&= ~CPU_CAP_SSE4_1
;
988 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
989 capfilter
&= ~CPU_CAP_NEON
;
991 WARN("Invalid CPU extension \"%s\"\n", str
);
995 FillCPUCaps(capfilter
);
1002 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
1006 str
= getenv("ALSOFT_TRAP_ERROR");
1007 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1009 TrapALError
= AL_TRUE
;
1010 TrapALCError
= AL_TRUE
;
1014 str
= getenv("ALSOFT_TRAP_AL_ERROR");
1015 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1016 TrapALError
= AL_TRUE
;
1017 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
1019 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1020 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1021 TrapALCError
= ALC_TRUE
;
1022 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1025 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1026 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1028 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1030 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1031 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1035 const char *next
= devs
;
1036 int endlist
, delitem
;
1041 while(isspace(devs
[0]))
1043 next
= strchr(devs
, ',');
1045 delitem
= (devs
[0] == '-');
1046 if(devs
[0] == '-') devs
++;
1048 if(!devs
[0] || devs
[0] == ',')
1055 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1056 while(len
> 0 && isspace(devs
[len
-1]))
1058 for(n
= i
;n
< BackendListSize
;n
++)
1060 if(len
== strlen(BackendList
[n
].name
) &&
1061 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1065 for(;n
+1 < BackendListSize
;n
++)
1066 BackendList
[n
] = BackendList
[n
+1];
1071 struct BackendInfo Bkp
= BackendList
[n
];
1073 BackendList
[n
] = BackendList
[n
-1];
1074 BackendList
[n
] = Bkp
;
1084 BackendListSize
= i
;
1087 for(i
= 0;i
< BackendListSize
&& (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1089 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1090 if(!V0(factory
,init
)())
1092 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1096 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1097 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1099 PlaybackBackend
= BackendList
[i
];
1100 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1102 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1104 CaptureBackend
= BackendList
[i
];
1105 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1109 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1113 if(!PlaybackBackend
.name
)
1114 WARN("No playback backend available!\n");
1115 if(!CaptureBackend
.name
)
1116 WARN("No capture backend available!\n");
1118 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1121 const char *next
= str
;
1125 next
= strchr(str
, ',');
1127 if(!str
[0] || next
== str
)
1130 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1131 for(n
= 0;EffectList
[n
].name
;n
++)
1133 if(len
== strlen(EffectList
[n
].name
) &&
1134 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1135 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1140 InitEffectFactoryMap();
1142 InitEffect(&DefaultEffect
);
1143 str
= getenv("ALSOFT_DEFAULT_REVERB");
1144 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1145 LoadReverbPreset(str
, &DefaultEffect
);
1147 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1152 static JavaVM
*gJavaVM
;
1153 static pthread_key_t gJVMThreadKey
;
1155 static void CleanupJNIEnv(void* UNUSED(ptr
))
1157 JCALL0(gJavaVM
,DetachCurrentThread
)();
1160 void *Android_GetJNIEnv(void)
1164 WARN("gJavaVM is NULL!\n");
1168 /* http://developer.android.com/guide/practices/jni.html
1170 * All threads are Linux threads, scheduled by the kernel. They're usually
1171 * started from managed code (using Thread.start), but they can also be
1172 * created elsewhere and then attached to the JavaVM. For example, a thread
1173 * started with pthread_create can be attached with the JNI
1174 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1175 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1176 * Attaching a natively-created thread causes a java.lang.Thread object to
1177 * be constructed and added to the "main" ThreadGroup, making it visible to
1178 * the debugger. Calling AttachCurrentThread on an already-attached thread
1181 JNIEnv
*env
= pthread_getspecific(gJVMThreadKey
);
1184 int status
= JCALL(gJavaVM
,AttachCurrentThread
)(&env
, NULL
);
1187 ERR("Failed to attach current thread\n");
1190 pthread_setspecific(gJVMThreadKey
, env
);
1195 /* Automatically called by JNI. */
1196 JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM
*jvm
, void* UNUSED(reserved
))
1202 if(JCALL(gJavaVM
,GetEnv
)(&env
, JNI_VERSION_1_4
) != JNI_OK
)
1204 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1208 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1209 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1211 if((err
=pthread_key_create(&gJVMThreadKey
, CleanupJNIEnv
)) != 0)
1212 ERR("pthread_key_create failed: %d\n", err
);
1213 pthread_setspecific(gJVMThreadKey
, env
);
1214 return JNI_VERSION_1_4
;
1217 /* Android doesn't have log2f, really? */
1218 #define log2f(x) (logf(x) / logf(2.0f))
1222 /************************************************
1223 * Library deinitialization
1224 ************************************************/
1225 static void alc_cleanup(void)
1229 AL_STRING_DEINIT(alcAllDevicesList
);
1230 AL_STRING_DEINIT(alcCaptureDeviceList
);
1232 free(alcDefaultAllDevicesSpecifier
);
1233 alcDefaultAllDevicesSpecifier
= NULL
;
1234 free(alcCaptureDefaultDeviceSpecifier
);
1235 alcCaptureDefaultDeviceSpecifier
= NULL
;
1237 if((dev
=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList
, NULL
)) != NULL
)
1242 } while((dev
=dev
->next
) != NULL
);
1243 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1246 DeinitEffectFactoryMap();
1249 static void alc_deinit_safe(void)
1257 almtx_destroy(&ListLock
);
1258 altss_delete(LocalContext
);
1260 if(LogFile
!= stderr
)
1265 static void alc_deinit(void)
1271 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1272 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1274 for(i
= 0;i
< BackendListSize
;i
++)
1276 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1277 V0(factory
,deinit
)();
1280 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1281 V0(factory
,deinit
)();
1288 /************************************************
1289 * Device enumeration
1290 ************************************************/
1291 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1293 ALCbackendFactory
*factory
;
1300 factory
= backendinfo
->getFactory();
1301 V(factory
,probe
)(type
);
1305 static void ProbeAllDevicesList(void)
1306 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1307 static void ProbeCaptureDeviceList(void)
1308 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1310 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1312 size_t len
= strlen(name
);
1314 alstr_append_range(devnames
, name
, name
+len
+1);
1316 void AppendAllDevicesList(const ALCchar
*name
)
1317 { AppendDevice(name
, &alcAllDevicesList
); }
1318 void AppendCaptureDeviceList(const ALCchar
*name
)
1319 { AppendDevice(name
, &alcCaptureDeviceList
); }
1322 /************************************************
1323 * Device format information
1324 ************************************************/
1325 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1329 case DevFmtByte
: return "Signed Byte";
1330 case DevFmtUByte
: return "Unsigned Byte";
1331 case DevFmtShort
: return "Signed Short";
1332 case DevFmtUShort
: return "Unsigned Short";
1333 case DevFmtInt
: return "Signed Int";
1334 case DevFmtUInt
: return "Unsigned Int";
1335 case DevFmtFloat
: return "Float";
1337 return "(unknown type)";
1339 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1343 case DevFmtMono
: return "Mono";
1344 case DevFmtStereo
: return "Stereo";
1345 case DevFmtQuad
: return "Quadraphonic";
1346 case DevFmtX51
: return "5.1 Surround";
1347 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1348 case DevFmtX61
: return "6.1 Surround";
1349 case DevFmtX71
: return "7.1 Surround";
1350 case DevFmtAmbi3D
: return "Ambisonic 3D";
1352 return "(unknown channels)";
1355 extern inline ALsizei
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
, ALsizei ambiorder
);
1356 ALsizei
BytesFromDevFmt(enum DevFmtType type
)
1360 case DevFmtByte
: return sizeof(ALbyte
);
1361 case DevFmtUByte
: return sizeof(ALubyte
);
1362 case DevFmtShort
: return sizeof(ALshort
);
1363 case DevFmtUShort
: return sizeof(ALushort
);
1364 case DevFmtInt
: return sizeof(ALint
);
1365 case DevFmtUInt
: return sizeof(ALuint
);
1366 case DevFmtFloat
: return sizeof(ALfloat
);
1370 ALsizei
ChannelsFromDevFmt(enum DevFmtChannels chans
, ALsizei ambiorder
)
1374 case DevFmtMono
: return 1;
1375 case DevFmtStereo
: return 2;
1376 case DevFmtQuad
: return 4;
1377 case DevFmtX51
: return 6;
1378 case DevFmtX51Rear
: return 6;
1379 case DevFmtX61
: return 7;
1380 case DevFmtX71
: return 8;
1381 case DevFmtAmbi3D
: return (ambiorder
>= 3) ? 16 :
1382 (ambiorder
== 2) ? 9 :
1383 (ambiorder
== 1) ? 4 : 1;
1388 static ALboolean
DecomposeDevFormat(ALenum format
, enum DevFmtChannels
*chans
,
1389 enum DevFmtType
*type
)
1391 static const struct {
1393 enum DevFmtChannels channels
;
1394 enum DevFmtType type
;
1396 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1397 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1398 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1400 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1401 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1402 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1404 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1405 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1406 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1408 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1409 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1410 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1412 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1413 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1414 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1416 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1417 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1418 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1422 for(i
= 0;i
< COUNTOF(list
);i
++)
1424 if(list
[i
].format
== format
)
1426 *chans
= list
[i
].channels
;
1427 *type
= list
[i
].type
;
1435 static ALCboolean
IsValidALCType(ALCenum type
)
1440 case ALC_UNSIGNED_BYTE_SOFT
:
1441 case ALC_SHORT_SOFT
:
1442 case ALC_UNSIGNED_SHORT_SOFT
:
1444 case ALC_UNSIGNED_INT_SOFT
:
1445 case ALC_FLOAT_SOFT
:
1451 static ALCboolean
IsValidALCChannels(ALCenum channels
)
1456 case ALC_STEREO_SOFT
:
1458 case ALC_5POINT1_SOFT
:
1459 case ALC_6POINT1_SOFT
:
1460 case ALC_7POINT1_SOFT
:
1461 case ALC_BFORMAT3D_SOFT
:
1467 static ALCboolean
IsValidAmbiLayout(ALCenum layout
)
1478 static ALCboolean
IsValidAmbiScaling(ALCenum scaling
)
1490 /************************************************
1491 * Miscellaneous ALC helpers
1492 ************************************************/
1494 void ALCdevice_Lock(ALCdevice
*device
)
1496 V0(device
->Backend
,lock
)();
1499 void ALCdevice_Unlock(ALCdevice
*device
)
1501 V0(device
->Backend
,unlock
)();
1505 /* SetDefaultWFXChannelOrder
1507 * Sets the default channel order used by WaveFormatEx.
1509 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1513 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1514 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1516 switch(device
->FmtChans
)
1519 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1522 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1523 device
->RealOut
.ChannelName
[1] = FrontRight
;
1526 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1527 device
->RealOut
.ChannelName
[1] = FrontRight
;
1528 device
->RealOut
.ChannelName
[2] = BackLeft
;
1529 device
->RealOut
.ChannelName
[3] = BackRight
;
1532 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1533 device
->RealOut
.ChannelName
[1] = FrontRight
;
1534 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1535 device
->RealOut
.ChannelName
[3] = LFE
;
1536 device
->RealOut
.ChannelName
[4] = SideLeft
;
1537 device
->RealOut
.ChannelName
[5] = SideRight
;
1540 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1541 device
->RealOut
.ChannelName
[1] = FrontRight
;
1542 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1543 device
->RealOut
.ChannelName
[3] = LFE
;
1544 device
->RealOut
.ChannelName
[4] = BackLeft
;
1545 device
->RealOut
.ChannelName
[5] = BackRight
;
1548 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1549 device
->RealOut
.ChannelName
[1] = FrontRight
;
1550 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1551 device
->RealOut
.ChannelName
[3] = LFE
;
1552 device
->RealOut
.ChannelName
[4] = BackCenter
;
1553 device
->RealOut
.ChannelName
[5] = SideLeft
;
1554 device
->RealOut
.ChannelName
[6] = SideRight
;
1557 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1558 device
->RealOut
.ChannelName
[1] = FrontRight
;
1559 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1560 device
->RealOut
.ChannelName
[3] = LFE
;
1561 device
->RealOut
.ChannelName
[4] = BackLeft
;
1562 device
->RealOut
.ChannelName
[5] = BackRight
;
1563 device
->RealOut
.ChannelName
[6] = SideLeft
;
1564 device
->RealOut
.ChannelName
[7] = SideRight
;
1567 device
->RealOut
.ChannelName
[0] = Aux0
;
1568 if(device
->AmbiOrder
> 0)
1570 device
->RealOut
.ChannelName
[1] = Aux1
;
1571 device
->RealOut
.ChannelName
[2] = Aux2
;
1572 device
->RealOut
.ChannelName
[3] = Aux3
;
1574 if(device
->AmbiOrder
> 1)
1576 device
->RealOut
.ChannelName
[4] = Aux4
;
1577 device
->RealOut
.ChannelName
[5] = Aux5
;
1578 device
->RealOut
.ChannelName
[6] = Aux6
;
1579 device
->RealOut
.ChannelName
[7] = Aux7
;
1580 device
->RealOut
.ChannelName
[8] = Aux8
;
1582 if(device
->AmbiOrder
> 2)
1584 device
->RealOut
.ChannelName
[9] = Aux9
;
1585 device
->RealOut
.ChannelName
[10] = Aux10
;
1586 device
->RealOut
.ChannelName
[11] = Aux11
;
1587 device
->RealOut
.ChannelName
[12] = Aux12
;
1588 device
->RealOut
.ChannelName
[13] = Aux13
;
1589 device
->RealOut
.ChannelName
[14] = Aux14
;
1590 device
->RealOut
.ChannelName
[15] = Aux15
;
1596 /* SetDefaultChannelOrder
1598 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1600 void SetDefaultChannelOrder(ALCdevice
*device
)
1604 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1605 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1607 switch(device
->FmtChans
)
1610 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1611 device
->RealOut
.ChannelName
[1] = FrontRight
;
1612 device
->RealOut
.ChannelName
[2] = BackLeft
;
1613 device
->RealOut
.ChannelName
[3] = BackRight
;
1614 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1615 device
->RealOut
.ChannelName
[5] = LFE
;
1618 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1619 device
->RealOut
.ChannelName
[1] = FrontRight
;
1620 device
->RealOut
.ChannelName
[2] = BackLeft
;
1621 device
->RealOut
.ChannelName
[3] = BackRight
;
1622 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1623 device
->RealOut
.ChannelName
[5] = LFE
;
1624 device
->RealOut
.ChannelName
[6] = SideLeft
;
1625 device
->RealOut
.ChannelName
[7] = SideRight
;
1628 /* Same as WFX order */
1635 SetDefaultWFXChannelOrder(device
);
1640 extern inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
);
1643 /* ALCcontext_DeferUpdates
1645 * Defers/suspends updates for the given context's listener and sources. This
1646 * does *NOT* stop mixing, but rather prevents certain property changes from
1649 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1651 ATOMIC_STORE_SEQ(&context
->DeferUpdates
, AL_TRUE
);
1654 /* ALCcontext_ProcessUpdates
1656 * Resumes update processing after being deferred.
1658 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1660 ReadLock(&context
->PropLock
);
1661 if(ATOMIC_EXCHANGE_SEQ(&context
->DeferUpdates
, AL_FALSE
))
1663 /* Tell the mixer to stop applying updates, then wait for any active
1664 * updating to finish, before providing updates.
1666 ATOMIC_STORE_SEQ(&context
->HoldUpdates
, AL_TRUE
);
1667 while((ATOMIC_LOAD(&context
->UpdateCount
, almemory_order_acquire
)&1) != 0)
1670 UpdateListenerProps(context
);
1671 UpdateAllEffectSlotProps(context
);
1672 UpdateAllSourceProps(context
);
1674 /* Now with all updates declared, let the mixer continue applying them
1675 * so they all happen at once.
1677 ATOMIC_STORE_SEQ(&context
->HoldUpdates
, AL_FALSE
);
1679 ReadUnlock(&context
->PropLock
);
1685 * Stores the latest ALC device error
1687 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1689 WARN("Error generated on device %p, code 0x%04x\n", device
, errorCode
);
1693 /* DebugBreak() will cause an exception if there is no debugger */
1694 if(IsDebuggerPresent())
1696 #elif defined(SIGTRAP)
1702 ATOMIC_STORE_SEQ(&device
->LastError
, errorCode
);
1704 ATOMIC_STORE_SEQ(&LastNullDeviceError
, errorCode
);
1708 struct Compressor
*CreateDeviceLimiter(const ALCdevice
*device
)
1710 return CompressorInit(0.0f
, 0.0f
, AL_FALSE
, AL_TRUE
, 0.0f
, 0.0f
, 0.5f
, 2.0f
,
1711 0.0f
, -3.0f
, 3.0f
, device
->Frequency
);
1716 * Updates the device's base clock time with however many samples have been
1717 * done. This is used so frequency changes on the device don't cause the time
1718 * to jump forward or back. Must not be called while the device is running/
1721 static inline void UpdateClockBase(ALCdevice
*device
)
1723 IncrementRef(&device
->MixCount
);
1724 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1725 device
->SamplesDone
= 0;
1726 IncrementRef(&device
->MixCount
);
1729 /* UpdateDeviceParams
1731 * Updates device parameters according to the attribute list (caller is
1732 * responsible for holding the list lock).
1734 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1736 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1737 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1738 ALCenum gainLimiter
= device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
1739 const ALsizei old_sends
= device
->NumAuxSends
;
1740 ALsizei new_sends
= device
->NumAuxSends
;
1741 enum DevFmtChannels oldChans
;
1742 enum DevFmtType oldType
;
1743 ALboolean update_failed
;
1744 ALCsizei hrtf_id
= -1;
1745 ALCcontext
*context
;
1752 // Check for attributes
1753 if(device
->Type
== Loopback
)
1755 ALCsizei numMono
, numStereo
, numSends
;
1756 ALCenum alayout
= AL_NONE
;
1757 ALCenum ascale
= AL_NONE
;
1758 ALCenum schans
= AL_NONE
;
1759 ALCenum stype
= AL_NONE
;
1760 ALCsizei attrIdx
= 0;
1761 ALCsizei aorder
= 0;
1766 WARN("Missing attributes for loopback device\n");
1767 return ALC_INVALID_VALUE
;
1770 numMono
= device
->NumMonoSources
;
1771 numStereo
= device
->NumStereoSources
;
1772 numSends
= old_sends
;
1774 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1775 while(attrList
[attrIdx
])
1777 switch(attrList
[attrIdx
])
1779 case ALC_FORMAT_CHANNELS_SOFT
:
1780 schans
= attrList
[attrIdx
+ 1];
1781 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT
, schans
);
1782 if(!IsValidALCChannels(schans
))
1783 return ALC_INVALID_VALUE
;
1786 case ALC_FORMAT_TYPE_SOFT
:
1787 stype
= attrList
[attrIdx
+ 1];
1788 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT
, stype
);
1789 if(!IsValidALCType(stype
))
1790 return ALC_INVALID_VALUE
;
1794 freq
= attrList
[attrIdx
+ 1];
1795 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1796 if(freq
< MIN_OUTPUT_RATE
)
1797 return ALC_INVALID_VALUE
;
1800 case ALC_AMBISONIC_LAYOUT_SOFT
:
1801 alayout
= attrList
[attrIdx
+ 1];
1802 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT
, alayout
);
1803 if(!IsValidAmbiLayout(alayout
))
1804 return ALC_INVALID_VALUE
;
1807 case ALC_AMBISONIC_SCALING_SOFT
:
1808 ascale
= attrList
[attrIdx
+ 1];
1809 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT
, ascale
);
1810 if(!IsValidAmbiScaling(ascale
))
1811 return ALC_INVALID_VALUE
;
1814 case ALC_AMBISONIC_ORDER_SOFT
:
1815 aorder
= attrList
[attrIdx
+ 1];
1816 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT
, aorder
);
1817 if(aorder
< 1 || aorder
> MAX_AMBI_ORDER
)
1818 return ALC_INVALID_VALUE
;
1821 case ALC_MONO_SOURCES
:
1822 numMono
= attrList
[attrIdx
+ 1];
1823 TRACE_ATTR(ALC_MONO_SOURCES
, numMono
);
1824 numMono
= maxi(numMono
, 0);
1827 case ALC_STEREO_SOURCES
:
1828 numStereo
= attrList
[attrIdx
+ 1];
1829 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1830 numStereo
= maxi(numStereo
, 0);
1833 case ALC_MAX_AUXILIARY_SENDS
:
1834 numSends
= attrList
[attrIdx
+ 1];
1835 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1836 numSends
= clampi(numSends
, 0, MAX_SENDS
);
1840 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1841 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1842 hrtf_appreq
= Hrtf_Disable
;
1843 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1844 hrtf_appreq
= Hrtf_Enable
;
1846 hrtf_appreq
= Hrtf_Default
;
1849 case ALC_HRTF_ID_SOFT
:
1850 hrtf_id
= attrList
[attrIdx
+ 1];
1851 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1854 case ALC_OUTPUT_LIMITER_SOFT
:
1855 gainLimiter
= attrList
[attrIdx
+ 1];
1856 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT
, gainLimiter
);
1860 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList
[attrIdx
],
1861 attrList
[attrIdx
+ 1], attrList
[attrIdx
+ 1]);
1869 if(!schans
|| !stype
|| !freq
)
1871 WARN("Missing format for loopback device\n");
1872 return ALC_INVALID_VALUE
;
1874 if(schans
== ALC_BFORMAT3D_SOFT
&& (!alayout
|| !ascale
|| !aorder
))
1876 WARN("Missing ambisonic info for loopback device\n");
1877 return ALC_INVALID_VALUE
;
1880 if((device
->Flags
&DEVICE_RUNNING
))
1881 V0(device
->Backend
,stop
)();
1882 device
->Flags
&= ~DEVICE_RUNNING
;
1884 UpdateClockBase(device
);
1886 device
->Frequency
= freq
;
1887 device
->FmtChans
= schans
;
1888 device
->FmtType
= stype
;
1889 if(schans
== ALC_BFORMAT3D_SOFT
)
1891 device
->AmbiOrder
= aorder
;
1892 device
->AmbiLayout
= alayout
;
1893 device
->AmbiScale
= ascale
;
1896 if(numMono
> INT_MAX
-numStereo
)
1897 numMono
= INT_MAX
-numStereo
;
1898 numMono
+= numStereo
;
1899 if(ConfigValueInt(NULL
, NULL
, "sources", &numMono
))
1905 numMono
= maxi(numMono
, 256);
1906 numStereo
= mini(numStereo
, numMono
);
1907 numMono
-= numStereo
;
1908 device
->SourcesMax
= numMono
+ numStereo
;
1910 device
->NumMonoSources
= numMono
;
1911 device
->NumStereoSources
= numStereo
;
1913 if(ConfigValueInt(NULL
, NULL
, "sends", &new_sends
))
1914 new_sends
= mini(numSends
, clampi(new_sends
, 0, MAX_SENDS
));
1916 new_sends
= numSends
;
1918 else if(attrList
&& attrList
[0])
1920 ALCsizei numMono
, numStereo
, numSends
;
1921 ALCsizei attrIdx
= 0;
1924 /* If a context is already running on the device, stop playback so the
1925 * device attributes can be updated. */
1926 if((device
->Flags
&DEVICE_RUNNING
))
1927 V0(device
->Backend
,stop
)();
1928 device
->Flags
&= ~DEVICE_RUNNING
;
1930 UpdateClockBase(device
);
1932 freq
= device
->Frequency
;
1933 numMono
= device
->NumMonoSources
;
1934 numStereo
= device
->NumStereoSources
;
1935 numSends
= old_sends
;
1937 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1938 while(attrList
[attrIdx
])
1940 switch(attrList
[attrIdx
])
1943 freq
= attrList
[attrIdx
+ 1];
1944 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1945 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1948 case ALC_MONO_SOURCES
:
1949 numMono
= attrList
[attrIdx
+ 1];
1950 TRACE_ATTR(ALC_MONO_SOURCES
, numMono
);
1951 numMono
= maxi(numMono
, 0);
1954 case ALC_STEREO_SOURCES
:
1955 numStereo
= attrList
[attrIdx
+ 1];
1956 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1957 numStereo
= maxi(numStereo
, 0);
1960 case ALC_MAX_AUXILIARY_SENDS
:
1961 numSends
= attrList
[attrIdx
+ 1];
1962 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1963 numSends
= clampi(numSends
, 0, MAX_SENDS
);
1967 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1968 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1969 hrtf_appreq
= Hrtf_Disable
;
1970 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1971 hrtf_appreq
= Hrtf_Enable
;
1973 hrtf_appreq
= Hrtf_Default
;
1976 case ALC_HRTF_ID_SOFT
:
1977 hrtf_id
= attrList
[attrIdx
+ 1];
1978 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1981 case ALC_OUTPUT_LIMITER_SOFT
:
1982 gainLimiter
= attrList
[attrIdx
+ 1];
1983 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT
, gainLimiter
);
1987 TRACE("0x%04X = %d (0x%x)\n", attrList
[attrIdx
],
1988 attrList
[attrIdx
+ 1], attrList
[attrIdx
+ 1]);
1996 ConfigValueUInt(alstr_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1997 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1999 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
2001 /* SSE and Neon do best with the update size being a multiple of 4 */
2002 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
2003 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
2005 device
->Frequency
= freq
;
2007 if(numMono
> INT_MAX
-numStereo
)
2008 numMono
= INT_MAX
-numStereo
;
2009 numMono
+= numStereo
;
2010 if(ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "sources", &numMono
))
2016 numMono
= maxi(numMono
, 256);
2017 numStereo
= mini(numStereo
, numMono
);
2018 numMono
-= numStereo
;
2019 device
->SourcesMax
= numMono
+ numStereo
;
2021 device
->NumMonoSources
= numMono
;
2022 device
->NumStereoSources
= numStereo
;
2024 if(ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "sends", &new_sends
))
2025 new_sends
= mini(numSends
, clampi(new_sends
, 0, MAX_SENDS
));
2027 new_sends
= numSends
;
2030 if((device
->Flags
&DEVICE_RUNNING
))
2031 return ALC_NO_ERROR
;
2033 al_free(device
->Uhj_Encoder
);
2034 device
->Uhj_Encoder
= NULL
;
2036 al_free(device
->Bs2b
);
2037 device
->Bs2b
= NULL
;
2039 al_free(device
->ChannelDelay
[0].Buffer
);
2040 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
2042 device
->ChannelDelay
[i
].Length
= 0;
2043 device
->ChannelDelay
[i
].Buffer
= NULL
;
2046 al_free(device
->Dry
.Buffer
);
2047 device
->Dry
.Buffer
= NULL
;
2048 device
->Dry
.NumChannels
= 0;
2049 device
->FOAOut
.Buffer
= NULL
;
2050 device
->FOAOut
.NumChannels
= 0;
2051 device
->RealOut
.Buffer
= NULL
;
2052 device
->RealOut
.NumChannels
= 0;
2054 UpdateClockBase(device
);
2056 device
->DitherSeed
= DITHER_RNG_SEED
;
2058 /*************************************************************************
2059 * Update device format request if HRTF is requested
2061 device
->HrtfStatus
= ALC_HRTF_DISABLED_SOFT
;
2062 if(device
->Type
!= Loopback
)
2065 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
2067 if(strcasecmp(hrtf
, "true") == 0)
2068 hrtf_userreq
= Hrtf_Enable
;
2069 else if(strcasecmp(hrtf
, "false") == 0)
2070 hrtf_userreq
= Hrtf_Disable
;
2071 else if(strcasecmp(hrtf
, "auto") != 0)
2072 ERR("Unexpected hrtf value: %s\n", hrtf
);
2075 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
2077 struct Hrtf
*hrtf
= NULL
;
2078 if(VECTOR_SIZE(device
->HrtfList
) == 0)
2080 VECTOR_DEINIT(device
->HrtfList
);
2081 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
2083 if(VECTOR_SIZE(device
->HrtfList
) > 0)
2085 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->HrtfList
))
2086 hrtf
= GetLoadedHrtf(VECTOR_ELEM(device
->HrtfList
, hrtf_id
).hrtf
);
2088 hrtf
= GetLoadedHrtf(VECTOR_ELEM(device
->HrtfList
, 0).hrtf
);
2093 device
->FmtChans
= DevFmtStereo
;
2094 device
->Frequency
= hrtf
->sampleRate
;
2095 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
2096 if(device
->HrtfHandle
)
2097 Hrtf_DecRef(device
->HrtfHandle
);
2098 device
->HrtfHandle
= hrtf
;
2102 hrtf_userreq
= Hrtf_Default
;
2103 hrtf_appreq
= Hrtf_Disable
;
2104 device
->HrtfStatus
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2109 oldFreq
= device
->Frequency
;
2110 oldChans
= device
->FmtChans
;
2111 oldType
= device
->FmtType
;
2113 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2114 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
2115 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
2116 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
2117 device
->UpdateSize
, device
->NumUpdates
2120 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
2121 return ALC_INVALID_DEVICE
;
2123 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
2125 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
2126 DevFmtChannelsString(device
->FmtChans
));
2127 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
2129 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
2131 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
2132 DevFmtTypeString(device
->FmtType
));
2133 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
2135 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
2137 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
2138 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
2141 if((device
->UpdateSize
&3) != 0)
2143 if((CPUCapFlags
&CPU_CAP_SSE
))
2144 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2145 if((CPUCapFlags
&CPU_CAP_NEON
))
2146 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2149 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2150 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
2151 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
2154 aluInitRenderer(device
, hrtf_id
, hrtf_appreq
, hrtf_userreq
);
2155 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device
->Dry
.NumChannels
,
2156 device
->FOAOut
.NumChannels
, device
->RealOut
.NumChannels
);
2158 /* Allocate extra channels for any post-filter output. */
2159 size
= (device
->Dry
.NumChannels
+ device
->FOAOut
.NumChannels
+
2160 device
->RealOut
.NumChannels
)*sizeof(device
->Dry
.Buffer
[0]);
2162 TRACE("Allocating "SZFMT
" channels, "SZFMT
" bytes\n", size
/sizeof(device
->Dry
.Buffer
[0]), size
);
2163 device
->Dry
.Buffer
= al_calloc(16, size
);
2164 if(!device
->Dry
.Buffer
)
2166 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2167 return ALC_INVALID_DEVICE
;
2170 if(device
->RealOut
.NumChannels
!= 0)
2171 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
+
2172 device
->FOAOut
.NumChannels
;
2175 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2176 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2179 if(device
->FOAOut
.NumChannels
!= 0)
2180 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2183 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
;
2184 device
->FOAOut
.NumChannels
= device
->Dry
.NumChannels
;
2187 device
->NumAuxSends
= new_sends
;
2188 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2189 device
->SourcesMax
, device
->NumMonoSources
, device
->NumStereoSources
,
2190 device
->AuxiliaryEffectSlotMax
, device
->NumAuxSends
);
2192 device
->DitherDepth
= 0.0f
;
2193 if(GetConfigValueBool(alstr_get_cstr(device
->DeviceName
), NULL
, "dither", 1))
2196 ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "dither-depth", &depth
);
2199 switch(device
->FmtType
)
2217 device
->DitherDepth
= (depth
> 0) ? powf(2.0f
, (ALfloat
)(depth
-1)) : 0.0f
;
2219 if(!(device
->DitherDepth
> 0.0f
))
2220 TRACE("Dithering disabled\n");
2222 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device
->DitherDepth
)+1.0f
,
2223 device
->DitherDepth
);
2225 if(ConfigValueBool(alstr_get_cstr(device
->DeviceName
), NULL
, "output-limiter", &val
))
2226 gainLimiter
= val
? ALC_TRUE
: ALC_FALSE
;
2227 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2228 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2231 if(gainLimiter
!= ALC_FALSE
)
2233 if(!device
->Limiter
|| device
->Frequency
!= GetCompressorSampleRate(device
->Limiter
))
2235 al_free(device
->Limiter
);
2236 device
->Limiter
= CreateDeviceLimiter(device
);
2241 al_free(device
->Limiter
);
2242 device
->Limiter
= NULL
;
2244 TRACE("Output limiter %s\n", device
->Limiter
? "enabled" : "disabled");
2246 /* Need to delay returning failure until replacement Send arrays have been
2247 * allocated with the appropriate size.
2249 update_failed
= AL_FALSE
;
2250 SetMixerFPUMode(&oldMode
);
2251 if(device
->DefaultSlot
)
2253 ALeffectslot
*slot
= device
->DefaultSlot
;
2254 ALeffectState
*state
= slot
->Effect
.State
;
2256 state
->OutBuffer
= device
->Dry
.Buffer
;
2257 state
->OutChannels
= device
->Dry
.NumChannels
;
2258 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2259 update_failed
= AL_TRUE
;
2261 UpdateEffectSlotProps(slot
);
2264 context
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
2269 WriteLock(&context
->PropLock
);
2270 LockUIntMapRead(&context
->EffectSlotMap
);
2271 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2273 ALeffectslot
*slot
= context
->EffectSlotMap
.values
[pos
];
2274 ALeffectState
*state
= slot
->Effect
.State
;
2276 state
->OutBuffer
= device
->Dry
.Buffer
;
2277 state
->OutChannels
= device
->Dry
.NumChannels
;
2278 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2279 update_failed
= AL_TRUE
;
2281 UpdateEffectSlotProps(slot
);
2283 UnlockUIntMapRead(&context
->EffectSlotMap
);
2285 LockUIntMapRead(&context
->SourceMap
);
2286 RelimitUIntMapNoLock(&context
->SourceMap
, device
->SourcesMax
);
2287 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2289 ALsource
*source
= context
->SourceMap
.values
[pos
];
2291 if(old_sends
!= device
->NumAuxSends
)
2293 ALvoid
*sends
= al_calloc(16, device
->NumAuxSends
*sizeof(source
->Send
[0]));
2296 memcpy(sends
, source
->Send
,
2297 mini(device
->NumAuxSends
, old_sends
)*sizeof(source
->Send
[0])
2299 for(s
= device
->NumAuxSends
;s
< old_sends
;s
++)
2301 if(source
->Send
[s
].Slot
)
2302 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2303 source
->Send
[s
].Slot
= NULL
;
2305 al_free(source
->Send
);
2306 source
->Send
= sends
;
2307 for(s
= old_sends
;s
< device
->NumAuxSends
;s
++)
2309 source
->Send
[s
].Slot
= NULL
;
2310 source
->Send
[s
].Gain
= 1.0f
;
2311 source
->Send
[s
].GainHF
= 1.0f
;
2312 source
->Send
[s
].HFReference
= LOWPASSFREQREF
;
2313 source
->Send
[s
].GainLF
= 1.0f
;
2314 source
->Send
[s
].LFReference
= HIGHPASSFREQREF
;
2318 ATOMIC_FLAG_CLEAR(&source
->PropsClean
, almemory_order_release
);
2320 AllocateVoices(context
, context
->MaxVoices
, old_sends
);
2321 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2323 ALvoice
*voice
= context
->Voices
[pos
];
2324 struct ALvoiceProps
*props
;
2326 /* Clear any pre-existing voice property structs, in case the
2327 * number of auxiliary sends changed. Active sources will have
2328 * updates respecified in UpdateAllSourceProps.
2330 props
= ATOMIC_EXCHANGE_PTR(&voice
->Update
, NULL
, almemory_order_relaxed
);
2333 props
= ATOMIC_EXCHANGE_PTR(&voice
->FreeList
, NULL
, almemory_order_relaxed
);
2336 struct ALvoiceProps
*next
= ATOMIC_LOAD(&props
->next
, almemory_order_relaxed
);
2341 if(ATOMIC_LOAD(&voice
->Source
, almemory_order_acquire
) == NULL
)
2344 if(device
->AvgSpeakerDist
> 0.0f
)
2346 /* Reinitialize the NFC filters for new parameters. */
2347 ALfloat w1
= SPEEDOFSOUNDMETRESPERSEC
/
2348 (device
->AvgSpeakerDist
* device
->Frequency
);
2349 for(i
= 0;i
< voice
->NumChannels
;i
++)
2351 NfcFilterCreate1(&voice
->Direct
.Params
[i
].NFCtrlFilter
[0], 0.0f
, w1
);
2352 NfcFilterCreate2(&voice
->Direct
.Params
[i
].NFCtrlFilter
[1], 0.0f
, w1
);
2353 NfcFilterCreate3(&voice
->Direct
.Params
[i
].NFCtrlFilter
[2], 0.0f
, w1
);
2357 UnlockUIntMapRead(&context
->SourceMap
);
2359 UpdateListenerProps(context
);
2360 UpdateAllSourceProps(context
);
2361 WriteUnlock(&context
->PropLock
);
2363 context
= context
->next
;
2365 RestoreFPUMode(&oldMode
);
2367 return ALC_INVALID_DEVICE
;
2369 if(!(device
->Flags
&DEVICE_PAUSED
))
2371 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2372 return ALC_INVALID_DEVICE
;
2373 device
->Flags
|= DEVICE_RUNNING
;
2376 return ALC_NO_ERROR
;
2381 * Frees the device structure, and destroys any objects the app failed to
2382 * delete. Called once there's no more references on the device.
2384 static ALCvoid
FreeDevice(ALCdevice
*device
)
2388 TRACE("%p\n", device
);
2390 V0(device
->Backend
,close
)();
2391 DELETE_OBJ(device
->Backend
);
2392 device
->Backend
= NULL
;
2394 almtx_destroy(&device
->BackendLock
);
2396 if(device
->DefaultSlot
)
2398 DeinitEffectSlot(device
->DefaultSlot
);
2399 device
->DefaultSlot
= NULL
;
2402 if(device
->BufferMap
.size
> 0)
2404 WARN("(%p) Deleting %d Buffer%s\n", device
, device
->BufferMap
.size
,
2405 (device
->BufferMap
.size
==1)?"":"s");
2406 ReleaseALBuffers(device
);
2408 ResetUIntMap(&device
->BufferMap
);
2410 if(device
->EffectMap
.size
> 0)
2412 WARN("(%p) Deleting %d Effect%s\n", device
, device
->EffectMap
.size
,
2413 (device
->EffectMap
.size
==1)?"":"s");
2414 ReleaseALEffects(device
);
2416 ResetUIntMap(&device
->EffectMap
);
2418 if(device
->FilterMap
.size
> 0)
2420 WARN("(%p) Deleting %d Filter%s\n", device
, device
->FilterMap
.size
,
2421 (device
->FilterMap
.size
==1)?"":"s");
2422 ReleaseALFilters(device
);
2424 ResetUIntMap(&device
->FilterMap
);
2426 AL_STRING_DEINIT(device
->HrtfName
);
2427 FreeHrtfList(&device
->HrtfList
);
2428 if(device
->HrtfHandle
)
2429 Hrtf_DecRef(device
->HrtfHandle
);
2430 device
->HrtfHandle
= NULL
;
2431 al_free(device
->Hrtf
);
2432 device
->Hrtf
= NULL
;
2434 al_free(device
->Bs2b
);
2435 device
->Bs2b
= NULL
;
2437 al_free(device
->Uhj_Encoder
);
2438 device
->Uhj_Encoder
= NULL
;
2440 bformatdec_free(device
->AmbiDecoder
);
2441 device
->AmbiDecoder
= NULL
;
2443 ambiup_free(device
->AmbiUp
);
2444 device
->AmbiUp
= NULL
;
2446 al_free(device
->Limiter
);
2447 device
->Limiter
= NULL
;
2449 al_free(device
->ChannelDelay
[0].Buffer
);
2450 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
2452 device
->ChannelDelay
[i
].Gain
= 1.0f
;
2453 device
->ChannelDelay
[i
].Length
= 0;
2454 device
->ChannelDelay
[i
].Buffer
= NULL
;
2457 AL_STRING_DEINIT(device
->DeviceName
);
2459 al_free(device
->Dry
.Buffer
);
2460 device
->Dry
.Buffer
= NULL
;
2461 device
->Dry
.NumChannels
= 0;
2462 device
->FOAOut
.Buffer
= NULL
;
2463 device
->FOAOut
.NumChannels
= 0;
2464 device
->RealOut
.Buffer
= NULL
;
2465 device
->RealOut
.NumChannels
= 0;
2471 void ALCdevice_IncRef(ALCdevice
*device
)
2474 ref
= IncrementRef(&device
->ref
);
2475 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2478 void ALCdevice_DecRef(ALCdevice
*device
)
2481 ref
= DecrementRef(&device
->ref
);
2482 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2483 if(ref
== 0) FreeDevice(device
);
2488 * Checks if the device handle is valid, and increments its ref count if so.
2490 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2492 ALCdevice
*tmpDevice
;
2495 tmpDevice
= ATOMIC_LOAD_SEQ(&DeviceList
);
2498 if(tmpDevice
== *device
)
2500 ALCdevice_IncRef(tmpDevice
);
2504 tmpDevice
= tmpDevice
->next
;
2515 * Initializes context fields
2517 static ALvoid
InitContext(ALCcontext
*Context
)
2519 ALlistener
*listener
= Context
->Listener
;
2520 struct ALeffectslotArray
*auxslots
;
2522 //Initialise listener
2523 listener
->Gain
= 1.0f
;
2524 listener
->MetersPerUnit
= 1.0f
;
2525 listener
->Position
[0] = 0.0f
;
2526 listener
->Position
[1] = 0.0f
;
2527 listener
->Position
[2] = 0.0f
;
2528 listener
->Velocity
[0] = 0.0f
;
2529 listener
->Velocity
[1] = 0.0f
;
2530 listener
->Velocity
[2] = 0.0f
;
2531 listener
->Forward
[0] = 0.0f
;
2532 listener
->Forward
[1] = 0.0f
;
2533 listener
->Forward
[2] = -1.0f
;
2534 listener
->Up
[0] = 0.0f
;
2535 listener
->Up
[1] = 1.0f
;
2536 listener
->Up
[2] = 0.0f
;
2538 aluMatrixfSet(&listener
->Params
.Matrix
,
2539 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2540 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2541 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2542 0.0f
, 0.0f
, 0.0f
, 1.0f
2544 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2545 listener
->Params
.Gain
= 1.0f
;
2546 listener
->Params
.MetersPerUnit
= 1.0f
;
2547 listener
->Params
.DopplerFactor
= 1.0f
;
2548 listener
->Params
.SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2550 ATOMIC_INIT(&listener
->Update
, NULL
);
2551 ATOMIC_INIT(&listener
->FreeList
, NULL
);
2554 InitRef(&Context
->UpdateCount
, 0);
2555 ATOMIC_INIT(&Context
->HoldUpdates
, AL_FALSE
);
2556 Context
->GainBoost
= 1.0f
;
2557 RWLockInit(&Context
->PropLock
);
2558 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2559 InitUIntMap(&Context
->SourceMap
, Context
->Device
->SourcesMax
);
2560 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2562 auxslots
= al_calloc(DEF_ALIGN
, sizeof(struct ALeffectslotArray
));
2563 auxslots
->count
= 0;
2564 ATOMIC_INIT(&Context
->ActiveAuxSlots
, auxslots
);
2567 Context
->DistanceModel
= DefaultDistanceModel
;
2568 Context
->SourceDistanceModel
= AL_FALSE
;
2569 Context
->DopplerFactor
= 1.0f
;
2570 Context
->DopplerVelocity
= 1.0f
;
2571 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2572 ATOMIC_INIT(&Context
->DeferUpdates
, AL_FALSE
);
2574 Context
->ExtensionList
= alExtList
;
2580 * Cleans up the context, and destroys any remaining objects the app failed to
2581 * delete. Called once there's no more references on the context.
2583 static void FreeContext(ALCcontext
*context
)
2585 ALlistener
*listener
= context
->Listener
;
2586 struct ALeffectslotArray
*auxslots
;
2587 struct ALlistenerProps
*lprops
;
2591 TRACE("%p\n", context
);
2593 auxslots
= ATOMIC_EXCHANGE_PTR(&context
->ActiveAuxSlots
, NULL
, almemory_order_relaxed
);
2596 if(context
->SourceMap
.size
> 0)
2598 WARN("(%p) Deleting %d Source%s\n", context
, context
->SourceMap
.size
,
2599 (context
->SourceMap
.size
==1)?"":"s");
2600 ReleaseALSources(context
);
2602 ResetUIntMap(&context
->SourceMap
);
2604 if(context
->EffectSlotMap
.size
> 0)
2606 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context
, context
->EffectSlotMap
.size
,
2607 (context
->EffectSlotMap
.size
==1)?"":"s");
2608 ReleaseALAuxiliaryEffectSlots(context
);
2610 ResetUIntMap(&context
->EffectSlotMap
);
2612 for(i
= 0;i
< context
->VoiceCount
;i
++)
2613 DeinitVoice(context
->Voices
[i
]);
2614 al_free(context
->Voices
);
2615 context
->Voices
= NULL
;
2616 context
->VoiceCount
= 0;
2617 context
->MaxVoices
= 0;
2619 if((lprops
=ATOMIC_LOAD(&listener
->Update
, almemory_order_acquire
)) != NULL
)
2621 TRACE("Freed unapplied listener update %p\n", lprops
);
2625 lprops
= ATOMIC_LOAD(&listener
->FreeList
, almemory_order_acquire
);
2628 struct ALlistenerProps
*next
= ATOMIC_LOAD(&lprops
->next
, almemory_order_acquire
);
2633 TRACE("Freed "SZFMT
" listener property object%s\n", count
, (count
==1)?"":"s");
2635 ALCdevice_DecRef(context
->Device
);
2636 context
->Device
= NULL
;
2638 //Invalidate context
2639 memset(context
, 0, sizeof(ALCcontext
));
2645 * Removes the context reference from the given device and removes it from
2646 * being current on the running thread or globally. Returns true if other
2647 * contexts still exist on the device.
2649 static bool ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2651 ALCcontext
*origctx
, *newhead
;
2654 if(altss_get(LocalContext
) == context
)
2656 WARN("%p released while current on thread\n", context
);
2657 altss_set(LocalContext
, NULL
);
2658 ALCcontext_DecRef(context
);
2662 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext
, &origctx
, NULL
))
2663 ALCcontext_DecRef(context
);
2665 ALCdevice_Lock(device
);
2667 newhead
= context
->next
;
2668 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device
->ContextList
, &origctx
, newhead
))
2670 ALCcontext
*volatile*list
= &origctx
->next
;
2673 if(*list
== context
)
2675 *list
= (*list
)->next
;
2678 list
= &(*list
)->next
;
2683 ALCdevice_Unlock(device
);
2685 ALCcontext_DecRef(context
);
2689 void ALCcontext_IncRef(ALCcontext
*context
)
2691 uint ref
= IncrementRef(&context
->ref
);
2692 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2695 void ALCcontext_DecRef(ALCcontext
*context
)
2697 uint ref
= DecrementRef(&context
->ref
);
2698 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2699 if(ref
== 0) FreeContext(context
);
2702 static void ReleaseThreadCtx(void *ptr
)
2704 ALCcontext
*context
= ptr
;
2705 uint ref
= DecrementRef(&context
->ref
);
2706 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2707 ERR("Context %p current for thread being destroyed, possible leak!\n", context
);
2712 * Checks that the given context is valid, and increments its reference count.
2714 static ALCboolean
VerifyContext(ALCcontext
**context
)
2719 dev
= ATOMIC_LOAD_SEQ(&DeviceList
);
2722 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
, almemory_order_acquire
);
2727 ALCcontext_IncRef(ctx
);
2744 * Returns the currently active context for this thread, and adds a reference
2745 * without locking it.
2747 ALCcontext
*GetContextRef(void)
2749 ALCcontext
*context
;
2751 context
= altss_get(LocalContext
);
2753 ALCcontext_IncRef(context
);
2757 context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
2759 ALCcontext_IncRef(context
);
2767 void AllocateVoices(ALCcontext
*context
, ALsizei num_voices
, ALsizei old_sends
)
2769 ALCdevice
*device
= context
->Device
;
2770 ALsizei num_sends
= device
->NumAuxSends
;
2771 struct ALvoiceProps
*props
;
2772 size_t sizeof_props
;
2773 size_t sizeof_voice
;
2779 if(num_voices
== context
->MaxVoices
&& num_sends
== old_sends
)
2782 /* Allocate the voice pointers, voices, and the voices' stored source
2783 * property set (including the dynamically-sized Send[] array) in one
2786 sizeof_voice
= RoundUp(FAM_SIZE(ALvoice
, Send
, num_sends
), 16);
2787 sizeof_props
= RoundUp(FAM_SIZE(struct ALvoiceProps
, Send
, num_sends
), 16);
2788 size
= sizeof(ALvoice
*) + sizeof_voice
+ sizeof_props
;
2790 voices
= al_calloc(16, RoundUp(size
*num_voices
, 16));
2791 /* The voice and property objects are stored interleaved since they're
2794 voice
= (ALvoice
*)((char*)voices
+ RoundUp(num_voices
*sizeof(ALvoice
*), 16));
2795 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2799 const ALsizei v_count
= mini(context
->VoiceCount
, num_voices
);
2800 const ALsizei s_count
= mini(old_sends
, num_sends
);
2802 for(;v
< v_count
;v
++)
2804 ALvoice
*old_voice
= context
->Voices
[v
];
2807 /* Copy the old voice data and source property set to the new
2810 *voice
= *old_voice
;
2811 for(i
= 0;i
< s_count
;i
++)
2812 voice
->Send
[i
] = old_voice
->Send
[i
];
2813 *props
= *(old_voice
->Props
);
2814 for(i
= 0;i
< s_count
;i
++)
2815 props
->Send
[i
] = old_voice
->Props
->Send
[i
];
2817 /* Set this voice's property set pointer and voice reference. */
2818 voice
->Props
= props
;
2821 /* Increment pointers to the next storage space. */
2822 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2823 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2825 /* Deinit any left over voices that weren't copied over to the new
2826 * array. NOTE: If this does anything, v equals num_voices and
2827 * num_voices is less than VoiceCount, so the following loop won't do
2830 for(;v
< context
->VoiceCount
;v
++)
2831 DeinitVoice(context
->Voices
[v
]);
2833 /* Finish setting the voices' property set pointers and references. */
2834 for(;v
< num_voices
;v
++)
2836 ATOMIC_INIT(&voice
->Update
, NULL
);
2837 ATOMIC_INIT(&voice
->FreeList
, NULL
);
2839 voice
->Props
= props
;
2842 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2843 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2846 al_free(context
->Voices
);
2847 context
->Voices
= voices
;
2848 context
->MaxVoices
= num_voices
;
2849 context
->VoiceCount
= mini(context
->VoiceCount
, num_voices
);
2853 /************************************************
2854 * Standard ALC functions
2855 ************************************************/
2859 * Return last ALC generated error code for the given device
2861 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2865 if(VerifyDevice(&device
))
2867 errorCode
= ATOMIC_EXCHANGE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
2868 ALCdevice_DecRef(device
);
2871 errorCode
= ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError
, ALC_NO_ERROR
);
2877 /* alcSuspendContext
2879 * Suspends updates for the given context
2881 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2886 if(!VerifyContext(&context
))
2887 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2890 ALCcontext_DeferUpdates(context
);
2891 ALCcontext_DecRef(context
);
2895 /* alcProcessContext
2897 * Resumes processing updates for the given context
2899 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2904 if(!VerifyContext(&context
))
2905 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2908 ALCcontext_ProcessUpdates(context
);
2909 ALCcontext_DecRef(context
);
2916 * Returns information about the device, and error strings
2918 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2920 const ALCchar
*value
= NULL
;
2928 case ALC_INVALID_ENUM
:
2929 value
= alcErrInvalidEnum
;
2932 case ALC_INVALID_VALUE
:
2933 value
= alcErrInvalidValue
;
2936 case ALC_INVALID_DEVICE
:
2937 value
= alcErrInvalidDevice
;
2940 case ALC_INVALID_CONTEXT
:
2941 value
= alcErrInvalidContext
;
2944 case ALC_OUT_OF_MEMORY
:
2945 value
= alcErrOutOfMemory
;
2948 case ALC_DEVICE_SPECIFIER
:
2949 value
= alcDefaultName
;
2952 case ALC_ALL_DEVICES_SPECIFIER
:
2953 if(VerifyDevice(&Device
))
2955 value
= alstr_get_cstr(Device
->DeviceName
);
2956 ALCdevice_DecRef(Device
);
2960 ProbeAllDevicesList();
2961 value
= alstr_get_cstr(alcAllDevicesList
);
2965 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2966 if(VerifyDevice(&Device
))
2968 value
= alstr_get_cstr(Device
->DeviceName
);
2969 ALCdevice_DecRef(Device
);
2973 ProbeCaptureDeviceList();
2974 value
= alstr_get_cstr(alcCaptureDeviceList
);
2978 /* Default devices are always first in the list */
2979 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2980 value
= alcDefaultName
;
2983 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2984 if(alstr_empty(alcAllDevicesList
))
2985 ProbeAllDevicesList();
2987 VerifyDevice(&Device
);
2989 free(alcDefaultAllDevicesSpecifier
);
2990 alcDefaultAllDevicesSpecifier
= strdup(alstr_get_cstr(alcAllDevicesList
));
2991 if(!alcDefaultAllDevicesSpecifier
)
2992 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2994 value
= alcDefaultAllDevicesSpecifier
;
2995 if(Device
) ALCdevice_DecRef(Device
);
2998 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2999 if(alstr_empty(alcCaptureDeviceList
))
3000 ProbeCaptureDeviceList();
3002 VerifyDevice(&Device
);
3004 free(alcCaptureDefaultDeviceSpecifier
);
3005 alcCaptureDefaultDeviceSpecifier
= strdup(alstr_get_cstr(alcCaptureDeviceList
));
3006 if(!alcCaptureDefaultDeviceSpecifier
)
3007 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
3009 value
= alcCaptureDefaultDeviceSpecifier
;
3010 if(Device
) ALCdevice_DecRef(Device
);
3013 case ALC_EXTENSIONS
:
3014 if(!VerifyDevice(&Device
))
3015 value
= alcNoDeviceExtList
;
3018 value
= alcExtensionList
;
3019 ALCdevice_DecRef(Device
);
3023 case ALC_HRTF_SPECIFIER_SOFT
:
3024 if(!VerifyDevice(&Device
))
3025 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3028 almtx_lock(&Device
->BackendLock
);
3029 value
= (Device
->HrtfHandle
? alstr_get_cstr(Device
->HrtfName
) : "");
3030 almtx_unlock(&Device
->BackendLock
);
3031 ALCdevice_DecRef(Device
);
3036 VerifyDevice(&Device
);
3037 alcSetError(Device
, ALC_INVALID_ENUM
);
3038 if(Device
) ALCdevice_DecRef(Device
);
3046 static inline ALCsizei
NumAttrsForDevice(ALCdevice
*device
)
3048 if(device
->Type
== Loopback
&& device
->FmtChans
== DevFmtAmbi3D
)
3053 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3057 if(size
<= 0 || values
== NULL
)
3059 alcSetError(device
, ALC_INVALID_VALUE
);
3067 case ALC_MAJOR_VERSION
:
3068 values
[0] = alcMajorVersion
;
3070 case ALC_MINOR_VERSION
:
3071 values
[0] = alcMinorVersion
;
3074 case ALC_ATTRIBUTES_SIZE
:
3075 case ALC_ALL_ATTRIBUTES
:
3079 case ALC_MONO_SOURCES
:
3080 case ALC_STEREO_SOURCES
:
3081 case ALC_CAPTURE_SAMPLES
:
3082 case ALC_FORMAT_CHANNELS_SOFT
:
3083 case ALC_FORMAT_TYPE_SOFT
:
3084 case ALC_AMBISONIC_LAYOUT_SOFT
:
3085 case ALC_AMBISONIC_SCALING_SOFT
:
3086 case ALC_AMBISONIC_ORDER_SOFT
:
3087 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3091 alcSetError(NULL
, ALC_INVALID_ENUM
);
3097 if(device
->Type
== Capture
)
3101 case ALC_CAPTURE_SAMPLES
:
3102 almtx_lock(&device
->BackendLock
);
3103 values
[0] = V0(device
->Backend
,availableSamples
)();
3104 almtx_unlock(&device
->BackendLock
);
3108 values
[0] = device
->Connected
;
3112 alcSetError(device
, ALC_INVALID_ENUM
);
3121 case ALC_MAJOR_VERSION
:
3122 values
[0] = alcMajorVersion
;
3125 case ALC_MINOR_VERSION
:
3126 values
[0] = alcMinorVersion
;
3129 case ALC_EFX_MAJOR_VERSION
:
3130 values
[0] = alcEFXMajorVersion
;
3133 case ALC_EFX_MINOR_VERSION
:
3134 values
[0] = alcEFXMinorVersion
;
3137 case ALC_ATTRIBUTES_SIZE
:
3138 values
[0] = NumAttrsForDevice(device
);
3141 case ALC_ALL_ATTRIBUTES
:
3142 if(size
< NumAttrsForDevice(device
))
3144 alcSetError(device
, ALC_INVALID_VALUE
);
3149 almtx_lock(&device
->BackendLock
);
3150 values
[i
++] = ALC_FREQUENCY
;
3151 values
[i
++] = device
->Frequency
;
3153 if(device
->Type
!= Loopback
)
3155 values
[i
++] = ALC_REFRESH
;
3156 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3158 values
[i
++] = ALC_SYNC
;
3159 values
[i
++] = ALC_FALSE
;
3163 if(device
->FmtChans
== DevFmtAmbi3D
)
3165 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3166 values
[i
++] = device
->AmbiLayout
;
3168 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3169 values
[i
++] = device
->AmbiScale
;
3171 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3172 values
[i
++] = device
->AmbiOrder
;
3175 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3176 values
[i
++] = device
->FmtChans
;
3178 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3179 values
[i
++] = device
->FmtType
;
3182 values
[i
++] = ALC_MONO_SOURCES
;
3183 values
[i
++] = device
->NumMonoSources
;
3185 values
[i
++] = ALC_STEREO_SOURCES
;
3186 values
[i
++] = device
->NumStereoSources
;
3188 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3189 values
[i
++] = device
->NumAuxSends
;
3191 values
[i
++] = ALC_HRTF_SOFT
;
3192 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3194 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3195 values
[i
++] = device
->HrtfStatus
;
3197 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3198 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3199 almtx_unlock(&device
->BackendLock
);
3205 values
[0] = device
->Frequency
;
3209 if(device
->Type
== Loopback
)
3211 alcSetError(device
, ALC_INVALID_DEVICE
);
3214 almtx_lock(&device
->BackendLock
);
3215 values
[0] = device
->Frequency
/ device
->UpdateSize
;
3216 almtx_unlock(&device
->BackendLock
);
3220 if(device
->Type
== Loopback
)
3222 alcSetError(device
, ALC_INVALID_DEVICE
);
3225 values
[0] = ALC_FALSE
;
3228 case ALC_FORMAT_CHANNELS_SOFT
:
3229 if(device
->Type
!= Loopback
)
3231 alcSetError(device
, ALC_INVALID_DEVICE
);
3234 values
[0] = device
->FmtChans
;
3237 case ALC_FORMAT_TYPE_SOFT
:
3238 if(device
->Type
!= Loopback
)
3240 alcSetError(device
, ALC_INVALID_DEVICE
);
3243 values
[0] = device
->FmtType
;
3246 case ALC_AMBISONIC_LAYOUT_SOFT
:
3247 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3249 alcSetError(device
, ALC_INVALID_DEVICE
);
3252 values
[0] = device
->AmbiLayout
;
3255 case ALC_AMBISONIC_SCALING_SOFT
:
3256 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3258 alcSetError(device
, ALC_INVALID_DEVICE
);
3261 values
[0] = device
->AmbiScale
;
3264 case ALC_AMBISONIC_ORDER_SOFT
:
3265 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3267 alcSetError(device
, ALC_INVALID_DEVICE
);
3270 values
[0] = device
->AmbiOrder
;
3273 case ALC_MONO_SOURCES
:
3274 values
[0] = device
->NumMonoSources
;
3277 case ALC_STEREO_SOURCES
:
3278 values
[0] = device
->NumStereoSources
;
3281 case ALC_MAX_AUXILIARY_SENDS
:
3282 values
[0] = device
->NumAuxSends
;
3286 values
[0] = device
->Connected
;
3290 values
[0] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3293 case ALC_HRTF_STATUS_SOFT
:
3294 values
[0] = device
->HrtfStatus
;
3297 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
3298 almtx_lock(&device
->BackendLock
);
3299 FreeHrtfList(&device
->HrtfList
);
3300 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
3301 values
[0] = (ALCint
)VECTOR_SIZE(device
->HrtfList
);
3302 almtx_unlock(&device
->BackendLock
);
3305 case ALC_OUTPUT_LIMITER_SOFT
:
3306 values
[0] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3310 alcSetError(device
, ALC_INVALID_ENUM
);
3318 * Returns information about the device and the version of OpenAL
3320 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3322 VerifyDevice(&device
);
3323 if(size
<= 0 || values
== NULL
)
3324 alcSetError(device
, ALC_INVALID_VALUE
);
3326 GetIntegerv(device
, param
, size
, values
);
3327 if(device
) ALCdevice_DecRef(device
);
3330 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
3335 VerifyDevice(&device
);
3336 if(size
<= 0 || values
== NULL
)
3337 alcSetError(device
, ALC_INVALID_VALUE
);
3338 else if(!device
|| device
->Type
== Capture
)
3340 ivals
= malloc(size
* sizeof(ALCint
));
3341 size
= GetIntegerv(device
, pname
, size
, ivals
);
3342 for(i
= 0;i
< size
;i
++)
3343 values
[i
] = ivals
[i
];
3346 else /* render device */
3355 case ALC_ATTRIBUTES_SIZE
:
3356 *values
= NumAttrsForDevice(device
)+4;
3359 case ALC_ALL_ATTRIBUTES
:
3360 if(size
< NumAttrsForDevice(device
)+4)
3361 alcSetError(device
, ALC_INVALID_VALUE
);
3365 almtx_lock(&device
->BackendLock
);
3366 values
[i
++] = ALC_FREQUENCY
;
3367 values
[i
++] = device
->Frequency
;
3369 if(device
->Type
!= Loopback
)
3371 values
[i
++] = ALC_REFRESH
;
3372 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3374 values
[i
++] = ALC_SYNC
;
3375 values
[i
++] = ALC_FALSE
;
3379 if(device
->FmtChans
== DevFmtAmbi3D
)
3381 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3382 values
[i
++] = device
->AmbiLayout
;
3384 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3385 values
[i
++] = device
->AmbiScale
;
3387 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3388 values
[i
++] = device
->AmbiOrder
;
3391 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3392 values
[i
++] = device
->FmtChans
;
3394 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3395 values
[i
++] = device
->FmtType
;
3398 values
[i
++] = ALC_MONO_SOURCES
;
3399 values
[i
++] = device
->NumMonoSources
;
3401 values
[i
++] = ALC_STEREO_SOURCES
;
3402 values
[i
++] = device
->NumStereoSources
;
3404 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3405 values
[i
++] = device
->NumAuxSends
;
3407 values
[i
++] = ALC_HRTF_SOFT
;
3408 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3410 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3411 values
[i
++] = device
->HrtfStatus
;
3413 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3414 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3416 clock
= V0(device
->Backend
,getClockLatency
)();
3417 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3418 values
[i
++] = clock
.ClockTime
;
3420 values
[i
++] = ALC_DEVICE_LATENCY_SOFT
;
3421 values
[i
++] = clock
.Latency
;
3422 almtx_unlock(&device
->BackendLock
);
3428 case ALC_DEVICE_CLOCK_SOFT
:
3429 almtx_lock(&device
->BackendLock
);
3431 while(((refcount
=ReadRef(&device
->MixCount
))&1) != 0)
3433 basecount
= device
->ClockBase
;
3434 samplecount
= device
->SamplesDone
;
3435 } while(refcount
!= ReadRef(&device
->MixCount
));
3436 *values
= basecount
+ (samplecount
*DEVICE_CLOCK_RES
/device
->Frequency
);
3437 almtx_unlock(&device
->BackendLock
);
3440 case ALC_DEVICE_LATENCY_SOFT
:
3441 almtx_lock(&device
->BackendLock
);
3442 clock
= V0(device
->Backend
,getClockLatency
)();
3443 almtx_unlock(&device
->BackendLock
);
3444 *values
= clock
.Latency
;
3447 case ALC_DEVICE_CLOCK_LATENCY_SOFT
:
3449 alcSetError(device
, ALC_INVALID_VALUE
);
3452 almtx_lock(&device
->BackendLock
);
3453 clock
= V0(device
->Backend
,getClockLatency
)();
3454 almtx_unlock(&device
->BackendLock
);
3455 values
[0] = clock
.ClockTime
;
3456 values
[1] = clock
.Latency
;
3461 ivals
= malloc(size
* sizeof(ALCint
));
3462 size
= GetIntegerv(device
, pname
, size
, ivals
);
3463 for(i
= 0;i
< size
;i
++)
3464 values
[i
] = ivals
[i
];
3470 ALCdevice_DecRef(device
);
3474 /* alcIsExtensionPresent
3476 * Determines if there is support for a particular extension
3478 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3480 ALCboolean bResult
= ALC_FALSE
;
3482 VerifyDevice(&device
);
3485 alcSetError(device
, ALC_INVALID_VALUE
);
3488 size_t len
= strlen(extName
);
3489 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3492 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3493 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3498 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3502 } while(isspace(*ptr
));
3507 ALCdevice_DecRef(device
);
3512 /* alcGetProcAddress
3514 * Retrieves the function address for a particular extension function
3516 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3518 ALCvoid
*ptr
= NULL
;
3522 VerifyDevice(&device
);
3523 alcSetError(device
, ALC_INVALID_VALUE
);
3524 if(device
) ALCdevice_DecRef(device
);
3529 for(i
= 0;i
< COUNTOF(alcFunctions
);i
++)
3531 if(strcmp(alcFunctions
[i
].funcName
, funcName
) == 0)
3533 ptr
= alcFunctions
[i
].address
;
3545 * Get the value for a particular ALC enumeration name
3547 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3553 VerifyDevice(&device
);
3554 alcSetError(device
, ALC_INVALID_VALUE
);
3555 if(device
) ALCdevice_DecRef(device
);
3560 for(i
= 0;i
< COUNTOF(alcEnumerations
);i
++)
3562 if(strcmp(alcEnumerations
[i
].enumName
, enumName
) == 0)
3564 val
= alcEnumerations
[i
].value
;
3576 * Create and attach a context to the given device.
3578 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3580 ALCcontext
*ALContext
;
3584 /* Explicitly hold the list lock while taking the BackendLock in case the
3585 * device is asynchronously destropyed, to ensure this new context is
3586 * properly cleaned up after being made.
3589 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3592 alcSetError(device
, ALC_INVALID_DEVICE
);
3593 if(device
) ALCdevice_DecRef(device
);
3596 almtx_lock(&device
->BackendLock
);
3599 ATOMIC_STORE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
3601 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3604 almtx_unlock(&device
->BackendLock
);
3606 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3607 ALCdevice_DecRef(device
);
3611 InitRef(&ALContext
->ref
, 1);
3612 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3614 ALContext
->Voices
= NULL
;
3615 ALContext
->VoiceCount
= 0;
3616 ALContext
->MaxVoices
= 0;
3617 ATOMIC_INIT(&ALContext
->ActiveAuxSlots
, NULL
);
3618 ALContext
->Device
= device
;
3620 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3622 almtx_unlock(&device
->BackendLock
);
3624 al_free(ALContext
->Voices
);
3625 ALContext
->Voices
= NULL
;
3630 alcSetError(device
, err
);
3631 if(err
== ALC_INVALID_DEVICE
)
3633 V0(device
->Backend
,lock
)();
3634 aluHandleDisconnect(device
);
3635 V0(device
->Backend
,unlock
)();
3637 ALCdevice_DecRef(device
);
3640 AllocateVoices(ALContext
, 256, device
->NumAuxSends
);
3642 ALCdevice_IncRef(ALContext
->Device
);
3643 InitContext(ALContext
);
3645 if(ConfigValueFloat(alstr_get_cstr(device
->DeviceName
), NULL
, "volume-adjust", &valf
))
3648 ERR("volume-adjust must be finite: %f\n", valf
);
3651 ALfloat db
= clampf(valf
, -24.0f
, 24.0f
);
3653 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf
, 24.0f
);
3654 ALContext
->GainBoost
= powf(10.0f
, db
/20.0f
);
3655 TRACE("volume-adjust gain: %f\n", ALContext
->GainBoost
);
3658 UpdateListenerProps(ALContext
);
3661 ALCcontext
*head
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
3663 ALContext
->next
= head
;
3664 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device
->ContextList
, &head
,
3667 almtx_unlock(&device
->BackendLock
);
3669 ALCdevice_DecRef(device
);
3671 TRACE("Created context %p\n", ALContext
);
3675 /* alcDestroyContext
3677 * Remove a context from its device
3679 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3684 if(!VerifyContext(&context
))
3687 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3691 Device
= context
->Device
;
3694 almtx_lock(&Device
->BackendLock
);
3695 if(!ReleaseContext(context
, Device
))
3697 V0(Device
->Backend
,stop
)();
3698 Device
->Flags
&= ~DEVICE_RUNNING
;
3700 almtx_unlock(&Device
->BackendLock
);
3704 ALCcontext_DecRef(context
);
3708 /* alcGetCurrentContext
3710 * Returns the currently active context on the calling thread
3712 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3714 ALCcontext
*Context
= altss_get(LocalContext
);
3715 if(!Context
) Context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
3719 /* alcGetThreadContext
3721 * Returns the currently active thread-local context
3723 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3725 return altss_get(LocalContext
);
3729 /* alcMakeContextCurrent
3731 * Makes the given context the active process-wide context, and removes the
3732 * thread-local context for the calling thread.
3734 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3736 /* context must be valid or NULL */
3737 if(context
&& !VerifyContext(&context
))
3739 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3742 /* context's reference count is already incremented */
3743 context
= ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext
, context
);
3744 if(context
) ALCcontext_DecRef(context
);
3746 if((context
=altss_get(LocalContext
)) != NULL
)
3748 altss_set(LocalContext
, NULL
);
3749 ALCcontext_DecRef(context
);
3755 /* alcSetThreadContext
3757 * Makes the given context the active context for the current thread
3759 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3763 /* context must be valid or NULL */
3764 if(context
&& !VerifyContext(&context
))
3766 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3769 /* context's reference count is already incremented */
3770 old
= altss_get(LocalContext
);
3771 altss_set(LocalContext
, context
);
3772 if(old
) ALCcontext_DecRef(old
);
3778 /* alcGetContextsDevice
3780 * Returns the device that a particular context is attached to
3782 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3786 if(!VerifyContext(&Context
))
3788 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3791 Device
= Context
->Device
;
3792 ALCcontext_DecRef(Context
);
3800 * Opens the named device.
3802 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3804 ALCbackendFactory
*factory
;
3812 if(!PlaybackBackend
.name
)
3814 alcSetError(NULL
, ALC_INVALID_VALUE
);
3818 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3820 /* Some old Windows apps hardcode these expecting OpenAL to use a
3821 * specific audio API, even when they're not enumerated. Creative's
3822 * router effectively ignores them too.
3824 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3825 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3830 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3833 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3838 InitRef(&device
->ref
, 1);
3839 device
->Connected
= ALC_TRUE
;
3840 device
->Type
= Playback
;
3841 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3844 device
->Bs2b
= NULL
;
3845 device
->Uhj_Encoder
= NULL
;
3846 device
->Hrtf
= NULL
;
3847 device
->HrtfHandle
= NULL
;
3848 VECTOR_INIT(device
->HrtfList
);
3849 AL_STRING_INIT(device
->HrtfName
);
3850 device
->Render_Mode
= NormalRender
;
3851 AL_STRING_INIT(device
->DeviceName
);
3852 device
->Dry
.Buffer
= NULL
;
3853 device
->Dry
.NumChannels
= 0;
3854 device
->FOAOut
.Buffer
= NULL
;
3855 device
->FOAOut
.NumChannels
= 0;
3856 device
->RealOut
.Buffer
= NULL
;
3857 device
->RealOut
.NumChannels
= 0;
3858 device
->Limiter
= NULL
;
3859 device
->AvgSpeakerDist
= 0.0f
;
3861 ATOMIC_INIT(&device
->ContextList
, NULL
);
3863 device
->ClockBase
= 0;
3864 device
->SamplesDone
= 0;
3866 device
->SourcesMax
= 256;
3867 device
->AuxiliaryEffectSlotMax
= 64;
3868 device
->NumAuxSends
= DEFAULT_SENDS
;
3870 InitUIntMap(&device
->BufferMap
, INT_MAX
);
3871 InitUIntMap(&device
->EffectMap
, INT_MAX
);
3872 InitUIntMap(&device
->FilterMap
, INT_MAX
);
3874 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
3876 device
->ChannelDelay
[i
].Gain
= 1.0f
;
3877 device
->ChannelDelay
[i
].Length
= 0;
3878 device
->ChannelDelay
[i
].Buffer
= NULL
;
3882 device
->FmtChans
= DevFmtChannelsDefault
;
3883 device
->FmtType
= DevFmtTypeDefault
;
3884 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3885 device
->IsHeadphones
= AL_FALSE
;
3886 device
->AmbiLayout
= AmbiLayout_Default
;
3887 device
->AmbiScale
= AmbiNorm_Default
;
3888 device
->NumUpdates
= 3;
3889 device
->UpdateSize
= 1024;
3891 factory
= PlaybackBackend
.getFactory();
3892 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3893 if(!device
->Backend
)
3896 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3901 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3903 static const struct {
3904 const char name
[16];
3905 enum DevFmtChannels chans
;
3908 { "mono", DevFmtMono
, 0 },
3909 { "stereo", DevFmtStereo
, 0 },
3910 { "quad", DevFmtQuad
, 0 },
3911 { "surround51", DevFmtX51
, 0 },
3912 { "surround61", DevFmtX61
, 0 },
3913 { "surround71", DevFmtX71
, 0 },
3914 { "surround51rear", DevFmtX51Rear
, 0 },
3915 { "ambi1", DevFmtAmbi3D
, 1 },
3916 { "ambi2", DevFmtAmbi3D
, 2 },
3917 { "ambi3", DevFmtAmbi3D
, 3 },
3921 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3923 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3925 device
->FmtChans
= chanlist
[i
].chans
;
3926 device
->AmbiOrder
= chanlist
[i
].order
;
3927 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3931 if(i
== COUNTOF(chanlist
))
3932 ERR("Unsupported channels: %s\n", fmt
);
3934 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3936 static const struct {
3937 const char name
[16];
3938 enum DevFmtType type
;
3940 { "int8", DevFmtByte
},
3941 { "uint8", DevFmtUByte
},
3942 { "int16", DevFmtShort
},
3943 { "uint16", DevFmtUShort
},
3944 { "int32", DevFmtInt
},
3945 { "uint32", DevFmtUInt
},
3946 { "float32", DevFmtFloat
},
3950 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3952 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3954 device
->FmtType
= typelist
[i
].type
;
3955 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3959 if(i
== COUNTOF(typelist
))
3960 ERR("Unsupported sample-type: %s\n", fmt
);
3963 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3965 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3966 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3967 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3968 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3971 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3972 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3974 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3975 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3976 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3977 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3979 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
3980 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
3982 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3983 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
3985 if(ConfigValueInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
))
3986 device
->NumAuxSends
= clampi(
3987 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
3990 device
->NumStereoSources
= 1;
3991 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
3993 // Find a playback device to open
3994 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3996 DELETE_OBJ(device
->Backend
);
3998 alcSetError(NULL
, err
);
4001 almtx_init(&device
->BackendLock
, almtx_plain
);
4003 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "ambi-format", &fmt
))
4005 if(strcasecmp(fmt
, "fuma") == 0)
4007 device
->AmbiLayout
= AmbiLayout_FuMa
;
4008 device
->AmbiScale
= AmbiNorm_FuMa
;
4010 else if(strcasecmp(fmt
, "acn+sn3d") == 0)
4012 device
->AmbiLayout
= AmbiLayout_ACN
;
4013 device
->AmbiScale
= AmbiNorm_SN3D
;
4015 else if(strcasecmp(fmt
, "acn+n3d") == 0)
4017 device
->AmbiLayout
= AmbiLayout_ACN
;
4018 device
->AmbiScale
= AmbiNorm_N3D
;
4021 ERR("Unsupported ambi-format: %s\n", fmt
);
4024 device
->Limiter
= CreateDeviceLimiter(device
);
4026 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
4028 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
4029 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
4031 device
->DefaultSlot
= NULL
;
4032 ERR("Failed to initialize the default effect slot\n");
4036 aluInitEffectPanning(device
->DefaultSlot
);
4037 if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
4039 DeinitEffectSlot(device
->DefaultSlot
);
4040 device
->DefaultSlot
= NULL
;
4041 ERR("Failed to initialize the default effect\n");
4047 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4049 device
->next
= head
;
4050 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4053 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4059 * Closes the given device.
4061 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
4063 ALCdevice
*iter
, *origdev
;
4067 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4071 } while((iter
=iter
->next
) != NULL
);
4072 if(!iter
|| iter
->Type
== Capture
)
4074 alcSetError(iter
, ALC_INVALID_DEVICE
);
4078 almtx_lock(&device
->BackendLock
);
4081 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4083 ALCdevice
*volatile*list
= &origdev
->next
;
4088 *list
= (*list
)->next
;
4091 list
= &(*list
)->next
;
4096 ctx
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
4099 ALCcontext
*next
= ctx
->next
;
4100 WARN("Releasing context %p\n", ctx
);
4101 ReleaseContext(ctx
, device
);
4104 if((device
->Flags
&DEVICE_RUNNING
))
4105 V0(device
->Backend
,stop
)();
4106 device
->Flags
&= ~DEVICE_RUNNING
;
4107 almtx_unlock(&device
->BackendLock
);
4109 ALCdevice_DecRef(device
);
4115 /************************************************
4116 * ALC capture functions
4117 ************************************************/
4118 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
4120 ALCbackendFactory
*factory
;
4121 ALCdevice
*device
= NULL
;
4127 if(!CaptureBackend
.name
)
4129 alcSetError(NULL
, ALC_INVALID_VALUE
);
4135 alcSetError(NULL
, ALC_INVALID_VALUE
);
4139 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
4142 device
= al_calloc(16, sizeof(ALCdevice
));
4145 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4150 InitRef(&device
->ref
, 1);
4151 device
->Connected
= ALC_TRUE
;
4152 device
->Type
= Capture
;
4154 device
->Hrtf
= NULL
;
4155 device
->HrtfHandle
= NULL
;
4156 VECTOR_INIT(device
->HrtfList
);
4157 AL_STRING_INIT(device
->HrtfName
);
4159 AL_STRING_INIT(device
->DeviceName
);
4160 device
->Dry
.Buffer
= NULL
;
4161 device
->Dry
.NumChannels
= 0;
4162 device
->FOAOut
.Buffer
= NULL
;
4163 device
->FOAOut
.NumChannels
= 0;
4164 device
->RealOut
.Buffer
= NULL
;
4165 device
->RealOut
.NumChannels
= 0;
4167 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4168 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4169 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4171 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4173 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4174 device
->ChannelDelay
[i
].Length
= 0;
4175 device
->ChannelDelay
[i
].Buffer
= NULL
;
4178 factory
= CaptureBackend
.getFactory();
4179 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
4180 if(!device
->Backend
)
4183 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4187 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4188 device
->Frequency
= frequency
;
4190 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
4191 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
4194 alcSetError(NULL
, ALC_INVALID_ENUM
);
4197 device
->IsHeadphones
= AL_FALSE
;
4198 device
->AmbiOrder
= 0;
4199 device
->AmbiLayout
= AmbiLayout_Default
;
4200 device
->AmbiScale
= AmbiNorm_Default
;
4202 device
->UpdateSize
= samples
;
4203 device
->NumUpdates
= 1;
4205 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4206 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
4207 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
4209 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4212 alcSetError(NULL
, err
);
4215 almtx_init(&device
->BackendLock
, almtx_plain
);
4218 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4220 device
->next
= head
;
4221 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4224 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4228 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
4230 ALCdevice
*iter
, *origdev
;
4233 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4237 } while((iter
=iter
->next
) != NULL
);
4238 if(!iter
|| iter
->Type
!= Capture
)
4240 alcSetError(iter
, ALC_INVALID_DEVICE
);
4246 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4248 ALCdevice
*volatile*list
= &origdev
->next
;
4253 *list
= (*list
)->next
;
4256 list
= &(*list
)->next
;
4261 ALCdevice_DecRef(device
);
4266 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
4268 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4269 alcSetError(device
, ALC_INVALID_DEVICE
);
4272 almtx_lock(&device
->BackendLock
);
4273 if(!device
->Connected
)
4274 alcSetError(device
, ALC_INVALID_DEVICE
);
4275 else if(!(device
->Flags
&DEVICE_RUNNING
))
4277 if(V0(device
->Backend
,start
)())
4278 device
->Flags
|= DEVICE_RUNNING
;
4281 aluHandleDisconnect(device
);
4282 alcSetError(device
, ALC_INVALID_DEVICE
);
4285 almtx_unlock(&device
->BackendLock
);
4288 if(device
) ALCdevice_DecRef(device
);
4291 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
4293 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4294 alcSetError(device
, ALC_INVALID_DEVICE
);
4297 almtx_lock(&device
->BackendLock
);
4298 if((device
->Flags
&DEVICE_RUNNING
))
4299 V0(device
->Backend
,stop
)();
4300 device
->Flags
&= ~DEVICE_RUNNING
;
4301 almtx_unlock(&device
->BackendLock
);
4304 if(device
) ALCdevice_DecRef(device
);
4307 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4309 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4310 alcSetError(device
, ALC_INVALID_DEVICE
);
4313 ALCenum err
= ALC_INVALID_VALUE
;
4315 almtx_lock(&device
->BackendLock
);
4316 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
4317 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
4318 almtx_unlock(&device
->BackendLock
);
4320 if(err
!= ALC_NO_ERROR
)
4321 alcSetError(device
, err
);
4323 if(device
) ALCdevice_DecRef(device
);
4327 /************************************************
4328 * ALC loopback functions
4329 ************************************************/
4331 /* alcLoopbackOpenDeviceSOFT
4333 * Open a loopback device, for manual rendering.
4335 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
4337 ALCbackendFactory
*factory
;
4343 /* Make sure the device name, if specified, is us. */
4344 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
4346 alcSetError(NULL
, ALC_INVALID_VALUE
);
4350 device
= al_calloc(16, sizeof(ALCdevice
));
4353 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4358 InitRef(&device
->ref
, 1);
4359 device
->Connected
= ALC_TRUE
;
4360 device
->Type
= Loopback
;
4361 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
4364 device
->Hrtf
= NULL
;
4365 device
->HrtfHandle
= NULL
;
4366 VECTOR_INIT(device
->HrtfList
);
4367 AL_STRING_INIT(device
->HrtfName
);
4368 device
->Bs2b
= NULL
;
4369 device
->Uhj_Encoder
= NULL
;
4370 device
->Render_Mode
= NormalRender
;
4371 AL_STRING_INIT(device
->DeviceName
);
4372 device
->Dry
.Buffer
= NULL
;
4373 device
->Dry
.NumChannels
= 0;
4374 device
->FOAOut
.Buffer
= NULL
;
4375 device
->FOAOut
.NumChannels
= 0;
4376 device
->RealOut
.Buffer
= NULL
;
4377 device
->RealOut
.NumChannels
= 0;
4378 device
->Limiter
= NULL
;
4379 device
->AvgSpeakerDist
= 0.0f
;
4381 ATOMIC_INIT(&device
->ContextList
, NULL
);
4383 device
->ClockBase
= 0;
4384 device
->SamplesDone
= 0;
4386 device
->SourcesMax
= 256;
4387 device
->AuxiliaryEffectSlotMax
= 64;
4388 device
->NumAuxSends
= DEFAULT_SENDS
;
4390 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4391 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4392 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4394 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4396 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4397 device
->ChannelDelay
[i
].Length
= 0;
4398 device
->ChannelDelay
[i
].Buffer
= NULL
;
4401 factory
= ALCloopbackFactory_getFactory();
4402 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
4403 if(!device
->Backend
)
4406 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4409 almtx_init(&device
->BackendLock
, almtx_plain
);
4412 device
->NumUpdates
= 0;
4413 device
->UpdateSize
= 0;
4415 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
4416 device
->FmtChans
= DevFmtChannelsDefault
;
4417 device
->FmtType
= DevFmtTypeDefault
;
4418 device
->IsHeadphones
= AL_FALSE
;
4419 device
->AmbiLayout
= AmbiLayout_Default
;
4420 device
->AmbiScale
= AmbiNorm_Default
;
4422 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
4423 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4425 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4426 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4428 if(ConfigValueInt(NULL
, NULL
, "sends", &device
->NumAuxSends
))
4429 device
->NumAuxSends
= clampi(
4430 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4433 device
->NumStereoSources
= 1;
4434 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4436 // Open the "backend"
4437 V(device
->Backend
,open
)("Loopback");
4439 device
->Limiter
= CreateDeviceLimiter(device
);
4442 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4444 device
->next
= head
;
4445 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4448 TRACE("Created device %p\n", device
);
4452 /* alcIsRenderFormatSupportedSOFT
4454 * Determines if the loopback device supports the given format for rendering.
4456 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
4458 ALCboolean ret
= ALC_FALSE
;
4460 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4461 alcSetError(device
, ALC_INVALID_DEVICE
);
4463 alcSetError(device
, ALC_INVALID_VALUE
);
4466 if(IsValidALCType(type
) && IsValidALCChannels(channels
) && freq
>= MIN_OUTPUT_RATE
)
4469 if(device
) ALCdevice_DecRef(device
);
4474 /* alcRenderSamplesSOFT
4476 * Renders some samples into a buffer, using the format last set by the
4477 * attributes given to alcCreateContext.
4479 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4481 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4482 alcSetError(device
, ALC_INVALID_DEVICE
);
4483 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
4484 alcSetError(device
, ALC_INVALID_VALUE
);
4487 V0(device
->Backend
,lock
)();
4488 aluMixData(device
, buffer
, samples
);
4489 V0(device
->Backend
,unlock
)();
4491 if(device
) ALCdevice_DecRef(device
);
4495 /************************************************
4496 * ALC loopback2 functions
4497 ************************************************/
4499 ALC_API ALCboolean ALC_APIENTRY
alcIsAmbisonicFormatSupportedSOFT(ALCdevice
*device
, ALCenum layout
, ALCenum scaling
, ALsizei order
)
4501 ALCboolean ret
= ALC_FALSE
;
4503 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4504 alcSetError(device
, ALC_INVALID_DEVICE
);
4506 alcSetError(device
, ALC_INVALID_VALUE
);
4509 if(IsValidAmbiLayout(layout
) && IsValidAmbiScaling(scaling
) && order
<= MAX_AMBI_ORDER
)
4512 if(device
) ALCdevice_DecRef(device
);
4517 /************************************************
4518 * ALC DSP pause/resume functions
4519 ************************************************/
4521 /* alcDevicePauseSOFT
4523 * Pause the DSP to stop audio processing.
4525 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
4527 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4528 alcSetError(device
, ALC_INVALID_DEVICE
);
4531 almtx_lock(&device
->BackendLock
);
4532 if((device
->Flags
&DEVICE_RUNNING
))
4533 V0(device
->Backend
,stop
)();
4534 device
->Flags
&= ~DEVICE_RUNNING
;
4535 device
->Flags
|= DEVICE_PAUSED
;
4536 almtx_unlock(&device
->BackendLock
);
4538 if(device
) ALCdevice_DecRef(device
);
4541 /* alcDeviceResumeSOFT
4543 * Resume the DSP to restart audio processing.
4545 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
4547 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4548 alcSetError(device
, ALC_INVALID_DEVICE
);
4551 almtx_lock(&device
->BackendLock
);
4552 if((device
->Flags
&DEVICE_PAUSED
))
4554 device
->Flags
&= ~DEVICE_PAUSED
;
4555 if(ATOMIC_LOAD_SEQ(&device
->ContextList
) != NULL
)
4557 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4558 device
->Flags
|= DEVICE_RUNNING
;
4561 alcSetError(device
, ALC_INVALID_DEVICE
);
4562 V0(device
->Backend
,lock
)();
4563 aluHandleDisconnect(device
);
4564 V0(device
->Backend
,unlock
)();
4568 almtx_unlock(&device
->BackendLock
);
4570 if(device
) ALCdevice_DecRef(device
);
4574 /************************************************
4575 * ALC HRTF functions
4576 ************************************************/
4578 /* alcGetStringiSOFT
4580 * Gets a string parameter at the given index.
4582 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4584 const ALCchar
*str
= NULL
;
4586 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4587 alcSetError(device
, ALC_INVALID_DEVICE
);
4588 else switch(paramName
)
4590 case ALC_HRTF_SPECIFIER_SOFT
:
4591 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->HrtfList
))
4592 str
= alstr_get_cstr(VECTOR_ELEM(device
->HrtfList
, index
).name
);
4594 alcSetError(device
, ALC_INVALID_VALUE
);
4598 alcSetError(device
, ALC_INVALID_ENUM
);
4601 if(device
) ALCdevice_DecRef(device
);
4606 /* alcResetDeviceSOFT
4608 * Resets the given device output, using the specified attribute list.
4610 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4615 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4618 alcSetError(device
, ALC_INVALID_DEVICE
);
4619 if(device
) ALCdevice_DecRef(device
);
4622 almtx_lock(&device
->BackendLock
);
4625 err
= UpdateDeviceParams(device
, attribs
);
4626 almtx_unlock(&device
->BackendLock
);
4628 if(err
!= ALC_NO_ERROR
)
4630 alcSetError(device
, err
);
4631 if(err
== ALC_INVALID_DEVICE
)
4633 V0(device
->Backend
,lock
)();
4634 aluHandleDisconnect(device
);
4635 V0(device
->Backend
,unlock
)();
4637 ALCdevice_DecRef(device
);
4640 ALCdevice_DecRef(device
);