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
;
1219 /************************************************
1220 * Library deinitialization
1221 ************************************************/
1222 static void alc_cleanup(void)
1226 AL_STRING_DEINIT(alcAllDevicesList
);
1227 AL_STRING_DEINIT(alcCaptureDeviceList
);
1229 free(alcDefaultAllDevicesSpecifier
);
1230 alcDefaultAllDevicesSpecifier
= NULL
;
1231 free(alcCaptureDefaultDeviceSpecifier
);
1232 alcCaptureDefaultDeviceSpecifier
= NULL
;
1234 if((dev
=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList
, NULL
)) != NULL
)
1239 } while((dev
=dev
->next
) != NULL
);
1240 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1243 DeinitEffectFactoryMap();
1246 static void alc_deinit_safe(void)
1254 almtx_destroy(&ListLock
);
1255 altss_delete(LocalContext
);
1257 if(LogFile
!= stderr
)
1262 static void alc_deinit(void)
1268 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1269 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1271 for(i
= 0;i
< BackendListSize
;i
++)
1273 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1274 V0(factory
,deinit
)();
1277 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1278 V0(factory
,deinit
)();
1285 /************************************************
1286 * Device enumeration
1287 ************************************************/
1288 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1290 ALCbackendFactory
*factory
;
1297 factory
= backendinfo
->getFactory();
1298 V(factory
,probe
)(type
);
1302 static void ProbeAllDevicesList(void)
1303 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1304 static void ProbeCaptureDeviceList(void)
1305 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1307 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1309 size_t len
= strlen(name
);
1311 alstr_append_range(devnames
, name
, name
+len
+1);
1313 void AppendAllDevicesList(const ALCchar
*name
)
1314 { AppendDevice(name
, &alcAllDevicesList
); }
1315 void AppendCaptureDeviceList(const ALCchar
*name
)
1316 { AppendDevice(name
, &alcCaptureDeviceList
); }
1319 /************************************************
1320 * Device format information
1321 ************************************************/
1322 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1326 case DevFmtByte
: return "Signed Byte";
1327 case DevFmtUByte
: return "Unsigned Byte";
1328 case DevFmtShort
: return "Signed Short";
1329 case DevFmtUShort
: return "Unsigned Short";
1330 case DevFmtInt
: return "Signed Int";
1331 case DevFmtUInt
: return "Unsigned Int";
1332 case DevFmtFloat
: return "Float";
1334 return "(unknown type)";
1336 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1340 case DevFmtMono
: return "Mono";
1341 case DevFmtStereo
: return "Stereo";
1342 case DevFmtQuad
: return "Quadraphonic";
1343 case DevFmtX51
: return "5.1 Surround";
1344 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1345 case DevFmtX61
: return "6.1 Surround";
1346 case DevFmtX71
: return "7.1 Surround";
1347 case DevFmtAmbi3D
: return "Ambisonic 3D";
1349 return "(unknown channels)";
1352 extern inline ALsizei
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
, ALsizei ambiorder
);
1353 ALsizei
BytesFromDevFmt(enum DevFmtType type
)
1357 case DevFmtByte
: return sizeof(ALbyte
);
1358 case DevFmtUByte
: return sizeof(ALubyte
);
1359 case DevFmtShort
: return sizeof(ALshort
);
1360 case DevFmtUShort
: return sizeof(ALushort
);
1361 case DevFmtInt
: return sizeof(ALint
);
1362 case DevFmtUInt
: return sizeof(ALuint
);
1363 case DevFmtFloat
: return sizeof(ALfloat
);
1367 ALsizei
ChannelsFromDevFmt(enum DevFmtChannels chans
, ALsizei ambiorder
)
1371 case DevFmtMono
: return 1;
1372 case DevFmtStereo
: return 2;
1373 case DevFmtQuad
: return 4;
1374 case DevFmtX51
: return 6;
1375 case DevFmtX51Rear
: return 6;
1376 case DevFmtX61
: return 7;
1377 case DevFmtX71
: return 8;
1378 case DevFmtAmbi3D
: return (ambiorder
>= 3) ? 16 :
1379 (ambiorder
== 2) ? 9 :
1380 (ambiorder
== 1) ? 4 : 1;
1385 static ALboolean
DecomposeDevFormat(ALenum format
, enum DevFmtChannels
*chans
,
1386 enum DevFmtType
*type
)
1388 static const struct {
1390 enum DevFmtChannels channels
;
1391 enum DevFmtType type
;
1393 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1394 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1395 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1397 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1398 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1399 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1401 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1402 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1403 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1405 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1406 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1407 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1409 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1410 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1411 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1413 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1414 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1415 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1419 for(i
= 0;i
< COUNTOF(list
);i
++)
1421 if(list
[i
].format
== format
)
1423 *chans
= list
[i
].channels
;
1424 *type
= list
[i
].type
;
1432 static ALCboolean
IsValidALCType(ALCenum type
)
1437 case ALC_UNSIGNED_BYTE_SOFT
:
1438 case ALC_SHORT_SOFT
:
1439 case ALC_UNSIGNED_SHORT_SOFT
:
1441 case ALC_UNSIGNED_INT_SOFT
:
1442 case ALC_FLOAT_SOFT
:
1448 static ALCboolean
IsValidALCChannels(ALCenum channels
)
1453 case ALC_STEREO_SOFT
:
1455 case ALC_5POINT1_SOFT
:
1456 case ALC_6POINT1_SOFT
:
1457 case ALC_7POINT1_SOFT
:
1458 case ALC_BFORMAT3D_SOFT
:
1464 static ALCboolean
IsValidAmbiLayout(ALCenum layout
)
1475 static ALCboolean
IsValidAmbiScaling(ALCenum scaling
)
1487 /************************************************
1488 * Miscellaneous ALC helpers
1489 ************************************************/
1491 void ALCdevice_Lock(ALCdevice
*device
)
1493 V0(device
->Backend
,lock
)();
1496 void ALCdevice_Unlock(ALCdevice
*device
)
1498 V0(device
->Backend
,unlock
)();
1502 /* SetDefaultWFXChannelOrder
1504 * Sets the default channel order used by WaveFormatEx.
1506 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1510 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1511 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1513 switch(device
->FmtChans
)
1516 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1519 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1520 device
->RealOut
.ChannelName
[1] = FrontRight
;
1523 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1524 device
->RealOut
.ChannelName
[1] = FrontRight
;
1525 device
->RealOut
.ChannelName
[2] = BackLeft
;
1526 device
->RealOut
.ChannelName
[3] = BackRight
;
1529 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1530 device
->RealOut
.ChannelName
[1] = FrontRight
;
1531 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1532 device
->RealOut
.ChannelName
[3] = LFE
;
1533 device
->RealOut
.ChannelName
[4] = SideLeft
;
1534 device
->RealOut
.ChannelName
[5] = SideRight
;
1537 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1538 device
->RealOut
.ChannelName
[1] = FrontRight
;
1539 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1540 device
->RealOut
.ChannelName
[3] = LFE
;
1541 device
->RealOut
.ChannelName
[4] = BackLeft
;
1542 device
->RealOut
.ChannelName
[5] = BackRight
;
1545 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1546 device
->RealOut
.ChannelName
[1] = FrontRight
;
1547 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1548 device
->RealOut
.ChannelName
[3] = LFE
;
1549 device
->RealOut
.ChannelName
[4] = BackCenter
;
1550 device
->RealOut
.ChannelName
[5] = SideLeft
;
1551 device
->RealOut
.ChannelName
[6] = SideRight
;
1554 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1555 device
->RealOut
.ChannelName
[1] = FrontRight
;
1556 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1557 device
->RealOut
.ChannelName
[3] = LFE
;
1558 device
->RealOut
.ChannelName
[4] = BackLeft
;
1559 device
->RealOut
.ChannelName
[5] = BackRight
;
1560 device
->RealOut
.ChannelName
[6] = SideLeft
;
1561 device
->RealOut
.ChannelName
[7] = SideRight
;
1564 device
->RealOut
.ChannelName
[0] = Aux0
;
1565 if(device
->AmbiOrder
> 0)
1567 device
->RealOut
.ChannelName
[1] = Aux1
;
1568 device
->RealOut
.ChannelName
[2] = Aux2
;
1569 device
->RealOut
.ChannelName
[3] = Aux3
;
1571 if(device
->AmbiOrder
> 1)
1573 device
->RealOut
.ChannelName
[4] = Aux4
;
1574 device
->RealOut
.ChannelName
[5] = Aux5
;
1575 device
->RealOut
.ChannelName
[6] = Aux6
;
1576 device
->RealOut
.ChannelName
[7] = Aux7
;
1577 device
->RealOut
.ChannelName
[8] = Aux8
;
1579 if(device
->AmbiOrder
> 2)
1581 device
->RealOut
.ChannelName
[9] = Aux9
;
1582 device
->RealOut
.ChannelName
[10] = Aux10
;
1583 device
->RealOut
.ChannelName
[11] = Aux11
;
1584 device
->RealOut
.ChannelName
[12] = Aux12
;
1585 device
->RealOut
.ChannelName
[13] = Aux13
;
1586 device
->RealOut
.ChannelName
[14] = Aux14
;
1587 device
->RealOut
.ChannelName
[15] = Aux15
;
1593 /* SetDefaultChannelOrder
1595 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1597 void SetDefaultChannelOrder(ALCdevice
*device
)
1601 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1602 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1604 switch(device
->FmtChans
)
1607 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1608 device
->RealOut
.ChannelName
[1] = FrontRight
;
1609 device
->RealOut
.ChannelName
[2] = BackLeft
;
1610 device
->RealOut
.ChannelName
[3] = BackRight
;
1611 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1612 device
->RealOut
.ChannelName
[5] = LFE
;
1615 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1616 device
->RealOut
.ChannelName
[1] = FrontRight
;
1617 device
->RealOut
.ChannelName
[2] = BackLeft
;
1618 device
->RealOut
.ChannelName
[3] = BackRight
;
1619 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1620 device
->RealOut
.ChannelName
[5] = LFE
;
1621 device
->RealOut
.ChannelName
[6] = SideLeft
;
1622 device
->RealOut
.ChannelName
[7] = SideRight
;
1625 /* Same as WFX order */
1632 SetDefaultWFXChannelOrder(device
);
1637 extern inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
);
1640 /* ALCcontext_DeferUpdates
1642 * Defers/suspends updates for the given context's listener and sources. This
1643 * does *NOT* stop mixing, but rather prevents certain property changes from
1646 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1648 ATOMIC_STORE_SEQ(&context
->DeferUpdates
, AL_TRUE
);
1651 /* ALCcontext_ProcessUpdates
1653 * Resumes update processing after being deferred.
1655 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1657 ReadLock(&context
->PropLock
);
1658 if(ATOMIC_EXCHANGE_SEQ(&context
->DeferUpdates
, AL_FALSE
))
1660 /* Tell the mixer to stop applying updates, then wait for any active
1661 * updating to finish, before providing updates.
1663 ATOMIC_STORE_SEQ(&context
->HoldUpdates
, AL_TRUE
);
1664 while((ATOMIC_LOAD(&context
->UpdateCount
, almemory_order_acquire
)&1) != 0)
1667 UpdateListenerProps(context
);
1668 UpdateAllEffectSlotProps(context
);
1669 UpdateAllSourceProps(context
);
1671 /* Now with all updates declared, let the mixer continue applying them
1672 * so they all happen at once.
1674 ATOMIC_STORE_SEQ(&context
->HoldUpdates
, AL_FALSE
);
1676 ReadUnlock(&context
->PropLock
);
1682 * Stores the latest ALC device error
1684 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1686 WARN("Error generated on device %p, code 0x%04x\n", device
, errorCode
);
1690 /* DebugBreak() will cause an exception if there is no debugger */
1691 if(IsDebuggerPresent())
1693 #elif defined(SIGTRAP)
1699 ATOMIC_STORE_SEQ(&device
->LastError
, errorCode
);
1701 ATOMIC_STORE_SEQ(&LastNullDeviceError
, errorCode
);
1705 struct Compressor
*CreateDeviceLimiter(const ALCdevice
*device
)
1707 return CompressorInit(0.0f
, 0.0f
, AL_FALSE
, AL_TRUE
, 0.0f
, 0.0f
, 0.5f
, 2.0f
,
1708 0.0f
, -3.0f
, 3.0f
, device
->Frequency
);
1713 * Updates the device's base clock time with however many samples have been
1714 * done. This is used so frequency changes on the device don't cause the time
1715 * to jump forward or back. Must not be called while the device is running/
1718 static inline void UpdateClockBase(ALCdevice
*device
)
1720 IncrementRef(&device
->MixCount
);
1721 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1722 device
->SamplesDone
= 0;
1723 IncrementRef(&device
->MixCount
);
1726 /* UpdateDeviceParams
1728 * Updates device parameters according to the attribute list (caller is
1729 * responsible for holding the list lock).
1731 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1733 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1734 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1735 ALCenum gainLimiter
= device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
1736 const ALsizei old_sends
= device
->NumAuxSends
;
1737 ALsizei new_sends
= device
->NumAuxSends
;
1738 enum DevFmtChannels oldChans
;
1739 enum DevFmtType oldType
;
1740 ALboolean update_failed
;
1741 ALCsizei hrtf_id
= -1;
1742 ALCcontext
*context
;
1749 // Check for attributes
1750 if(device
->Type
== Loopback
)
1752 ALCsizei numMono
, numStereo
, numSends
;
1753 ALCenum alayout
= AL_NONE
;
1754 ALCenum ascale
= AL_NONE
;
1755 ALCenum schans
= AL_NONE
;
1756 ALCenum stype
= AL_NONE
;
1757 ALCsizei attrIdx
= 0;
1758 ALCsizei aorder
= 0;
1763 WARN("Missing attributes for loopback device\n");
1764 return ALC_INVALID_VALUE
;
1767 numMono
= device
->NumMonoSources
;
1768 numStereo
= device
->NumStereoSources
;
1769 numSends
= old_sends
;
1771 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1772 while(attrList
[attrIdx
])
1774 switch(attrList
[attrIdx
])
1776 case ALC_FORMAT_CHANNELS_SOFT
:
1777 schans
= attrList
[attrIdx
+ 1];
1778 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT
, schans
);
1779 if(!IsValidALCChannels(schans
))
1780 return ALC_INVALID_VALUE
;
1783 case ALC_FORMAT_TYPE_SOFT
:
1784 stype
= attrList
[attrIdx
+ 1];
1785 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT
, stype
);
1786 if(!IsValidALCType(stype
))
1787 return ALC_INVALID_VALUE
;
1791 freq
= attrList
[attrIdx
+ 1];
1792 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1793 if(freq
< MIN_OUTPUT_RATE
)
1794 return ALC_INVALID_VALUE
;
1797 case ALC_AMBISONIC_LAYOUT_SOFT
:
1798 alayout
= attrList
[attrIdx
+ 1];
1799 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT
, alayout
);
1800 if(!IsValidAmbiLayout(alayout
))
1801 return ALC_INVALID_VALUE
;
1804 case ALC_AMBISONIC_SCALING_SOFT
:
1805 ascale
= attrList
[attrIdx
+ 1];
1806 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT
, ascale
);
1807 if(!IsValidAmbiScaling(ascale
))
1808 return ALC_INVALID_VALUE
;
1811 case ALC_AMBISONIC_ORDER_SOFT
:
1812 aorder
= attrList
[attrIdx
+ 1];
1813 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT
, aorder
);
1814 if(aorder
< 1 || aorder
> MAX_AMBI_ORDER
)
1815 return ALC_INVALID_VALUE
;
1818 case ALC_MONO_SOURCES
:
1819 numMono
= attrList
[attrIdx
+ 1];
1820 TRACE_ATTR(ALC_MONO_SOURCES
, numMono
);
1821 numMono
= maxi(numMono
, 0);
1824 case ALC_STEREO_SOURCES
:
1825 numStereo
= attrList
[attrIdx
+ 1];
1826 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1827 numStereo
= maxi(numStereo
, 0);
1830 case ALC_MAX_AUXILIARY_SENDS
:
1831 numSends
= attrList
[attrIdx
+ 1];
1832 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1833 numSends
= clampi(numSends
, 0, MAX_SENDS
);
1837 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1838 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1839 hrtf_appreq
= Hrtf_Disable
;
1840 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1841 hrtf_appreq
= Hrtf_Enable
;
1843 hrtf_appreq
= Hrtf_Default
;
1846 case ALC_HRTF_ID_SOFT
:
1847 hrtf_id
= attrList
[attrIdx
+ 1];
1848 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1851 case ALC_OUTPUT_LIMITER_SOFT
:
1852 gainLimiter
= attrList
[attrIdx
+ 1];
1853 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT
, gainLimiter
);
1857 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList
[attrIdx
],
1858 attrList
[attrIdx
+ 1], attrList
[attrIdx
+ 1]);
1866 if(!schans
|| !stype
|| !freq
)
1868 WARN("Missing format for loopback device\n");
1869 return ALC_INVALID_VALUE
;
1871 if(schans
== ALC_BFORMAT3D_SOFT
&& (!alayout
|| !ascale
|| !aorder
))
1873 WARN("Missing ambisonic info for loopback device\n");
1874 return ALC_INVALID_VALUE
;
1877 if((device
->Flags
&DEVICE_RUNNING
))
1878 V0(device
->Backend
,stop
)();
1879 device
->Flags
&= ~DEVICE_RUNNING
;
1881 UpdateClockBase(device
);
1883 device
->Frequency
= freq
;
1884 device
->FmtChans
= schans
;
1885 device
->FmtType
= stype
;
1886 if(schans
== ALC_BFORMAT3D_SOFT
)
1888 device
->AmbiOrder
= aorder
;
1889 device
->AmbiLayout
= alayout
;
1890 device
->AmbiScale
= ascale
;
1893 if(numMono
> INT_MAX
-numStereo
)
1894 numMono
= INT_MAX
-numStereo
;
1895 numMono
+= numStereo
;
1896 if(ConfigValueInt(NULL
, NULL
, "sources", &numMono
))
1902 numMono
= maxi(numMono
, 256);
1903 numStereo
= mini(numStereo
, numMono
);
1904 numMono
-= numStereo
;
1905 device
->SourcesMax
= numMono
+ numStereo
;
1907 device
->NumMonoSources
= numMono
;
1908 device
->NumStereoSources
= numStereo
;
1910 if(ConfigValueInt(NULL
, NULL
, "sends", &new_sends
))
1911 new_sends
= mini(numSends
, clampi(new_sends
, 0, MAX_SENDS
));
1913 new_sends
= numSends
;
1915 else if(attrList
&& attrList
[0])
1917 ALCsizei numMono
, numStereo
, numSends
;
1918 ALCsizei attrIdx
= 0;
1921 /* If a context is already running on the device, stop playback so the
1922 * device attributes can be updated. */
1923 if((device
->Flags
&DEVICE_RUNNING
))
1924 V0(device
->Backend
,stop
)();
1925 device
->Flags
&= ~DEVICE_RUNNING
;
1927 UpdateClockBase(device
);
1929 freq
= device
->Frequency
;
1930 numMono
= device
->NumMonoSources
;
1931 numStereo
= device
->NumStereoSources
;
1932 numSends
= old_sends
;
1934 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1935 while(attrList
[attrIdx
])
1937 switch(attrList
[attrIdx
])
1940 freq
= attrList
[attrIdx
+ 1];
1941 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1942 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1945 case ALC_MONO_SOURCES
:
1946 numMono
= attrList
[attrIdx
+ 1];
1947 TRACE_ATTR(ALC_MONO_SOURCES
, numMono
);
1948 numMono
= maxi(numMono
, 0);
1951 case ALC_STEREO_SOURCES
:
1952 numStereo
= attrList
[attrIdx
+ 1];
1953 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1954 numStereo
= maxi(numStereo
, 0);
1957 case ALC_MAX_AUXILIARY_SENDS
:
1958 numSends
= attrList
[attrIdx
+ 1];
1959 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1960 numSends
= clampi(numSends
, 0, MAX_SENDS
);
1964 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1965 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1966 hrtf_appreq
= Hrtf_Disable
;
1967 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1968 hrtf_appreq
= Hrtf_Enable
;
1970 hrtf_appreq
= Hrtf_Default
;
1973 case ALC_HRTF_ID_SOFT
:
1974 hrtf_id
= attrList
[attrIdx
+ 1];
1975 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1978 case ALC_OUTPUT_LIMITER_SOFT
:
1979 gainLimiter
= attrList
[attrIdx
+ 1];
1980 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT
, gainLimiter
);
1984 TRACE("0x%04X = %d (0x%x)\n", attrList
[attrIdx
],
1985 attrList
[attrIdx
+ 1], attrList
[attrIdx
+ 1]);
1993 ConfigValueUInt(alstr_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1994 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1996 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1998 /* SSE and Neon do best with the update size being a multiple of 4 */
1999 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
2000 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
2002 device
->Frequency
= freq
;
2004 if(numMono
> INT_MAX
-numStereo
)
2005 numMono
= INT_MAX
-numStereo
;
2006 numMono
+= numStereo
;
2007 if(ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "sources", &numMono
))
2013 numMono
= maxi(numMono
, 256);
2014 numStereo
= mini(numStereo
, numMono
);
2015 numMono
-= numStereo
;
2016 device
->SourcesMax
= numMono
+ numStereo
;
2018 device
->NumMonoSources
= numMono
;
2019 device
->NumStereoSources
= numStereo
;
2021 if(ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "sends", &new_sends
))
2022 new_sends
= mini(numSends
, clampi(new_sends
, 0, MAX_SENDS
));
2024 new_sends
= numSends
;
2027 if((device
->Flags
&DEVICE_RUNNING
))
2028 return ALC_NO_ERROR
;
2030 al_free(device
->Uhj_Encoder
);
2031 device
->Uhj_Encoder
= NULL
;
2033 al_free(device
->Bs2b
);
2034 device
->Bs2b
= NULL
;
2036 al_free(device
->ChannelDelay
[0].Buffer
);
2037 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
2039 device
->ChannelDelay
[i
].Length
= 0;
2040 device
->ChannelDelay
[i
].Buffer
= NULL
;
2043 al_free(device
->Dry
.Buffer
);
2044 device
->Dry
.Buffer
= NULL
;
2045 device
->Dry
.NumChannels
= 0;
2046 device
->FOAOut
.Buffer
= NULL
;
2047 device
->FOAOut
.NumChannels
= 0;
2048 device
->RealOut
.Buffer
= NULL
;
2049 device
->RealOut
.NumChannels
= 0;
2051 UpdateClockBase(device
);
2053 device
->DitherSeed
= DITHER_RNG_SEED
;
2055 /*************************************************************************
2056 * Update device format request if HRTF is requested
2058 device
->HrtfStatus
= ALC_HRTF_DISABLED_SOFT
;
2059 if(device
->Type
!= Loopback
)
2062 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
2064 if(strcasecmp(hrtf
, "true") == 0)
2065 hrtf_userreq
= Hrtf_Enable
;
2066 else if(strcasecmp(hrtf
, "false") == 0)
2067 hrtf_userreq
= Hrtf_Disable
;
2068 else if(strcasecmp(hrtf
, "auto") != 0)
2069 ERR("Unexpected hrtf value: %s\n", hrtf
);
2072 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
2074 struct Hrtf
*hrtf
= NULL
;
2075 if(VECTOR_SIZE(device
->HrtfList
) == 0)
2077 VECTOR_DEINIT(device
->HrtfList
);
2078 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
2080 if(VECTOR_SIZE(device
->HrtfList
) > 0)
2082 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->HrtfList
))
2083 hrtf
= GetLoadedHrtf(VECTOR_ELEM(device
->HrtfList
, hrtf_id
).hrtf
);
2085 hrtf
= GetLoadedHrtf(VECTOR_ELEM(device
->HrtfList
, 0).hrtf
);
2090 device
->FmtChans
= DevFmtStereo
;
2091 device
->Frequency
= hrtf
->sampleRate
;
2092 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
2093 if(device
->HrtfHandle
)
2094 Hrtf_DecRef(device
->HrtfHandle
);
2095 device
->HrtfHandle
= hrtf
;
2099 hrtf_userreq
= Hrtf_Default
;
2100 hrtf_appreq
= Hrtf_Disable
;
2101 device
->HrtfStatus
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2106 oldFreq
= device
->Frequency
;
2107 oldChans
= device
->FmtChans
;
2108 oldType
= device
->FmtType
;
2110 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2111 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
2112 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
2113 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
2114 device
->UpdateSize
, device
->NumUpdates
2117 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
2118 return ALC_INVALID_DEVICE
;
2120 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
2122 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
2123 DevFmtChannelsString(device
->FmtChans
));
2124 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
2126 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
2128 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
2129 DevFmtTypeString(device
->FmtType
));
2130 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
2132 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
2134 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
2135 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
2138 if((device
->UpdateSize
&3) != 0)
2140 if((CPUCapFlags
&CPU_CAP_SSE
))
2141 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2142 if((CPUCapFlags
&CPU_CAP_NEON
))
2143 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2146 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2147 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
2148 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
2151 aluInitRenderer(device
, hrtf_id
, hrtf_appreq
, hrtf_userreq
);
2152 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device
->Dry
.NumChannels
,
2153 device
->FOAOut
.NumChannels
, device
->RealOut
.NumChannels
);
2155 /* Allocate extra channels for any post-filter output. */
2156 size
= (device
->Dry
.NumChannels
+ device
->FOAOut
.NumChannels
+
2157 device
->RealOut
.NumChannels
)*sizeof(device
->Dry
.Buffer
[0]);
2159 TRACE("Allocating "SZFMT
" channels, "SZFMT
" bytes\n", size
/sizeof(device
->Dry
.Buffer
[0]), size
);
2160 device
->Dry
.Buffer
= al_calloc(16, size
);
2161 if(!device
->Dry
.Buffer
)
2163 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2164 return ALC_INVALID_DEVICE
;
2167 if(device
->RealOut
.NumChannels
!= 0)
2168 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
+
2169 device
->FOAOut
.NumChannels
;
2172 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2173 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2176 if(device
->FOAOut
.NumChannels
!= 0)
2177 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2180 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
;
2181 device
->FOAOut
.NumChannels
= device
->Dry
.NumChannels
;
2184 device
->NumAuxSends
= new_sends
;
2185 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2186 device
->SourcesMax
, device
->NumMonoSources
, device
->NumStereoSources
,
2187 device
->AuxiliaryEffectSlotMax
, device
->NumAuxSends
);
2189 device
->DitherDepth
= 0.0f
;
2190 if(GetConfigValueBool(alstr_get_cstr(device
->DeviceName
), NULL
, "dither", 1))
2193 ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "dither-depth", &depth
);
2196 switch(device
->FmtType
)
2214 device
->DitherDepth
= (depth
> 0) ? powf(2.0f
, (ALfloat
)(depth
-1)) : 0.0f
;
2216 if(!(device
->DitherDepth
> 0.0f
))
2217 TRACE("Dithering disabled\n");
2219 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device
->DitherDepth
)+1.0f
,
2220 device
->DitherDepth
);
2222 if(ConfigValueBool(alstr_get_cstr(device
->DeviceName
), NULL
, "output-limiter", &val
))
2223 gainLimiter
= val
? ALC_TRUE
: ALC_FALSE
;
2224 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2225 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2228 if(gainLimiter
!= ALC_FALSE
)
2230 if(!device
->Limiter
|| device
->Frequency
!= GetCompressorSampleRate(device
->Limiter
))
2232 al_free(device
->Limiter
);
2233 device
->Limiter
= CreateDeviceLimiter(device
);
2238 al_free(device
->Limiter
);
2239 device
->Limiter
= NULL
;
2241 TRACE("Output limiter %s\n", device
->Limiter
? "enabled" : "disabled");
2243 /* Need to delay returning failure until replacement Send arrays have been
2244 * allocated with the appropriate size.
2246 update_failed
= AL_FALSE
;
2247 SetMixerFPUMode(&oldMode
);
2248 if(device
->DefaultSlot
)
2250 ALeffectslot
*slot
= device
->DefaultSlot
;
2251 ALeffectState
*state
= slot
->Effect
.State
;
2253 state
->OutBuffer
= device
->Dry
.Buffer
;
2254 state
->OutChannels
= device
->Dry
.NumChannels
;
2255 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2256 update_failed
= AL_TRUE
;
2258 UpdateEffectSlotProps(slot
);
2261 context
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
2266 WriteLock(&context
->PropLock
);
2267 LockUIntMapRead(&context
->EffectSlotMap
);
2268 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2270 ALeffectslot
*slot
= context
->EffectSlotMap
.values
[pos
];
2271 ALeffectState
*state
= slot
->Effect
.State
;
2273 state
->OutBuffer
= device
->Dry
.Buffer
;
2274 state
->OutChannels
= device
->Dry
.NumChannels
;
2275 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2276 update_failed
= AL_TRUE
;
2278 UpdateEffectSlotProps(slot
);
2280 UnlockUIntMapRead(&context
->EffectSlotMap
);
2282 LockUIntMapRead(&context
->SourceMap
);
2283 RelimitUIntMapNoLock(&context
->SourceMap
, device
->SourcesMax
);
2284 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2286 ALsource
*source
= context
->SourceMap
.values
[pos
];
2288 if(old_sends
!= device
->NumAuxSends
)
2290 ALvoid
*sends
= al_calloc(16, device
->NumAuxSends
*sizeof(source
->Send
[0]));
2293 memcpy(sends
, source
->Send
,
2294 mini(device
->NumAuxSends
, old_sends
)*sizeof(source
->Send
[0])
2296 for(s
= device
->NumAuxSends
;s
< old_sends
;s
++)
2298 if(source
->Send
[s
].Slot
)
2299 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2300 source
->Send
[s
].Slot
= NULL
;
2302 al_free(source
->Send
);
2303 source
->Send
= sends
;
2304 for(s
= old_sends
;s
< device
->NumAuxSends
;s
++)
2306 source
->Send
[s
].Slot
= NULL
;
2307 source
->Send
[s
].Gain
= 1.0f
;
2308 source
->Send
[s
].GainHF
= 1.0f
;
2309 source
->Send
[s
].HFReference
= LOWPASSFREQREF
;
2310 source
->Send
[s
].GainLF
= 1.0f
;
2311 source
->Send
[s
].LFReference
= HIGHPASSFREQREF
;
2315 ATOMIC_FLAG_CLEAR(&source
->PropsClean
, almemory_order_release
);
2317 AllocateVoices(context
, context
->MaxVoices
, old_sends
);
2318 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2320 ALvoice
*voice
= context
->Voices
[pos
];
2321 struct ALvoiceProps
*props
;
2323 /* Clear any pre-existing voice property structs, in case the
2324 * number of auxiliary sends changed. Active sources will have
2325 * updates respecified in UpdateAllSourceProps.
2327 props
= ATOMIC_EXCHANGE_PTR(&voice
->Update
, NULL
, almemory_order_relaxed
);
2330 props
= ATOMIC_EXCHANGE_PTR(&voice
->FreeList
, NULL
, almemory_order_relaxed
);
2333 struct ALvoiceProps
*next
= ATOMIC_LOAD(&props
->next
, almemory_order_relaxed
);
2338 if(ATOMIC_LOAD(&voice
->Source
, almemory_order_acquire
) == NULL
)
2341 if(device
->AvgSpeakerDist
> 0.0f
)
2343 /* Reinitialize the NFC filters for new parameters. */
2344 ALfloat w1
= SPEEDOFSOUNDMETRESPERSEC
/
2345 (device
->AvgSpeakerDist
* device
->Frequency
);
2346 for(i
= 0;i
< voice
->NumChannels
;i
++)
2348 NfcFilterCreate1(&voice
->Direct
.Params
[i
].NFCtrlFilter
[0], 0.0f
, w1
);
2349 NfcFilterCreate2(&voice
->Direct
.Params
[i
].NFCtrlFilter
[1], 0.0f
, w1
);
2350 NfcFilterCreate3(&voice
->Direct
.Params
[i
].NFCtrlFilter
[2], 0.0f
, w1
);
2354 UnlockUIntMapRead(&context
->SourceMap
);
2356 UpdateListenerProps(context
);
2357 UpdateAllSourceProps(context
);
2358 WriteUnlock(&context
->PropLock
);
2360 context
= context
->next
;
2362 RestoreFPUMode(&oldMode
);
2364 return ALC_INVALID_DEVICE
;
2366 if(!(device
->Flags
&DEVICE_PAUSED
))
2368 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2369 return ALC_INVALID_DEVICE
;
2370 device
->Flags
|= DEVICE_RUNNING
;
2373 return ALC_NO_ERROR
;
2378 * Frees the device structure, and destroys any objects the app failed to
2379 * delete. Called once there's no more references on the device.
2381 static ALCvoid
FreeDevice(ALCdevice
*device
)
2385 TRACE("%p\n", device
);
2387 V0(device
->Backend
,close
)();
2388 DELETE_OBJ(device
->Backend
);
2389 device
->Backend
= NULL
;
2391 almtx_destroy(&device
->BackendLock
);
2393 if(device
->DefaultSlot
)
2395 DeinitEffectSlot(device
->DefaultSlot
);
2396 device
->DefaultSlot
= NULL
;
2399 if(device
->BufferMap
.size
> 0)
2401 WARN("(%p) Deleting %d Buffer%s\n", device
, device
->BufferMap
.size
,
2402 (device
->BufferMap
.size
==1)?"":"s");
2403 ReleaseALBuffers(device
);
2405 ResetUIntMap(&device
->BufferMap
);
2407 if(device
->EffectMap
.size
> 0)
2409 WARN("(%p) Deleting %d Effect%s\n", device
, device
->EffectMap
.size
,
2410 (device
->EffectMap
.size
==1)?"":"s");
2411 ReleaseALEffects(device
);
2413 ResetUIntMap(&device
->EffectMap
);
2415 if(device
->FilterMap
.size
> 0)
2417 WARN("(%p) Deleting %d Filter%s\n", device
, device
->FilterMap
.size
,
2418 (device
->FilterMap
.size
==1)?"":"s");
2419 ReleaseALFilters(device
);
2421 ResetUIntMap(&device
->FilterMap
);
2423 AL_STRING_DEINIT(device
->HrtfName
);
2424 FreeHrtfList(&device
->HrtfList
);
2425 if(device
->HrtfHandle
)
2426 Hrtf_DecRef(device
->HrtfHandle
);
2427 device
->HrtfHandle
= NULL
;
2428 al_free(device
->Hrtf
);
2429 device
->Hrtf
= NULL
;
2431 al_free(device
->Bs2b
);
2432 device
->Bs2b
= NULL
;
2434 al_free(device
->Uhj_Encoder
);
2435 device
->Uhj_Encoder
= NULL
;
2437 bformatdec_free(device
->AmbiDecoder
);
2438 device
->AmbiDecoder
= NULL
;
2440 ambiup_free(device
->AmbiUp
);
2441 device
->AmbiUp
= NULL
;
2443 al_free(device
->Limiter
);
2444 device
->Limiter
= NULL
;
2446 al_free(device
->ChannelDelay
[0].Buffer
);
2447 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
2449 device
->ChannelDelay
[i
].Gain
= 1.0f
;
2450 device
->ChannelDelay
[i
].Length
= 0;
2451 device
->ChannelDelay
[i
].Buffer
= NULL
;
2454 AL_STRING_DEINIT(device
->DeviceName
);
2456 al_free(device
->Dry
.Buffer
);
2457 device
->Dry
.Buffer
= NULL
;
2458 device
->Dry
.NumChannels
= 0;
2459 device
->FOAOut
.Buffer
= NULL
;
2460 device
->FOAOut
.NumChannels
= 0;
2461 device
->RealOut
.Buffer
= NULL
;
2462 device
->RealOut
.NumChannels
= 0;
2468 void ALCdevice_IncRef(ALCdevice
*device
)
2471 ref
= IncrementRef(&device
->ref
);
2472 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2475 void ALCdevice_DecRef(ALCdevice
*device
)
2478 ref
= DecrementRef(&device
->ref
);
2479 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2480 if(ref
== 0) FreeDevice(device
);
2485 * Checks if the device handle is valid, and increments its ref count if so.
2487 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2489 ALCdevice
*tmpDevice
;
2492 tmpDevice
= ATOMIC_LOAD_SEQ(&DeviceList
);
2495 if(tmpDevice
== *device
)
2497 ALCdevice_IncRef(tmpDevice
);
2501 tmpDevice
= tmpDevice
->next
;
2512 * Initializes context fields
2514 static ALvoid
InitContext(ALCcontext
*Context
)
2516 ALlistener
*listener
= Context
->Listener
;
2517 struct ALeffectslotArray
*auxslots
;
2519 //Initialise listener
2520 listener
->Gain
= 1.0f
;
2521 listener
->MetersPerUnit
= 1.0f
;
2522 listener
->Position
[0] = 0.0f
;
2523 listener
->Position
[1] = 0.0f
;
2524 listener
->Position
[2] = 0.0f
;
2525 listener
->Velocity
[0] = 0.0f
;
2526 listener
->Velocity
[1] = 0.0f
;
2527 listener
->Velocity
[2] = 0.0f
;
2528 listener
->Forward
[0] = 0.0f
;
2529 listener
->Forward
[1] = 0.0f
;
2530 listener
->Forward
[2] = -1.0f
;
2531 listener
->Up
[0] = 0.0f
;
2532 listener
->Up
[1] = 1.0f
;
2533 listener
->Up
[2] = 0.0f
;
2535 aluMatrixfSet(&listener
->Params
.Matrix
,
2536 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2537 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2538 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2539 0.0f
, 0.0f
, 0.0f
, 1.0f
2541 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2542 listener
->Params
.Gain
= 1.0f
;
2543 listener
->Params
.MetersPerUnit
= 1.0f
;
2544 listener
->Params
.DopplerFactor
= 1.0f
;
2545 listener
->Params
.SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2547 ATOMIC_INIT(&listener
->Update
, NULL
);
2548 ATOMIC_INIT(&listener
->FreeList
, NULL
);
2551 InitRef(&Context
->UpdateCount
, 0);
2552 ATOMIC_INIT(&Context
->HoldUpdates
, AL_FALSE
);
2553 Context
->GainBoost
= 1.0f
;
2554 RWLockInit(&Context
->PropLock
);
2555 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2556 InitUIntMap(&Context
->SourceMap
, Context
->Device
->SourcesMax
);
2557 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2559 auxslots
= al_calloc(DEF_ALIGN
, sizeof(struct ALeffectslotArray
));
2560 auxslots
->count
= 0;
2561 ATOMIC_INIT(&Context
->ActiveAuxSlots
, auxslots
);
2564 Context
->DistanceModel
= DefaultDistanceModel
;
2565 Context
->SourceDistanceModel
= AL_FALSE
;
2566 Context
->DopplerFactor
= 1.0f
;
2567 Context
->DopplerVelocity
= 1.0f
;
2568 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2569 ATOMIC_INIT(&Context
->DeferUpdates
, AL_FALSE
);
2571 Context
->ExtensionList
= alExtList
;
2577 * Cleans up the context, and destroys any remaining objects the app failed to
2578 * delete. Called once there's no more references on the context.
2580 static void FreeContext(ALCcontext
*context
)
2582 ALlistener
*listener
= context
->Listener
;
2583 struct ALeffectslotArray
*auxslots
;
2584 struct ALlistenerProps
*lprops
;
2588 TRACE("%p\n", context
);
2590 auxslots
= ATOMIC_EXCHANGE_PTR(&context
->ActiveAuxSlots
, NULL
, almemory_order_relaxed
);
2593 if(context
->SourceMap
.size
> 0)
2595 WARN("(%p) Deleting %d Source%s\n", context
, context
->SourceMap
.size
,
2596 (context
->SourceMap
.size
==1)?"":"s");
2597 ReleaseALSources(context
);
2599 ResetUIntMap(&context
->SourceMap
);
2601 if(context
->EffectSlotMap
.size
> 0)
2603 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context
, context
->EffectSlotMap
.size
,
2604 (context
->EffectSlotMap
.size
==1)?"":"s");
2605 ReleaseALAuxiliaryEffectSlots(context
);
2607 ResetUIntMap(&context
->EffectSlotMap
);
2609 for(i
= 0;i
< context
->VoiceCount
;i
++)
2610 DeinitVoice(context
->Voices
[i
]);
2611 al_free(context
->Voices
);
2612 context
->Voices
= NULL
;
2613 context
->VoiceCount
= 0;
2614 context
->MaxVoices
= 0;
2616 if((lprops
=ATOMIC_LOAD(&listener
->Update
, almemory_order_acquire
)) != NULL
)
2618 TRACE("Freed unapplied listener update %p\n", lprops
);
2622 lprops
= ATOMIC_LOAD(&listener
->FreeList
, almemory_order_acquire
);
2625 struct ALlistenerProps
*next
= ATOMIC_LOAD(&lprops
->next
, almemory_order_acquire
);
2630 TRACE("Freed "SZFMT
" listener property object%s\n", count
, (count
==1)?"":"s");
2632 ALCdevice_DecRef(context
->Device
);
2633 context
->Device
= NULL
;
2635 //Invalidate context
2636 memset(context
, 0, sizeof(ALCcontext
));
2642 * Removes the context reference from the given device and removes it from
2643 * being current on the running thread or globally. Returns true if other
2644 * contexts still exist on the device.
2646 static bool ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2648 ALCcontext
*origctx
, *newhead
;
2651 if(altss_get(LocalContext
) == context
)
2653 WARN("%p released while current on thread\n", context
);
2654 altss_set(LocalContext
, NULL
);
2655 ALCcontext_DecRef(context
);
2659 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext
, &origctx
, NULL
))
2660 ALCcontext_DecRef(context
);
2662 ALCdevice_Lock(device
);
2664 newhead
= context
->next
;
2665 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device
->ContextList
, &origctx
, newhead
))
2667 ALCcontext
*volatile*list
= &origctx
->next
;
2670 if(*list
== context
)
2672 *list
= (*list
)->next
;
2675 list
= &(*list
)->next
;
2680 ALCdevice_Unlock(device
);
2682 ALCcontext_DecRef(context
);
2686 void ALCcontext_IncRef(ALCcontext
*context
)
2688 uint ref
= IncrementRef(&context
->ref
);
2689 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2692 void ALCcontext_DecRef(ALCcontext
*context
)
2694 uint ref
= DecrementRef(&context
->ref
);
2695 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2696 if(ref
== 0) FreeContext(context
);
2699 static void ReleaseThreadCtx(void *ptr
)
2701 ALCcontext
*context
= ptr
;
2702 uint ref
= DecrementRef(&context
->ref
);
2703 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2704 ERR("Context %p current for thread being destroyed, possible leak!\n", context
);
2709 * Checks that the given context is valid, and increments its reference count.
2711 static ALCboolean
VerifyContext(ALCcontext
**context
)
2716 dev
= ATOMIC_LOAD_SEQ(&DeviceList
);
2719 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
, almemory_order_acquire
);
2724 ALCcontext_IncRef(ctx
);
2741 * Returns the currently active context for this thread, and adds a reference
2742 * without locking it.
2744 ALCcontext
*GetContextRef(void)
2746 ALCcontext
*context
;
2748 context
= altss_get(LocalContext
);
2750 ALCcontext_IncRef(context
);
2754 context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
2756 ALCcontext_IncRef(context
);
2764 void AllocateVoices(ALCcontext
*context
, ALsizei num_voices
, ALsizei old_sends
)
2766 ALCdevice
*device
= context
->Device
;
2767 ALsizei num_sends
= device
->NumAuxSends
;
2768 struct ALvoiceProps
*props
;
2769 size_t sizeof_props
;
2770 size_t sizeof_voice
;
2776 if(num_voices
== context
->MaxVoices
&& num_sends
== old_sends
)
2779 /* Allocate the voice pointers, voices, and the voices' stored source
2780 * property set (including the dynamically-sized Send[] array) in one
2783 sizeof_voice
= RoundUp(FAM_SIZE(ALvoice
, Send
, num_sends
), 16);
2784 sizeof_props
= RoundUp(FAM_SIZE(struct ALvoiceProps
, Send
, num_sends
), 16);
2785 size
= sizeof(ALvoice
*) + sizeof_voice
+ sizeof_props
;
2787 voices
= al_calloc(16, RoundUp(size
*num_voices
, 16));
2788 /* The voice and property objects are stored interleaved since they're
2791 voice
= (ALvoice
*)((char*)voices
+ RoundUp(num_voices
*sizeof(ALvoice
*), 16));
2792 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2796 const ALsizei v_count
= mini(context
->VoiceCount
, num_voices
);
2797 const ALsizei s_count
= mini(old_sends
, num_sends
);
2799 for(;v
< v_count
;v
++)
2801 ALvoice
*old_voice
= context
->Voices
[v
];
2804 /* Copy the old voice data and source property set to the new
2807 *voice
= *old_voice
;
2808 for(i
= 0;i
< s_count
;i
++)
2809 voice
->Send
[i
] = old_voice
->Send
[i
];
2810 *props
= *(old_voice
->Props
);
2811 for(i
= 0;i
< s_count
;i
++)
2812 props
->Send
[i
] = old_voice
->Props
->Send
[i
];
2814 /* Set this voice's property set pointer and voice reference. */
2815 voice
->Props
= props
;
2818 /* Increment pointers to the next storage space. */
2819 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2820 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2822 /* Deinit any left over voices that weren't copied over to the new
2823 * array. NOTE: If this does anything, v equals num_voices and
2824 * num_voices is less than VoiceCount, so the following loop won't do
2827 for(;v
< context
->VoiceCount
;v
++)
2828 DeinitVoice(context
->Voices
[v
]);
2830 /* Finish setting the voices' property set pointers and references. */
2831 for(;v
< num_voices
;v
++)
2833 ATOMIC_INIT(&voice
->Update
, NULL
);
2834 ATOMIC_INIT(&voice
->FreeList
, NULL
);
2836 voice
->Props
= props
;
2839 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2840 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2843 al_free(context
->Voices
);
2844 context
->Voices
= voices
;
2845 context
->MaxVoices
= num_voices
;
2846 context
->VoiceCount
= mini(context
->VoiceCount
, num_voices
);
2850 /************************************************
2851 * Standard ALC functions
2852 ************************************************/
2856 * Return last ALC generated error code for the given device
2858 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2862 if(VerifyDevice(&device
))
2864 errorCode
= ATOMIC_EXCHANGE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
2865 ALCdevice_DecRef(device
);
2868 errorCode
= ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError
, ALC_NO_ERROR
);
2874 /* alcSuspendContext
2876 * Suspends updates for the given context
2878 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2883 if(!VerifyContext(&context
))
2884 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2887 ALCcontext_DeferUpdates(context
);
2888 ALCcontext_DecRef(context
);
2892 /* alcProcessContext
2894 * Resumes processing updates for the given context
2896 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2901 if(!VerifyContext(&context
))
2902 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2905 ALCcontext_ProcessUpdates(context
);
2906 ALCcontext_DecRef(context
);
2913 * Returns information about the device, and error strings
2915 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2917 const ALCchar
*value
= NULL
;
2925 case ALC_INVALID_ENUM
:
2926 value
= alcErrInvalidEnum
;
2929 case ALC_INVALID_VALUE
:
2930 value
= alcErrInvalidValue
;
2933 case ALC_INVALID_DEVICE
:
2934 value
= alcErrInvalidDevice
;
2937 case ALC_INVALID_CONTEXT
:
2938 value
= alcErrInvalidContext
;
2941 case ALC_OUT_OF_MEMORY
:
2942 value
= alcErrOutOfMemory
;
2945 case ALC_DEVICE_SPECIFIER
:
2946 value
= alcDefaultName
;
2949 case ALC_ALL_DEVICES_SPECIFIER
:
2950 if(VerifyDevice(&Device
))
2952 value
= alstr_get_cstr(Device
->DeviceName
);
2953 ALCdevice_DecRef(Device
);
2957 ProbeAllDevicesList();
2958 value
= alstr_get_cstr(alcAllDevicesList
);
2962 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2963 if(VerifyDevice(&Device
))
2965 value
= alstr_get_cstr(Device
->DeviceName
);
2966 ALCdevice_DecRef(Device
);
2970 ProbeCaptureDeviceList();
2971 value
= alstr_get_cstr(alcCaptureDeviceList
);
2975 /* Default devices are always first in the list */
2976 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2977 value
= alcDefaultName
;
2980 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2981 if(alstr_empty(alcAllDevicesList
))
2982 ProbeAllDevicesList();
2984 VerifyDevice(&Device
);
2986 free(alcDefaultAllDevicesSpecifier
);
2987 alcDefaultAllDevicesSpecifier
= strdup(alstr_get_cstr(alcAllDevicesList
));
2988 if(!alcDefaultAllDevicesSpecifier
)
2989 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2991 value
= alcDefaultAllDevicesSpecifier
;
2992 if(Device
) ALCdevice_DecRef(Device
);
2995 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2996 if(alstr_empty(alcCaptureDeviceList
))
2997 ProbeCaptureDeviceList();
2999 VerifyDevice(&Device
);
3001 free(alcCaptureDefaultDeviceSpecifier
);
3002 alcCaptureDefaultDeviceSpecifier
= strdup(alstr_get_cstr(alcCaptureDeviceList
));
3003 if(!alcCaptureDefaultDeviceSpecifier
)
3004 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
3006 value
= alcCaptureDefaultDeviceSpecifier
;
3007 if(Device
) ALCdevice_DecRef(Device
);
3010 case ALC_EXTENSIONS
:
3011 if(!VerifyDevice(&Device
))
3012 value
= alcNoDeviceExtList
;
3015 value
= alcExtensionList
;
3016 ALCdevice_DecRef(Device
);
3020 case ALC_HRTF_SPECIFIER_SOFT
:
3021 if(!VerifyDevice(&Device
))
3022 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3025 almtx_lock(&Device
->BackendLock
);
3026 value
= (Device
->HrtfHandle
? alstr_get_cstr(Device
->HrtfName
) : "");
3027 almtx_unlock(&Device
->BackendLock
);
3028 ALCdevice_DecRef(Device
);
3033 VerifyDevice(&Device
);
3034 alcSetError(Device
, ALC_INVALID_ENUM
);
3035 if(Device
) ALCdevice_DecRef(Device
);
3043 static inline ALCsizei
NumAttrsForDevice(ALCdevice
*device
)
3045 if(device
->Type
== Loopback
&& device
->FmtChans
== DevFmtAmbi3D
)
3050 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3054 if(size
<= 0 || values
== NULL
)
3056 alcSetError(device
, ALC_INVALID_VALUE
);
3064 case ALC_MAJOR_VERSION
:
3065 values
[0] = alcMajorVersion
;
3067 case ALC_MINOR_VERSION
:
3068 values
[0] = alcMinorVersion
;
3071 case ALC_ATTRIBUTES_SIZE
:
3072 case ALC_ALL_ATTRIBUTES
:
3076 case ALC_MONO_SOURCES
:
3077 case ALC_STEREO_SOURCES
:
3078 case ALC_CAPTURE_SAMPLES
:
3079 case ALC_FORMAT_CHANNELS_SOFT
:
3080 case ALC_FORMAT_TYPE_SOFT
:
3081 case ALC_AMBISONIC_LAYOUT_SOFT
:
3082 case ALC_AMBISONIC_SCALING_SOFT
:
3083 case ALC_AMBISONIC_ORDER_SOFT
:
3084 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3088 alcSetError(NULL
, ALC_INVALID_ENUM
);
3094 if(device
->Type
== Capture
)
3098 case ALC_CAPTURE_SAMPLES
:
3099 almtx_lock(&device
->BackendLock
);
3100 values
[0] = V0(device
->Backend
,availableSamples
)();
3101 almtx_unlock(&device
->BackendLock
);
3105 values
[0] = device
->Connected
;
3109 alcSetError(device
, ALC_INVALID_ENUM
);
3118 case ALC_MAJOR_VERSION
:
3119 values
[0] = alcMajorVersion
;
3122 case ALC_MINOR_VERSION
:
3123 values
[0] = alcMinorVersion
;
3126 case ALC_EFX_MAJOR_VERSION
:
3127 values
[0] = alcEFXMajorVersion
;
3130 case ALC_EFX_MINOR_VERSION
:
3131 values
[0] = alcEFXMinorVersion
;
3134 case ALC_ATTRIBUTES_SIZE
:
3135 values
[0] = NumAttrsForDevice(device
);
3138 case ALC_ALL_ATTRIBUTES
:
3139 if(size
< NumAttrsForDevice(device
))
3141 alcSetError(device
, ALC_INVALID_VALUE
);
3146 almtx_lock(&device
->BackendLock
);
3147 values
[i
++] = ALC_FREQUENCY
;
3148 values
[i
++] = device
->Frequency
;
3150 if(device
->Type
!= Loopback
)
3152 values
[i
++] = ALC_REFRESH
;
3153 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3155 values
[i
++] = ALC_SYNC
;
3156 values
[i
++] = ALC_FALSE
;
3160 if(device
->FmtChans
== DevFmtAmbi3D
)
3162 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3163 values
[i
++] = device
->AmbiLayout
;
3165 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3166 values
[i
++] = device
->AmbiScale
;
3168 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3169 values
[i
++] = device
->AmbiOrder
;
3172 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3173 values
[i
++] = device
->FmtChans
;
3175 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3176 values
[i
++] = device
->FmtType
;
3179 values
[i
++] = ALC_MONO_SOURCES
;
3180 values
[i
++] = device
->NumMonoSources
;
3182 values
[i
++] = ALC_STEREO_SOURCES
;
3183 values
[i
++] = device
->NumStereoSources
;
3185 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3186 values
[i
++] = device
->NumAuxSends
;
3188 values
[i
++] = ALC_HRTF_SOFT
;
3189 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3191 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3192 values
[i
++] = device
->HrtfStatus
;
3194 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3195 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3196 almtx_unlock(&device
->BackendLock
);
3202 values
[0] = device
->Frequency
;
3206 if(device
->Type
== Loopback
)
3208 alcSetError(device
, ALC_INVALID_DEVICE
);
3211 almtx_lock(&device
->BackendLock
);
3212 values
[0] = device
->Frequency
/ device
->UpdateSize
;
3213 almtx_unlock(&device
->BackendLock
);
3217 if(device
->Type
== Loopback
)
3219 alcSetError(device
, ALC_INVALID_DEVICE
);
3222 values
[0] = ALC_FALSE
;
3225 case ALC_FORMAT_CHANNELS_SOFT
:
3226 if(device
->Type
!= Loopback
)
3228 alcSetError(device
, ALC_INVALID_DEVICE
);
3231 values
[0] = device
->FmtChans
;
3234 case ALC_FORMAT_TYPE_SOFT
:
3235 if(device
->Type
!= Loopback
)
3237 alcSetError(device
, ALC_INVALID_DEVICE
);
3240 values
[0] = device
->FmtType
;
3243 case ALC_AMBISONIC_LAYOUT_SOFT
:
3244 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3246 alcSetError(device
, ALC_INVALID_DEVICE
);
3249 values
[0] = device
->AmbiLayout
;
3252 case ALC_AMBISONIC_SCALING_SOFT
:
3253 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3255 alcSetError(device
, ALC_INVALID_DEVICE
);
3258 values
[0] = device
->AmbiScale
;
3261 case ALC_AMBISONIC_ORDER_SOFT
:
3262 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3264 alcSetError(device
, ALC_INVALID_DEVICE
);
3267 values
[0] = device
->AmbiOrder
;
3270 case ALC_MONO_SOURCES
:
3271 values
[0] = device
->NumMonoSources
;
3274 case ALC_STEREO_SOURCES
:
3275 values
[0] = device
->NumStereoSources
;
3278 case ALC_MAX_AUXILIARY_SENDS
:
3279 values
[0] = device
->NumAuxSends
;
3283 values
[0] = device
->Connected
;
3287 values
[0] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3290 case ALC_HRTF_STATUS_SOFT
:
3291 values
[0] = device
->HrtfStatus
;
3294 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
3295 almtx_lock(&device
->BackendLock
);
3296 FreeHrtfList(&device
->HrtfList
);
3297 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
3298 values
[0] = (ALCint
)VECTOR_SIZE(device
->HrtfList
);
3299 almtx_unlock(&device
->BackendLock
);
3302 case ALC_OUTPUT_LIMITER_SOFT
:
3303 values
[0] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3307 alcSetError(device
, ALC_INVALID_ENUM
);
3315 * Returns information about the device and the version of OpenAL
3317 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3319 VerifyDevice(&device
);
3320 if(size
<= 0 || values
== NULL
)
3321 alcSetError(device
, ALC_INVALID_VALUE
);
3323 GetIntegerv(device
, param
, size
, values
);
3324 if(device
) ALCdevice_DecRef(device
);
3327 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
3332 VerifyDevice(&device
);
3333 if(size
<= 0 || values
== NULL
)
3334 alcSetError(device
, ALC_INVALID_VALUE
);
3335 else if(!device
|| device
->Type
== Capture
)
3337 ivals
= malloc(size
* sizeof(ALCint
));
3338 size
= GetIntegerv(device
, pname
, size
, ivals
);
3339 for(i
= 0;i
< size
;i
++)
3340 values
[i
] = ivals
[i
];
3343 else /* render device */
3352 case ALC_ATTRIBUTES_SIZE
:
3353 *values
= NumAttrsForDevice(device
)+4;
3356 case ALC_ALL_ATTRIBUTES
:
3357 if(size
< NumAttrsForDevice(device
)+4)
3358 alcSetError(device
, ALC_INVALID_VALUE
);
3362 almtx_lock(&device
->BackendLock
);
3363 values
[i
++] = ALC_FREQUENCY
;
3364 values
[i
++] = device
->Frequency
;
3366 if(device
->Type
!= Loopback
)
3368 values
[i
++] = ALC_REFRESH
;
3369 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3371 values
[i
++] = ALC_SYNC
;
3372 values
[i
++] = ALC_FALSE
;
3376 if(device
->FmtChans
== DevFmtAmbi3D
)
3378 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3379 values
[i
++] = device
->AmbiLayout
;
3381 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3382 values
[i
++] = device
->AmbiScale
;
3384 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3385 values
[i
++] = device
->AmbiOrder
;
3388 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3389 values
[i
++] = device
->FmtChans
;
3391 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3392 values
[i
++] = device
->FmtType
;
3395 values
[i
++] = ALC_MONO_SOURCES
;
3396 values
[i
++] = device
->NumMonoSources
;
3398 values
[i
++] = ALC_STEREO_SOURCES
;
3399 values
[i
++] = device
->NumStereoSources
;
3401 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3402 values
[i
++] = device
->NumAuxSends
;
3404 values
[i
++] = ALC_HRTF_SOFT
;
3405 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3407 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3408 values
[i
++] = device
->HrtfStatus
;
3410 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3411 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3413 clock
= V0(device
->Backend
,getClockLatency
)();
3414 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3415 values
[i
++] = clock
.ClockTime
;
3417 values
[i
++] = ALC_DEVICE_LATENCY_SOFT
;
3418 values
[i
++] = clock
.Latency
;
3419 almtx_unlock(&device
->BackendLock
);
3425 case ALC_DEVICE_CLOCK_SOFT
:
3426 almtx_lock(&device
->BackendLock
);
3428 while(((refcount
=ReadRef(&device
->MixCount
))&1) != 0)
3430 basecount
= device
->ClockBase
;
3431 samplecount
= device
->SamplesDone
;
3432 } while(refcount
!= ReadRef(&device
->MixCount
));
3433 *values
= basecount
+ (samplecount
*DEVICE_CLOCK_RES
/device
->Frequency
);
3434 almtx_unlock(&device
->BackendLock
);
3437 case ALC_DEVICE_LATENCY_SOFT
:
3438 almtx_lock(&device
->BackendLock
);
3439 clock
= V0(device
->Backend
,getClockLatency
)();
3440 almtx_unlock(&device
->BackendLock
);
3441 *values
= clock
.Latency
;
3444 case ALC_DEVICE_CLOCK_LATENCY_SOFT
:
3446 alcSetError(device
, ALC_INVALID_VALUE
);
3449 almtx_lock(&device
->BackendLock
);
3450 clock
= V0(device
->Backend
,getClockLatency
)();
3451 almtx_unlock(&device
->BackendLock
);
3452 values
[0] = clock
.ClockTime
;
3453 values
[1] = clock
.Latency
;
3458 ivals
= malloc(size
* sizeof(ALCint
));
3459 size
= GetIntegerv(device
, pname
, size
, ivals
);
3460 for(i
= 0;i
< size
;i
++)
3461 values
[i
] = ivals
[i
];
3467 ALCdevice_DecRef(device
);
3471 /* alcIsExtensionPresent
3473 * Determines if there is support for a particular extension
3475 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3477 ALCboolean bResult
= ALC_FALSE
;
3479 VerifyDevice(&device
);
3482 alcSetError(device
, ALC_INVALID_VALUE
);
3485 size_t len
= strlen(extName
);
3486 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3489 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3490 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3495 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3499 } while(isspace(*ptr
));
3504 ALCdevice_DecRef(device
);
3509 /* alcGetProcAddress
3511 * Retrieves the function address for a particular extension function
3513 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3515 ALCvoid
*ptr
= NULL
;
3519 VerifyDevice(&device
);
3520 alcSetError(device
, ALC_INVALID_VALUE
);
3521 if(device
) ALCdevice_DecRef(device
);
3526 for(i
= 0;i
< COUNTOF(alcFunctions
);i
++)
3528 if(strcmp(alcFunctions
[i
].funcName
, funcName
) == 0)
3530 ptr
= alcFunctions
[i
].address
;
3542 * Get the value for a particular ALC enumeration name
3544 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3550 VerifyDevice(&device
);
3551 alcSetError(device
, ALC_INVALID_VALUE
);
3552 if(device
) ALCdevice_DecRef(device
);
3557 for(i
= 0;i
< COUNTOF(alcEnumerations
);i
++)
3559 if(strcmp(alcEnumerations
[i
].enumName
, enumName
) == 0)
3561 val
= alcEnumerations
[i
].value
;
3573 * Create and attach a context to the given device.
3575 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3577 ALCcontext
*ALContext
;
3581 /* Explicitly hold the list lock while taking the BackendLock in case the
3582 * device is asynchronously destropyed, to ensure this new context is
3583 * properly cleaned up after being made.
3586 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3589 alcSetError(device
, ALC_INVALID_DEVICE
);
3590 if(device
) ALCdevice_DecRef(device
);
3593 almtx_lock(&device
->BackendLock
);
3596 ATOMIC_STORE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
3598 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3601 almtx_unlock(&device
->BackendLock
);
3603 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3604 ALCdevice_DecRef(device
);
3608 InitRef(&ALContext
->ref
, 1);
3609 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3611 ALContext
->Voices
= NULL
;
3612 ALContext
->VoiceCount
= 0;
3613 ALContext
->MaxVoices
= 0;
3614 ATOMIC_INIT(&ALContext
->ActiveAuxSlots
, NULL
);
3615 ALContext
->Device
= device
;
3617 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3619 almtx_unlock(&device
->BackendLock
);
3621 al_free(ALContext
->Voices
);
3622 ALContext
->Voices
= NULL
;
3627 alcSetError(device
, err
);
3628 if(err
== ALC_INVALID_DEVICE
)
3630 V0(device
->Backend
,lock
)();
3631 aluHandleDisconnect(device
);
3632 V0(device
->Backend
,unlock
)();
3634 ALCdevice_DecRef(device
);
3637 AllocateVoices(ALContext
, 256, device
->NumAuxSends
);
3639 ALCdevice_IncRef(ALContext
->Device
);
3640 InitContext(ALContext
);
3642 if(ConfigValueFloat(alstr_get_cstr(device
->DeviceName
), NULL
, "volume-adjust", &valf
))
3645 ERR("volume-adjust must be finite: %f\n", valf
);
3648 ALfloat db
= clampf(valf
, -24.0f
, 24.0f
);
3650 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf
, 24.0f
);
3651 ALContext
->GainBoost
= powf(10.0f
, db
/20.0f
);
3652 TRACE("volume-adjust gain: %f\n", ALContext
->GainBoost
);
3655 UpdateListenerProps(ALContext
);
3658 ALCcontext
*head
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
3660 ALContext
->next
= head
;
3661 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device
->ContextList
, &head
,
3664 almtx_unlock(&device
->BackendLock
);
3666 ALCdevice_DecRef(device
);
3668 TRACE("Created context %p\n", ALContext
);
3672 /* alcDestroyContext
3674 * Remove a context from its device
3676 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3681 if(!VerifyContext(&context
))
3684 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3688 Device
= context
->Device
;
3691 almtx_lock(&Device
->BackendLock
);
3692 if(!ReleaseContext(context
, Device
))
3694 V0(Device
->Backend
,stop
)();
3695 Device
->Flags
&= ~DEVICE_RUNNING
;
3697 almtx_unlock(&Device
->BackendLock
);
3701 ALCcontext_DecRef(context
);
3705 /* alcGetCurrentContext
3707 * Returns the currently active context on the calling thread
3709 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3711 ALCcontext
*Context
= altss_get(LocalContext
);
3712 if(!Context
) Context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
3716 /* alcGetThreadContext
3718 * Returns the currently active thread-local context
3720 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3722 return altss_get(LocalContext
);
3726 /* alcMakeContextCurrent
3728 * Makes the given context the active process-wide context, and removes the
3729 * thread-local context for the calling thread.
3731 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3733 /* context must be valid or NULL */
3734 if(context
&& !VerifyContext(&context
))
3736 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3739 /* context's reference count is already incremented */
3740 context
= ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext
, context
);
3741 if(context
) ALCcontext_DecRef(context
);
3743 if((context
=altss_get(LocalContext
)) != NULL
)
3745 altss_set(LocalContext
, NULL
);
3746 ALCcontext_DecRef(context
);
3752 /* alcSetThreadContext
3754 * Makes the given context the active context for the current thread
3756 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3760 /* context must be valid or NULL */
3761 if(context
&& !VerifyContext(&context
))
3763 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3766 /* context's reference count is already incremented */
3767 old
= altss_get(LocalContext
);
3768 altss_set(LocalContext
, context
);
3769 if(old
) ALCcontext_DecRef(old
);
3775 /* alcGetContextsDevice
3777 * Returns the device that a particular context is attached to
3779 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3783 if(!VerifyContext(&Context
))
3785 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3788 Device
= Context
->Device
;
3789 ALCcontext_DecRef(Context
);
3797 * Opens the named device.
3799 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3801 ALCbackendFactory
*factory
;
3809 if(!PlaybackBackend
.name
)
3811 alcSetError(NULL
, ALC_INVALID_VALUE
);
3815 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3817 /* Some old Windows apps hardcode these expecting OpenAL to use a
3818 * specific audio API, even when they're not enumerated. Creative's
3819 * router effectively ignores them too.
3821 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3822 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3827 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3830 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3835 InitRef(&device
->ref
, 1);
3836 device
->Connected
= ALC_TRUE
;
3837 device
->Type
= Playback
;
3838 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3841 device
->Bs2b
= NULL
;
3842 device
->Uhj_Encoder
= NULL
;
3843 device
->Hrtf
= NULL
;
3844 device
->HrtfHandle
= NULL
;
3845 VECTOR_INIT(device
->HrtfList
);
3846 AL_STRING_INIT(device
->HrtfName
);
3847 device
->Render_Mode
= NormalRender
;
3848 AL_STRING_INIT(device
->DeviceName
);
3849 device
->Dry
.Buffer
= NULL
;
3850 device
->Dry
.NumChannels
= 0;
3851 device
->FOAOut
.Buffer
= NULL
;
3852 device
->FOAOut
.NumChannels
= 0;
3853 device
->RealOut
.Buffer
= NULL
;
3854 device
->RealOut
.NumChannels
= 0;
3855 device
->Limiter
= NULL
;
3856 device
->AvgSpeakerDist
= 0.0f
;
3858 ATOMIC_INIT(&device
->ContextList
, NULL
);
3860 device
->ClockBase
= 0;
3861 device
->SamplesDone
= 0;
3863 device
->SourcesMax
= 256;
3864 device
->AuxiliaryEffectSlotMax
= 64;
3865 device
->NumAuxSends
= DEFAULT_SENDS
;
3867 InitUIntMap(&device
->BufferMap
, INT_MAX
);
3868 InitUIntMap(&device
->EffectMap
, INT_MAX
);
3869 InitUIntMap(&device
->FilterMap
, INT_MAX
);
3871 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
3873 device
->ChannelDelay
[i
].Gain
= 1.0f
;
3874 device
->ChannelDelay
[i
].Length
= 0;
3875 device
->ChannelDelay
[i
].Buffer
= NULL
;
3879 device
->FmtChans
= DevFmtChannelsDefault
;
3880 device
->FmtType
= DevFmtTypeDefault
;
3881 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3882 device
->IsHeadphones
= AL_FALSE
;
3883 device
->AmbiLayout
= AmbiLayout_Default
;
3884 device
->AmbiScale
= AmbiNorm_Default
;
3885 device
->NumUpdates
= 3;
3886 device
->UpdateSize
= 1024;
3888 factory
= PlaybackBackend
.getFactory();
3889 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3890 if(!device
->Backend
)
3893 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3898 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3900 static const struct {
3901 const char name
[16];
3902 enum DevFmtChannels chans
;
3905 { "mono", DevFmtMono
, 0 },
3906 { "stereo", DevFmtStereo
, 0 },
3907 { "quad", DevFmtQuad
, 0 },
3908 { "surround51", DevFmtX51
, 0 },
3909 { "surround61", DevFmtX61
, 0 },
3910 { "surround71", DevFmtX71
, 0 },
3911 { "surround51rear", DevFmtX51Rear
, 0 },
3912 { "ambi1", DevFmtAmbi3D
, 1 },
3913 { "ambi2", DevFmtAmbi3D
, 2 },
3914 { "ambi3", DevFmtAmbi3D
, 3 },
3918 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3920 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3922 device
->FmtChans
= chanlist
[i
].chans
;
3923 device
->AmbiOrder
= chanlist
[i
].order
;
3924 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3928 if(i
== COUNTOF(chanlist
))
3929 ERR("Unsupported channels: %s\n", fmt
);
3931 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3933 static const struct {
3934 const char name
[16];
3935 enum DevFmtType type
;
3937 { "int8", DevFmtByte
},
3938 { "uint8", DevFmtUByte
},
3939 { "int16", DevFmtShort
},
3940 { "uint16", DevFmtUShort
},
3941 { "int32", DevFmtInt
},
3942 { "uint32", DevFmtUInt
},
3943 { "float32", DevFmtFloat
},
3947 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3949 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3951 device
->FmtType
= typelist
[i
].type
;
3952 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3956 if(i
== COUNTOF(typelist
))
3957 ERR("Unsupported sample-type: %s\n", fmt
);
3960 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3962 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3963 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3964 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3965 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3968 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3969 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3971 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3972 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3973 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3974 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3976 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
3977 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
3979 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3980 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
3982 if(ConfigValueInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
))
3983 device
->NumAuxSends
= clampi(
3984 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
3987 device
->NumStereoSources
= 1;
3988 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
3990 // Find a playback device to open
3991 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3993 DELETE_OBJ(device
->Backend
);
3995 alcSetError(NULL
, err
);
3998 almtx_init(&device
->BackendLock
, almtx_plain
);
4000 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "ambi-format", &fmt
))
4002 if(strcasecmp(fmt
, "fuma") == 0)
4004 device
->AmbiLayout
= AmbiLayout_FuMa
;
4005 device
->AmbiScale
= AmbiNorm_FuMa
;
4007 else if(strcasecmp(fmt
, "acn+sn3d") == 0)
4009 device
->AmbiLayout
= AmbiLayout_ACN
;
4010 device
->AmbiScale
= AmbiNorm_SN3D
;
4012 else if(strcasecmp(fmt
, "acn+n3d") == 0)
4014 device
->AmbiLayout
= AmbiLayout_ACN
;
4015 device
->AmbiScale
= AmbiNorm_N3D
;
4018 ERR("Unsupported ambi-format: %s\n", fmt
);
4021 device
->Limiter
= CreateDeviceLimiter(device
);
4023 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
4025 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
4026 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
4028 device
->DefaultSlot
= NULL
;
4029 ERR("Failed to initialize the default effect slot\n");
4033 aluInitEffectPanning(device
->DefaultSlot
);
4034 if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
4036 DeinitEffectSlot(device
->DefaultSlot
);
4037 device
->DefaultSlot
= NULL
;
4038 ERR("Failed to initialize the default effect\n");
4044 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4046 device
->next
= head
;
4047 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4050 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4056 * Closes the given device.
4058 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
4060 ALCdevice
*iter
, *origdev
;
4064 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4068 } while((iter
=iter
->next
) != NULL
);
4069 if(!iter
|| iter
->Type
== Capture
)
4071 alcSetError(iter
, ALC_INVALID_DEVICE
);
4075 almtx_lock(&device
->BackendLock
);
4078 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4080 ALCdevice
*volatile*list
= &origdev
->next
;
4085 *list
= (*list
)->next
;
4088 list
= &(*list
)->next
;
4093 ctx
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
4096 ALCcontext
*next
= ctx
->next
;
4097 WARN("Releasing context %p\n", ctx
);
4098 ReleaseContext(ctx
, device
);
4101 if((device
->Flags
&DEVICE_RUNNING
))
4102 V0(device
->Backend
,stop
)();
4103 device
->Flags
&= ~DEVICE_RUNNING
;
4104 almtx_unlock(&device
->BackendLock
);
4106 ALCdevice_DecRef(device
);
4112 /************************************************
4113 * ALC capture functions
4114 ************************************************/
4115 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
4117 ALCbackendFactory
*factory
;
4118 ALCdevice
*device
= NULL
;
4124 if(!CaptureBackend
.name
)
4126 alcSetError(NULL
, ALC_INVALID_VALUE
);
4132 alcSetError(NULL
, ALC_INVALID_VALUE
);
4136 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
4139 device
= al_calloc(16, sizeof(ALCdevice
));
4142 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4147 InitRef(&device
->ref
, 1);
4148 device
->Connected
= ALC_TRUE
;
4149 device
->Type
= Capture
;
4151 device
->Hrtf
= NULL
;
4152 device
->HrtfHandle
= NULL
;
4153 VECTOR_INIT(device
->HrtfList
);
4154 AL_STRING_INIT(device
->HrtfName
);
4156 AL_STRING_INIT(device
->DeviceName
);
4157 device
->Dry
.Buffer
= NULL
;
4158 device
->Dry
.NumChannels
= 0;
4159 device
->FOAOut
.Buffer
= NULL
;
4160 device
->FOAOut
.NumChannels
= 0;
4161 device
->RealOut
.Buffer
= NULL
;
4162 device
->RealOut
.NumChannels
= 0;
4164 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4165 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4166 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4168 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4170 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4171 device
->ChannelDelay
[i
].Length
= 0;
4172 device
->ChannelDelay
[i
].Buffer
= NULL
;
4175 factory
= CaptureBackend
.getFactory();
4176 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
4177 if(!device
->Backend
)
4180 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4184 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4185 device
->Frequency
= frequency
;
4187 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
4188 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
4191 alcSetError(NULL
, ALC_INVALID_ENUM
);
4194 device
->IsHeadphones
= AL_FALSE
;
4195 device
->AmbiOrder
= 0;
4196 device
->AmbiLayout
= AmbiLayout_Default
;
4197 device
->AmbiScale
= AmbiNorm_Default
;
4199 device
->UpdateSize
= samples
;
4200 device
->NumUpdates
= 1;
4202 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4203 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
4204 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
4206 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4209 alcSetError(NULL
, err
);
4212 almtx_init(&device
->BackendLock
, almtx_plain
);
4215 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4217 device
->next
= head
;
4218 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4221 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4225 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
4227 ALCdevice
*iter
, *origdev
;
4230 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4234 } while((iter
=iter
->next
) != NULL
);
4235 if(!iter
|| iter
->Type
!= Capture
)
4237 alcSetError(iter
, ALC_INVALID_DEVICE
);
4243 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4245 ALCdevice
*volatile*list
= &origdev
->next
;
4250 *list
= (*list
)->next
;
4253 list
= &(*list
)->next
;
4258 ALCdevice_DecRef(device
);
4263 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
4265 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4266 alcSetError(device
, ALC_INVALID_DEVICE
);
4269 almtx_lock(&device
->BackendLock
);
4270 if(!device
->Connected
)
4271 alcSetError(device
, ALC_INVALID_DEVICE
);
4272 else if(!(device
->Flags
&DEVICE_RUNNING
))
4274 if(V0(device
->Backend
,start
)())
4275 device
->Flags
|= DEVICE_RUNNING
;
4278 aluHandleDisconnect(device
);
4279 alcSetError(device
, ALC_INVALID_DEVICE
);
4282 almtx_unlock(&device
->BackendLock
);
4285 if(device
) ALCdevice_DecRef(device
);
4288 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
4290 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4291 alcSetError(device
, ALC_INVALID_DEVICE
);
4294 almtx_lock(&device
->BackendLock
);
4295 if((device
->Flags
&DEVICE_RUNNING
))
4296 V0(device
->Backend
,stop
)();
4297 device
->Flags
&= ~DEVICE_RUNNING
;
4298 almtx_unlock(&device
->BackendLock
);
4301 if(device
) ALCdevice_DecRef(device
);
4304 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4306 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4307 alcSetError(device
, ALC_INVALID_DEVICE
);
4310 ALCenum err
= ALC_INVALID_VALUE
;
4312 almtx_lock(&device
->BackendLock
);
4313 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
4314 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
4315 almtx_unlock(&device
->BackendLock
);
4317 if(err
!= ALC_NO_ERROR
)
4318 alcSetError(device
, err
);
4320 if(device
) ALCdevice_DecRef(device
);
4324 /************************************************
4325 * ALC loopback functions
4326 ************************************************/
4328 /* alcLoopbackOpenDeviceSOFT
4330 * Open a loopback device, for manual rendering.
4332 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
4334 ALCbackendFactory
*factory
;
4340 /* Make sure the device name, if specified, is us. */
4341 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
4343 alcSetError(NULL
, ALC_INVALID_VALUE
);
4347 device
= al_calloc(16, sizeof(ALCdevice
));
4350 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4355 InitRef(&device
->ref
, 1);
4356 device
->Connected
= ALC_TRUE
;
4357 device
->Type
= Loopback
;
4358 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
4361 device
->Hrtf
= NULL
;
4362 device
->HrtfHandle
= NULL
;
4363 VECTOR_INIT(device
->HrtfList
);
4364 AL_STRING_INIT(device
->HrtfName
);
4365 device
->Bs2b
= NULL
;
4366 device
->Uhj_Encoder
= NULL
;
4367 device
->Render_Mode
= NormalRender
;
4368 AL_STRING_INIT(device
->DeviceName
);
4369 device
->Dry
.Buffer
= NULL
;
4370 device
->Dry
.NumChannels
= 0;
4371 device
->FOAOut
.Buffer
= NULL
;
4372 device
->FOAOut
.NumChannels
= 0;
4373 device
->RealOut
.Buffer
= NULL
;
4374 device
->RealOut
.NumChannels
= 0;
4375 device
->Limiter
= NULL
;
4376 device
->AvgSpeakerDist
= 0.0f
;
4378 ATOMIC_INIT(&device
->ContextList
, NULL
);
4380 device
->ClockBase
= 0;
4381 device
->SamplesDone
= 0;
4383 device
->SourcesMax
= 256;
4384 device
->AuxiliaryEffectSlotMax
= 64;
4385 device
->NumAuxSends
= DEFAULT_SENDS
;
4387 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4388 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4389 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4391 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4393 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4394 device
->ChannelDelay
[i
].Length
= 0;
4395 device
->ChannelDelay
[i
].Buffer
= NULL
;
4398 factory
= ALCloopbackFactory_getFactory();
4399 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
4400 if(!device
->Backend
)
4403 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4406 almtx_init(&device
->BackendLock
, almtx_plain
);
4409 device
->NumUpdates
= 0;
4410 device
->UpdateSize
= 0;
4412 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
4413 device
->FmtChans
= DevFmtChannelsDefault
;
4414 device
->FmtType
= DevFmtTypeDefault
;
4415 device
->IsHeadphones
= AL_FALSE
;
4416 device
->AmbiLayout
= AmbiLayout_Default
;
4417 device
->AmbiScale
= AmbiNorm_Default
;
4419 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
4420 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4422 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4423 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4425 if(ConfigValueInt(NULL
, NULL
, "sends", &device
->NumAuxSends
))
4426 device
->NumAuxSends
= clampi(
4427 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4430 device
->NumStereoSources
= 1;
4431 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4433 // Open the "backend"
4434 V(device
->Backend
,open
)("Loopback");
4436 device
->Limiter
= CreateDeviceLimiter(device
);
4439 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4441 device
->next
= head
;
4442 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4445 TRACE("Created device %p\n", device
);
4449 /* alcIsRenderFormatSupportedSOFT
4451 * Determines if the loopback device supports the given format for rendering.
4453 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
4455 ALCboolean ret
= ALC_FALSE
;
4457 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4458 alcSetError(device
, ALC_INVALID_DEVICE
);
4460 alcSetError(device
, ALC_INVALID_VALUE
);
4463 if(IsValidALCType(type
) && IsValidALCChannels(channels
) && freq
>= MIN_OUTPUT_RATE
)
4466 if(device
) ALCdevice_DecRef(device
);
4471 /* alcRenderSamplesSOFT
4473 * Renders some samples into a buffer, using the format last set by the
4474 * attributes given to alcCreateContext.
4476 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4478 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4479 alcSetError(device
, ALC_INVALID_DEVICE
);
4480 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
4481 alcSetError(device
, ALC_INVALID_VALUE
);
4484 V0(device
->Backend
,lock
)();
4485 aluMixData(device
, buffer
, samples
);
4486 V0(device
->Backend
,unlock
)();
4488 if(device
) ALCdevice_DecRef(device
);
4492 /************************************************
4493 * ALC loopback2 functions
4494 ************************************************/
4496 ALC_API ALCboolean ALC_APIENTRY
alcIsAmbisonicFormatSupportedSOFT(ALCdevice
*device
, ALCenum layout
, ALCenum scaling
, ALsizei order
)
4498 ALCboolean ret
= ALC_FALSE
;
4500 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4501 alcSetError(device
, ALC_INVALID_DEVICE
);
4503 alcSetError(device
, ALC_INVALID_VALUE
);
4506 if(IsValidAmbiLayout(layout
) && IsValidAmbiScaling(scaling
) && order
<= MAX_AMBI_ORDER
)
4509 if(device
) ALCdevice_DecRef(device
);
4514 /************************************************
4515 * ALC DSP pause/resume functions
4516 ************************************************/
4518 /* alcDevicePauseSOFT
4520 * Pause the DSP to stop audio processing.
4522 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
4524 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4525 alcSetError(device
, ALC_INVALID_DEVICE
);
4528 almtx_lock(&device
->BackendLock
);
4529 if((device
->Flags
&DEVICE_RUNNING
))
4530 V0(device
->Backend
,stop
)();
4531 device
->Flags
&= ~DEVICE_RUNNING
;
4532 device
->Flags
|= DEVICE_PAUSED
;
4533 almtx_unlock(&device
->BackendLock
);
4535 if(device
) ALCdevice_DecRef(device
);
4538 /* alcDeviceResumeSOFT
4540 * Resume the DSP to restart audio processing.
4542 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
4544 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4545 alcSetError(device
, ALC_INVALID_DEVICE
);
4548 almtx_lock(&device
->BackendLock
);
4549 if((device
->Flags
&DEVICE_PAUSED
))
4551 device
->Flags
&= ~DEVICE_PAUSED
;
4552 if(ATOMIC_LOAD_SEQ(&device
->ContextList
) != NULL
)
4554 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4555 device
->Flags
|= DEVICE_RUNNING
;
4558 alcSetError(device
, ALC_INVALID_DEVICE
);
4559 V0(device
->Backend
,lock
)();
4560 aluHandleDisconnect(device
);
4561 V0(device
->Backend
,unlock
)();
4565 almtx_unlock(&device
->BackendLock
);
4567 if(device
) ALCdevice_DecRef(device
);
4571 /************************************************
4572 * ALC HRTF functions
4573 ************************************************/
4575 /* alcGetStringiSOFT
4577 * Gets a string parameter at the given index.
4579 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4581 const ALCchar
*str
= NULL
;
4583 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4584 alcSetError(device
, ALC_INVALID_DEVICE
);
4585 else switch(paramName
)
4587 case ALC_HRTF_SPECIFIER_SOFT
:
4588 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->HrtfList
))
4589 str
= alstr_get_cstr(VECTOR_ELEM(device
->HrtfList
, index
).name
);
4591 alcSetError(device
, ALC_INVALID_VALUE
);
4595 alcSetError(device
, ALC_INVALID_ENUM
);
4598 if(device
) ALCdevice_DecRef(device
);
4603 /* alcResetDeviceSOFT
4605 * Resets the given device output, using the specified attribute list.
4607 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4612 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4615 alcSetError(device
, ALC_INVALID_DEVICE
);
4616 if(device
) ALCdevice_DecRef(device
);
4619 almtx_lock(&device
->BackendLock
);
4622 err
= UpdateDeviceParams(device
, attribs
);
4623 almtx_unlock(&device
->BackendLock
);
4625 if(err
!= ALC_NO_ERROR
)
4627 alcSetError(device
, err
);
4628 if(err
== ALC_INVALID_DEVICE
)
4630 V0(device
->Backend
,lock
)();
4631 aluHandleDisconnect(device
);
4632 V0(device
->Backend
,unlock
)();
4634 ALCdevice_DecRef(device
);
4637 ALCdevice_DecRef(device
);