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
;
1748 // Check for attributes
1749 if(device
->Type
== Loopback
)
1751 ALCsizei numMono
, numStereo
, numSends
;
1752 ALCenum alayout
= AL_NONE
;
1753 ALCenum ascale
= AL_NONE
;
1754 ALCenum schans
= AL_NONE
;
1755 ALCenum stype
= AL_NONE
;
1756 ALCsizei attrIdx
= 0;
1757 ALCsizei aorder
= 0;
1762 WARN("Missing attributes for loopback device\n");
1763 return ALC_INVALID_VALUE
;
1766 numMono
= device
->NumMonoSources
;
1767 numStereo
= device
->NumStereoSources
;
1768 numSends
= old_sends
;
1770 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1771 while(attrList
[attrIdx
])
1773 switch(attrList
[attrIdx
])
1775 case ALC_FORMAT_CHANNELS_SOFT
:
1776 schans
= attrList
[attrIdx
+ 1];
1777 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT
, schans
);
1778 if(!IsValidALCChannels(schans
))
1779 return ALC_INVALID_VALUE
;
1782 case ALC_FORMAT_TYPE_SOFT
:
1783 stype
= attrList
[attrIdx
+ 1];
1784 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT
, stype
);
1785 if(!IsValidALCType(stype
))
1786 return ALC_INVALID_VALUE
;
1790 freq
= attrList
[attrIdx
+ 1];
1791 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1792 if(freq
< MIN_OUTPUT_RATE
)
1793 return ALC_INVALID_VALUE
;
1796 case ALC_AMBISONIC_LAYOUT_SOFT
:
1797 alayout
= attrList
[attrIdx
+ 1];
1798 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT
, alayout
);
1799 if(!IsValidAmbiLayout(alayout
))
1800 return ALC_INVALID_VALUE
;
1803 case ALC_AMBISONIC_SCALING_SOFT
:
1804 ascale
= attrList
[attrIdx
+ 1];
1805 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT
, ascale
);
1806 if(!IsValidAmbiScaling(ascale
))
1807 return ALC_INVALID_VALUE
;
1810 case ALC_AMBISONIC_ORDER_SOFT
:
1811 aorder
= attrList
[attrIdx
+ 1];
1812 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT
, aorder
);
1813 if(aorder
< 1 || aorder
> MAX_AMBI_ORDER
)
1814 return ALC_INVALID_VALUE
;
1817 case ALC_MONO_SOURCES
:
1818 numMono
= attrList
[attrIdx
+ 1];
1819 TRACE_ATTR(ALC_MONO_SOURCES
, numMono
);
1820 numMono
= maxi(numMono
, 0);
1823 case ALC_STEREO_SOURCES
:
1824 numStereo
= attrList
[attrIdx
+ 1];
1825 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1826 numStereo
= maxi(numStereo
, 0);
1829 case ALC_MAX_AUXILIARY_SENDS
:
1830 numSends
= attrList
[attrIdx
+ 1];
1831 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1832 numSends
= clampi(numSends
, 0, MAX_SENDS
);
1836 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1837 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1838 hrtf_appreq
= Hrtf_Disable
;
1839 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1840 hrtf_appreq
= Hrtf_Enable
;
1842 hrtf_appreq
= Hrtf_Default
;
1845 case ALC_HRTF_ID_SOFT
:
1846 hrtf_id
= attrList
[attrIdx
+ 1];
1847 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1850 case ALC_OUTPUT_LIMITER_SOFT
:
1851 gainLimiter
= attrList
[attrIdx
+ 1];
1852 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT
, gainLimiter
);
1856 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList
[attrIdx
],
1857 attrList
[attrIdx
+ 1], attrList
[attrIdx
+ 1]);
1865 if(!schans
|| !stype
|| !freq
)
1867 WARN("Missing format for loopback device\n");
1868 return ALC_INVALID_VALUE
;
1870 if(schans
== ALC_BFORMAT3D_SOFT
&& (!alayout
|| !ascale
|| !aorder
))
1872 WARN("Missing ambisonic info for loopback device\n");
1873 return ALC_INVALID_VALUE
;
1876 if((device
->Flags
&DEVICE_RUNNING
))
1877 V0(device
->Backend
,stop
)();
1878 device
->Flags
&= ~DEVICE_RUNNING
;
1880 UpdateClockBase(device
);
1882 device
->Frequency
= freq
;
1883 device
->FmtChans
= schans
;
1884 device
->FmtType
= stype
;
1885 if(schans
== ALC_BFORMAT3D_SOFT
)
1887 device
->AmbiOrder
= aorder
;
1888 device
->AmbiLayout
= alayout
;
1889 device
->AmbiScale
= ascale
;
1892 if(numMono
> INT_MAX
-numStereo
)
1893 numMono
= INT_MAX
-numStereo
;
1894 numMono
+= numStereo
;
1895 if(ConfigValueInt(NULL
, NULL
, "sources", &numMono
))
1901 numMono
= maxi(numMono
, 256);
1902 numStereo
= mini(numStereo
, numMono
);
1903 numMono
-= numStereo
;
1904 device
->SourcesMax
= numMono
+ numStereo
;
1906 device
->NumMonoSources
= numMono
;
1907 device
->NumStereoSources
= numStereo
;
1909 if(ConfigValueInt(NULL
, NULL
, "sends", &new_sends
))
1910 new_sends
= mini(numSends
, clampi(new_sends
, 0, MAX_SENDS
));
1912 new_sends
= numSends
;
1914 else if(attrList
&& attrList
[0])
1916 ALCsizei numMono
, numStereo
, numSends
;
1917 ALCsizei attrIdx
= 0;
1920 /* If a context is already running on the device, stop playback so the
1921 * device attributes can be updated. */
1922 if((device
->Flags
&DEVICE_RUNNING
))
1923 V0(device
->Backend
,stop
)();
1924 device
->Flags
&= ~DEVICE_RUNNING
;
1926 UpdateClockBase(device
);
1928 freq
= device
->Frequency
;
1929 numMono
= device
->NumMonoSources
;
1930 numStereo
= device
->NumStereoSources
;
1931 numSends
= old_sends
;
1933 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1934 while(attrList
[attrIdx
])
1936 switch(attrList
[attrIdx
])
1939 freq
= attrList
[attrIdx
+ 1];
1940 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1941 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1944 case ALC_MONO_SOURCES
:
1945 numMono
= attrList
[attrIdx
+ 1];
1946 TRACE_ATTR(ALC_MONO_SOURCES
, numMono
);
1947 numMono
= maxi(numMono
, 0);
1950 case ALC_STEREO_SOURCES
:
1951 numStereo
= attrList
[attrIdx
+ 1];
1952 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1953 numStereo
= maxi(numStereo
, 0);
1956 case ALC_MAX_AUXILIARY_SENDS
:
1957 numSends
= attrList
[attrIdx
+ 1];
1958 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1959 numSends
= clampi(numSends
, 0, MAX_SENDS
);
1963 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1964 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1965 hrtf_appreq
= Hrtf_Disable
;
1966 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1967 hrtf_appreq
= Hrtf_Enable
;
1969 hrtf_appreq
= Hrtf_Default
;
1972 case ALC_HRTF_ID_SOFT
:
1973 hrtf_id
= attrList
[attrIdx
+ 1];
1974 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1977 case ALC_OUTPUT_LIMITER_SOFT
:
1978 gainLimiter
= attrList
[attrIdx
+ 1];
1979 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT
, gainLimiter
);
1983 TRACE("0x%04X = %d (0x%x)\n", attrList
[attrIdx
],
1984 attrList
[attrIdx
+ 1], attrList
[attrIdx
+ 1]);
1992 ConfigValueUInt(alstr_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1993 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1995 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1997 /* SSE and Neon do best with the update size being a multiple of 4 */
1998 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1999 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
2001 device
->Frequency
= freq
;
2003 if(numMono
> INT_MAX
-numStereo
)
2004 numMono
= INT_MAX
-numStereo
;
2005 numMono
+= numStereo
;
2006 if(ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "sources", &numMono
))
2012 numMono
= maxi(numMono
, 256);
2013 numStereo
= mini(numStereo
, numMono
);
2014 numMono
-= numStereo
;
2015 device
->SourcesMax
= numMono
+ numStereo
;
2017 device
->NumMonoSources
= numMono
;
2018 device
->NumStereoSources
= numStereo
;
2020 if(ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "sends", &new_sends
))
2021 new_sends
= mini(numSends
, clampi(new_sends
, 0, MAX_SENDS
));
2023 new_sends
= numSends
;
2026 if((device
->Flags
&DEVICE_RUNNING
))
2027 return ALC_NO_ERROR
;
2029 al_free(device
->Uhj_Encoder
);
2030 device
->Uhj_Encoder
= NULL
;
2032 al_free(device
->Bs2b
);
2033 device
->Bs2b
= NULL
;
2035 al_free(device
->ChannelDelay
[0].Buffer
);
2036 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
2038 device
->ChannelDelay
[i
].Length
= 0;
2039 device
->ChannelDelay
[i
].Buffer
= NULL
;
2042 al_free(device
->Dry
.Buffer
);
2043 device
->Dry
.Buffer
= NULL
;
2044 device
->Dry
.NumChannels
= 0;
2045 device
->FOAOut
.Buffer
= NULL
;
2046 device
->FOAOut
.NumChannels
= 0;
2047 device
->RealOut
.Buffer
= NULL
;
2048 device
->RealOut
.NumChannels
= 0;
2050 UpdateClockBase(device
);
2052 device
->DitherSeed
= DITHER_RNG_SEED
;
2054 /*************************************************************************
2055 * Update device format request if HRTF is requested
2057 device
->HrtfStatus
= ALC_HRTF_DISABLED_SOFT
;
2058 if(device
->Type
!= Loopback
)
2061 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
2063 if(strcasecmp(hrtf
, "true") == 0)
2064 hrtf_userreq
= Hrtf_Enable
;
2065 else if(strcasecmp(hrtf
, "false") == 0)
2066 hrtf_userreq
= Hrtf_Disable
;
2067 else if(strcasecmp(hrtf
, "auto") != 0)
2068 ERR("Unexpected hrtf value: %s\n", hrtf
);
2071 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
2073 struct Hrtf
*hrtf
= NULL
;
2074 if(VECTOR_SIZE(device
->HrtfList
) == 0)
2076 VECTOR_DEINIT(device
->HrtfList
);
2077 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
2079 if(VECTOR_SIZE(device
->HrtfList
) > 0)
2081 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->HrtfList
))
2082 hrtf
= GetLoadedHrtf(VECTOR_ELEM(device
->HrtfList
, hrtf_id
).hrtf
);
2084 hrtf
= GetLoadedHrtf(VECTOR_ELEM(device
->HrtfList
, 0).hrtf
);
2089 device
->FmtChans
= DevFmtStereo
;
2090 device
->Frequency
= hrtf
->sampleRate
;
2091 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
2092 if(device
->HrtfHandle
)
2093 Hrtf_DecRef(device
->HrtfHandle
);
2094 device
->HrtfHandle
= hrtf
;
2098 hrtf_userreq
= Hrtf_Default
;
2099 hrtf_appreq
= Hrtf_Disable
;
2100 device
->HrtfStatus
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2105 oldFreq
= device
->Frequency
;
2106 oldChans
= device
->FmtChans
;
2107 oldType
= device
->FmtType
;
2109 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2110 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
2111 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
2112 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
2113 device
->UpdateSize
, device
->NumUpdates
2116 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
2117 return ALC_INVALID_DEVICE
;
2119 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
2121 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
2122 DevFmtChannelsString(device
->FmtChans
));
2123 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
2125 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
2127 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
2128 DevFmtTypeString(device
->FmtType
));
2129 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
2131 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
2133 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
2134 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
2137 if((device
->UpdateSize
&3) != 0)
2139 if((CPUCapFlags
&CPU_CAP_SSE
))
2140 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2141 if((CPUCapFlags
&CPU_CAP_NEON
))
2142 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2145 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2146 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
2147 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
2150 aluInitRenderer(device
, hrtf_id
, hrtf_appreq
, hrtf_userreq
);
2151 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device
->Dry
.NumChannels
,
2152 device
->FOAOut
.NumChannels
, device
->RealOut
.NumChannels
);
2154 /* Allocate extra channels for any post-filter output. */
2155 size
= (device
->Dry
.NumChannels
+ device
->FOAOut
.NumChannels
+
2156 device
->RealOut
.NumChannels
)*sizeof(device
->Dry
.Buffer
[0]);
2158 TRACE("Allocating "SZFMT
" channels, "SZFMT
" bytes\n", size
/sizeof(device
->Dry
.Buffer
[0]), size
);
2159 device
->Dry
.Buffer
= al_calloc(16, size
);
2160 if(!device
->Dry
.Buffer
)
2162 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2163 return ALC_INVALID_DEVICE
;
2166 if(device
->RealOut
.NumChannels
!= 0)
2167 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
+
2168 device
->FOAOut
.NumChannels
;
2171 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2172 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2175 if(device
->FOAOut
.NumChannels
!= 0)
2176 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2179 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
;
2180 device
->FOAOut
.NumChannels
= device
->Dry
.NumChannels
;
2183 device
->NumAuxSends
= new_sends
;
2184 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2185 device
->SourcesMax
, device
->NumMonoSources
, device
->NumStereoSources
,
2186 device
->AuxiliaryEffectSlotMax
, device
->NumAuxSends
);
2188 device
->DitherDepth
= 0.0f
;
2189 if(GetConfigValueBool(alstr_get_cstr(device
->DeviceName
), NULL
, "dither", 1))
2192 ConfigValueInt(alstr_get_cstr(device
->DeviceName
), NULL
, "dither-depth", &depth
);
2195 switch(device
->FmtType
)
2213 device
->DitherDepth
= (depth
> 0) ? powf(2.0f
, (ALfloat
)(depth
-1)) : 0.0f
;
2215 if(!(device
->DitherDepth
> 0.0f
))
2216 TRACE("Dithering disabled\n");
2218 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device
->DitherDepth
)+1.0f
,
2219 device
->DitherDepth
);
2221 if(ConfigValueBool(alstr_get_cstr(device
->DeviceName
), NULL
, "output-limiter", &val
))
2222 gainLimiter
= val
? ALC_TRUE
: ALC_FALSE
;
2223 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2224 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2227 if(gainLimiter
!= ALC_FALSE
)
2229 if(!device
->Limiter
|| device
->Frequency
!= GetCompressorSampleRate(device
->Limiter
))
2231 al_free(device
->Limiter
);
2232 device
->Limiter
= CreateDeviceLimiter(device
);
2237 al_free(device
->Limiter
);
2238 device
->Limiter
= NULL
;
2240 TRACE("Output limiter %s\n", device
->Limiter
? "enabled" : "disabled");
2242 /* Need to delay returning failure until replacement Send arrays have been
2243 * allocated with the appropriate size.
2245 update_failed
= AL_FALSE
;
2247 context
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
2252 if(context
->DefaultSlot
)
2254 ALeffectslot
*slot
= context
->DefaultSlot
;
2255 ALeffectState
*state
= slot
->Effect
.State
;
2257 state
->OutBuffer
= device
->Dry
.Buffer
;
2258 state
->OutChannels
= device
->Dry
.NumChannels
;
2259 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2260 update_failed
= AL_TRUE
;
2262 UpdateEffectSlotProps(slot
);
2265 WriteLock(&context
->PropLock
);
2266 LockUIntMapRead(&context
->EffectSlotMap
);
2267 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2269 ALeffectslot
*slot
= context
->EffectSlotMap
.values
[pos
];
2270 ALeffectState
*state
= slot
->Effect
.State
;
2272 state
->OutBuffer
= device
->Dry
.Buffer
;
2273 state
->OutChannels
= device
->Dry
.NumChannels
;
2274 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2275 update_failed
= AL_TRUE
;
2277 UpdateEffectSlotProps(slot
);
2279 UnlockUIntMapRead(&context
->EffectSlotMap
);
2281 LockUIntMapRead(&context
->SourceMap
);
2282 RelimitUIntMapNoLock(&context
->SourceMap
, device
->SourcesMax
);
2283 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2285 ALsource
*source
= context
->SourceMap
.values
[pos
];
2287 if(old_sends
!= device
->NumAuxSends
)
2289 ALvoid
*sends
= al_calloc(16, device
->NumAuxSends
*sizeof(source
->Send
[0]));
2292 memcpy(sends
, source
->Send
,
2293 mini(device
->NumAuxSends
, old_sends
)*sizeof(source
->Send
[0])
2295 for(s
= device
->NumAuxSends
;s
< old_sends
;s
++)
2297 if(source
->Send
[s
].Slot
)
2298 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2299 source
->Send
[s
].Slot
= NULL
;
2301 al_free(source
->Send
);
2302 source
->Send
= sends
;
2303 for(s
= old_sends
;s
< device
->NumAuxSends
;s
++)
2305 source
->Send
[s
].Slot
= NULL
;
2306 source
->Send
[s
].Gain
= 1.0f
;
2307 source
->Send
[s
].GainHF
= 1.0f
;
2308 source
->Send
[s
].HFReference
= LOWPASSFREQREF
;
2309 source
->Send
[s
].GainLF
= 1.0f
;
2310 source
->Send
[s
].LFReference
= HIGHPASSFREQREF
;
2314 ATOMIC_FLAG_CLEAR(&source
->PropsClean
, almemory_order_release
);
2316 AllocateVoices(context
, context
->MaxVoices
, old_sends
);
2317 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2319 ALvoice
*voice
= context
->Voices
[pos
];
2320 struct ALvoiceProps
*props
;
2322 /* Clear any pre-existing voice property structs, in case the
2323 * number of auxiliary sends changed. Active sources will have
2324 * updates respecified in UpdateAllSourceProps.
2326 props
= ATOMIC_EXCHANGE_PTR(&voice
->Update
, NULL
, almemory_order_relaxed
);
2329 props
= ATOMIC_EXCHANGE_PTR(&voice
->FreeList
, NULL
, almemory_order_relaxed
);
2332 struct ALvoiceProps
*next
= ATOMIC_LOAD(&props
->next
, almemory_order_relaxed
);
2337 if(ATOMIC_LOAD(&voice
->Source
, almemory_order_acquire
) == NULL
)
2340 if(device
->AvgSpeakerDist
> 0.0f
)
2342 /* Reinitialize the NFC filters for new parameters. */
2343 ALfloat w1
= SPEEDOFSOUNDMETRESPERSEC
/
2344 (device
->AvgSpeakerDist
* device
->Frequency
);
2345 for(i
= 0;i
< voice
->NumChannels
;i
++)
2347 NfcFilterCreate1(&voice
->Direct
.Params
[i
].NFCtrlFilter
[0], 0.0f
, w1
);
2348 NfcFilterCreate2(&voice
->Direct
.Params
[i
].NFCtrlFilter
[1], 0.0f
, w1
);
2349 NfcFilterCreate3(&voice
->Direct
.Params
[i
].NFCtrlFilter
[2], 0.0f
, w1
);
2353 UnlockUIntMapRead(&context
->SourceMap
);
2355 UpdateListenerProps(context
);
2356 UpdateAllSourceProps(context
);
2357 WriteUnlock(&context
->PropLock
);
2359 context
= context
->next
;
2363 return ALC_INVALID_DEVICE
;
2365 if(!(device
->Flags
&DEVICE_PAUSED
))
2367 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2368 return ALC_INVALID_DEVICE
;
2369 device
->Flags
|= DEVICE_RUNNING
;
2372 return ALC_NO_ERROR
;
2377 * Frees the device structure, and destroys any objects the app failed to
2378 * delete. Called once there's no more references on the device.
2380 static ALCvoid
FreeDevice(ALCdevice
*device
)
2384 TRACE("%p\n", device
);
2386 V0(device
->Backend
,close
)();
2387 DELETE_OBJ(device
->Backend
);
2388 device
->Backend
= NULL
;
2390 almtx_destroy(&device
->BackendLock
);
2392 if(device
->BufferMap
.size
> 0)
2394 WARN("(%p) Deleting %d Buffer%s\n", device
, device
->BufferMap
.size
,
2395 (device
->BufferMap
.size
==1)?"":"s");
2396 ReleaseALBuffers(device
);
2398 ResetUIntMap(&device
->BufferMap
);
2400 if(device
->EffectMap
.size
> 0)
2402 WARN("(%p) Deleting %d Effect%s\n", device
, device
->EffectMap
.size
,
2403 (device
->EffectMap
.size
==1)?"":"s");
2404 ReleaseALEffects(device
);
2406 ResetUIntMap(&device
->EffectMap
);
2408 if(device
->FilterMap
.size
> 0)
2410 WARN("(%p) Deleting %d Filter%s\n", device
, device
->FilterMap
.size
,
2411 (device
->FilterMap
.size
==1)?"":"s");
2412 ReleaseALFilters(device
);
2414 ResetUIntMap(&device
->FilterMap
);
2416 AL_STRING_DEINIT(device
->HrtfName
);
2417 FreeHrtfList(&device
->HrtfList
);
2418 if(device
->HrtfHandle
)
2419 Hrtf_DecRef(device
->HrtfHandle
);
2420 device
->HrtfHandle
= NULL
;
2421 al_free(device
->Hrtf
);
2422 device
->Hrtf
= NULL
;
2424 al_free(device
->Bs2b
);
2425 device
->Bs2b
= NULL
;
2427 al_free(device
->Uhj_Encoder
);
2428 device
->Uhj_Encoder
= NULL
;
2430 bformatdec_free(device
->AmbiDecoder
);
2431 device
->AmbiDecoder
= NULL
;
2433 ambiup_free(device
->AmbiUp
);
2434 device
->AmbiUp
= NULL
;
2436 al_free(device
->Limiter
);
2437 device
->Limiter
= NULL
;
2439 al_free(device
->ChannelDelay
[0].Buffer
);
2440 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
2442 device
->ChannelDelay
[i
].Gain
= 1.0f
;
2443 device
->ChannelDelay
[i
].Length
= 0;
2444 device
->ChannelDelay
[i
].Buffer
= NULL
;
2447 AL_STRING_DEINIT(device
->DeviceName
);
2449 al_free(device
->Dry
.Buffer
);
2450 device
->Dry
.Buffer
= NULL
;
2451 device
->Dry
.NumChannels
= 0;
2452 device
->FOAOut
.Buffer
= NULL
;
2453 device
->FOAOut
.NumChannels
= 0;
2454 device
->RealOut
.Buffer
= NULL
;
2455 device
->RealOut
.NumChannels
= 0;
2461 void ALCdevice_IncRef(ALCdevice
*device
)
2464 ref
= IncrementRef(&device
->ref
);
2465 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2468 void ALCdevice_DecRef(ALCdevice
*device
)
2471 ref
= DecrementRef(&device
->ref
);
2472 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2473 if(ref
== 0) FreeDevice(device
);
2478 * Checks if the device handle is valid, and increments its ref count if so.
2480 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2482 ALCdevice
*tmpDevice
;
2485 tmpDevice
= ATOMIC_LOAD_SEQ(&DeviceList
);
2488 if(tmpDevice
== *device
)
2490 ALCdevice_IncRef(tmpDevice
);
2494 tmpDevice
= tmpDevice
->next
;
2505 * Initializes context fields
2507 static ALvoid
InitContext(ALCcontext
*Context
)
2509 ALlistener
*listener
= Context
->Listener
;
2510 struct ALeffectslotArray
*auxslots
;
2512 //Initialise listener
2513 listener
->Gain
= 1.0f
;
2514 listener
->MetersPerUnit
= 1.0f
;
2515 listener
->Position
[0] = 0.0f
;
2516 listener
->Position
[1] = 0.0f
;
2517 listener
->Position
[2] = 0.0f
;
2518 listener
->Velocity
[0] = 0.0f
;
2519 listener
->Velocity
[1] = 0.0f
;
2520 listener
->Velocity
[2] = 0.0f
;
2521 listener
->Forward
[0] = 0.0f
;
2522 listener
->Forward
[1] = 0.0f
;
2523 listener
->Forward
[2] = -1.0f
;
2524 listener
->Up
[0] = 0.0f
;
2525 listener
->Up
[1] = 1.0f
;
2526 listener
->Up
[2] = 0.0f
;
2528 aluMatrixfSet(&listener
->Params
.Matrix
,
2529 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2530 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2531 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2532 0.0f
, 0.0f
, 0.0f
, 1.0f
2534 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2535 listener
->Params
.Gain
= 1.0f
;
2536 listener
->Params
.MetersPerUnit
= 1.0f
;
2537 listener
->Params
.DopplerFactor
= 1.0f
;
2538 listener
->Params
.SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2540 ATOMIC_INIT(&listener
->Update
, NULL
);
2541 ATOMIC_INIT(&listener
->FreeList
, NULL
);
2544 InitRef(&Context
->UpdateCount
, 0);
2545 ATOMIC_INIT(&Context
->HoldUpdates
, AL_FALSE
);
2546 Context
->GainBoost
= 1.0f
;
2547 RWLockInit(&Context
->PropLock
);
2548 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2549 InitUIntMap(&Context
->SourceMap
, Context
->Device
->SourcesMax
);
2550 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2552 auxslots
= al_calloc(DEF_ALIGN
, sizeof(struct ALeffectslotArray
));
2553 auxslots
->count
= 0;
2554 ATOMIC_INIT(&Context
->ActiveAuxSlots
, auxslots
);
2557 Context
->DistanceModel
= DefaultDistanceModel
;
2558 Context
->SourceDistanceModel
= AL_FALSE
;
2559 Context
->DopplerFactor
= 1.0f
;
2560 Context
->DopplerVelocity
= 1.0f
;
2561 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2562 ATOMIC_INIT(&Context
->DeferUpdates
, AL_FALSE
);
2564 Context
->ExtensionList
= alExtList
;
2570 * Cleans up the context, and destroys any remaining objects the app failed to
2571 * delete. Called once there's no more references on the context.
2573 static void FreeContext(ALCcontext
*context
)
2575 ALlistener
*listener
= context
->Listener
;
2576 struct ALeffectslotArray
*auxslots
;
2577 struct ALlistenerProps
*lprops
;
2581 TRACE("%p\n", context
);
2583 if(context
->DefaultSlot
)
2585 DeinitEffectSlot(context
->DefaultSlot
);
2586 context
->DefaultSlot
= NULL
;
2589 auxslots
= ATOMIC_EXCHANGE_PTR(&context
->ActiveAuxSlots
, NULL
, almemory_order_relaxed
);
2592 if(context
->SourceMap
.size
> 0)
2594 WARN("(%p) Deleting %d Source%s\n", context
, context
->SourceMap
.size
,
2595 (context
->SourceMap
.size
==1)?"":"s");
2596 ReleaseALSources(context
);
2598 ResetUIntMap(&context
->SourceMap
);
2600 if(context
->EffectSlotMap
.size
> 0)
2602 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context
, context
->EffectSlotMap
.size
,
2603 (context
->EffectSlotMap
.size
==1)?"":"s");
2604 ReleaseALAuxiliaryEffectSlots(context
);
2606 ResetUIntMap(&context
->EffectSlotMap
);
2608 for(i
= 0;i
< context
->VoiceCount
;i
++)
2609 DeinitVoice(context
->Voices
[i
]);
2610 al_free(context
->Voices
);
2611 context
->Voices
= NULL
;
2612 context
->VoiceCount
= 0;
2613 context
->MaxVoices
= 0;
2615 if((lprops
=ATOMIC_LOAD(&listener
->Update
, almemory_order_acquire
)) != NULL
)
2617 TRACE("Freed unapplied listener update %p\n", lprops
);
2621 lprops
= ATOMIC_LOAD(&listener
->FreeList
, almemory_order_acquire
);
2624 struct ALlistenerProps
*next
= ATOMIC_LOAD(&lprops
->next
, almemory_order_acquire
);
2629 TRACE("Freed "SZFMT
" listener property object%s\n", count
, (count
==1)?"":"s");
2631 ALCdevice_DecRef(context
->Device
);
2632 context
->Device
= NULL
;
2634 //Invalidate context
2635 memset(context
, 0, sizeof(ALCcontext
));
2641 * Removes the context reference from the given device and removes it from
2642 * being current on the running thread or globally. Returns true if other
2643 * contexts still exist on the device.
2645 static bool ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2647 ALCcontext
*origctx
, *newhead
;
2650 if(altss_get(LocalContext
) == context
)
2652 WARN("%p released while current on thread\n", context
);
2653 altss_set(LocalContext
, NULL
);
2654 ALCcontext_DecRef(context
);
2658 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext
, &origctx
, NULL
))
2659 ALCcontext_DecRef(context
);
2661 ALCdevice_Lock(device
);
2663 newhead
= context
->next
;
2664 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device
->ContextList
, &origctx
, newhead
))
2666 ALCcontext
*volatile*list
= &origctx
->next
;
2669 if(*list
== context
)
2671 *list
= (*list
)->next
;
2674 list
= &(*list
)->next
;
2679 ALCdevice_Unlock(device
);
2681 ALCcontext_DecRef(context
);
2685 void ALCcontext_IncRef(ALCcontext
*context
)
2687 uint ref
= IncrementRef(&context
->ref
);
2688 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2691 void ALCcontext_DecRef(ALCcontext
*context
)
2693 uint ref
= DecrementRef(&context
->ref
);
2694 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2695 if(ref
== 0) FreeContext(context
);
2698 static void ReleaseThreadCtx(void *ptr
)
2700 ALCcontext
*context
= ptr
;
2701 uint ref
= DecrementRef(&context
->ref
);
2702 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2703 ERR("Context %p current for thread being destroyed, possible leak!\n", context
);
2708 * Checks that the given context is valid, and increments its reference count.
2710 static ALCboolean
VerifyContext(ALCcontext
**context
)
2715 dev
= ATOMIC_LOAD_SEQ(&DeviceList
);
2718 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
, almemory_order_acquire
);
2723 ALCcontext_IncRef(ctx
);
2740 * Returns the currently active context for this thread, and adds a reference
2741 * without locking it.
2743 ALCcontext
*GetContextRef(void)
2745 ALCcontext
*context
;
2747 context
= altss_get(LocalContext
);
2749 ALCcontext_IncRef(context
);
2753 context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
2755 ALCcontext_IncRef(context
);
2763 void AllocateVoices(ALCcontext
*context
, ALsizei num_voices
, ALsizei old_sends
)
2765 ALCdevice
*device
= context
->Device
;
2766 ALsizei num_sends
= device
->NumAuxSends
;
2767 struct ALvoiceProps
*props
;
2768 size_t sizeof_props
;
2769 size_t sizeof_voice
;
2775 if(num_voices
== context
->MaxVoices
&& num_sends
== old_sends
)
2778 /* Allocate the voice pointers, voices, and the voices' stored source
2779 * property set (including the dynamically-sized Send[] array) in one
2782 sizeof_voice
= RoundUp(FAM_SIZE(ALvoice
, Send
, num_sends
), 16);
2783 sizeof_props
= RoundUp(FAM_SIZE(struct ALvoiceProps
, Send
, num_sends
), 16);
2784 size
= sizeof(ALvoice
*) + sizeof_voice
+ sizeof_props
;
2786 voices
= al_calloc(16, RoundUp(size
*num_voices
, 16));
2787 /* The voice and property objects are stored interleaved since they're
2790 voice
= (ALvoice
*)((char*)voices
+ RoundUp(num_voices
*sizeof(ALvoice
*), 16));
2791 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2795 const ALsizei v_count
= mini(context
->VoiceCount
, num_voices
);
2796 const ALsizei s_count
= mini(old_sends
, num_sends
);
2798 for(;v
< v_count
;v
++)
2800 ALvoice
*old_voice
= context
->Voices
[v
];
2803 /* Copy the old voice data and source property set to the new
2806 *voice
= *old_voice
;
2807 for(i
= 0;i
< s_count
;i
++)
2808 voice
->Send
[i
] = old_voice
->Send
[i
];
2809 *props
= *(old_voice
->Props
);
2810 for(i
= 0;i
< s_count
;i
++)
2811 props
->Send
[i
] = old_voice
->Props
->Send
[i
];
2813 /* Set this voice's property set pointer and voice reference. */
2814 voice
->Props
= props
;
2817 /* Increment pointers to the next storage space. */
2818 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2819 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2821 /* Deinit any left over voices that weren't copied over to the new
2822 * array. NOTE: If this does anything, v equals num_voices and
2823 * num_voices is less than VoiceCount, so the following loop won't do
2826 for(;v
< context
->VoiceCount
;v
++)
2827 DeinitVoice(context
->Voices
[v
]);
2829 /* Finish setting the voices' property set pointers and references. */
2830 for(;v
< num_voices
;v
++)
2832 ATOMIC_INIT(&voice
->Update
, NULL
);
2833 ATOMIC_INIT(&voice
->FreeList
, NULL
);
2835 voice
->Props
= props
;
2838 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2839 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2842 al_free(context
->Voices
);
2843 context
->Voices
= voices
;
2844 context
->MaxVoices
= num_voices
;
2845 context
->VoiceCount
= mini(context
->VoiceCount
, num_voices
);
2849 /************************************************
2850 * Standard ALC functions
2851 ************************************************/
2855 * Return last ALC generated error code for the given device
2857 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2861 if(VerifyDevice(&device
))
2863 errorCode
= ATOMIC_EXCHANGE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
2864 ALCdevice_DecRef(device
);
2867 errorCode
= ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError
, ALC_NO_ERROR
);
2873 /* alcSuspendContext
2875 * Suspends updates for the given context
2877 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2882 if(!VerifyContext(&context
))
2883 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2886 ALCcontext_DeferUpdates(context
);
2887 ALCcontext_DecRef(context
);
2891 /* alcProcessContext
2893 * Resumes processing updates for the given context
2895 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2900 if(!VerifyContext(&context
))
2901 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2904 ALCcontext_ProcessUpdates(context
);
2905 ALCcontext_DecRef(context
);
2912 * Returns information about the device, and error strings
2914 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2916 const ALCchar
*value
= NULL
;
2924 case ALC_INVALID_ENUM
:
2925 value
= alcErrInvalidEnum
;
2928 case ALC_INVALID_VALUE
:
2929 value
= alcErrInvalidValue
;
2932 case ALC_INVALID_DEVICE
:
2933 value
= alcErrInvalidDevice
;
2936 case ALC_INVALID_CONTEXT
:
2937 value
= alcErrInvalidContext
;
2940 case ALC_OUT_OF_MEMORY
:
2941 value
= alcErrOutOfMemory
;
2944 case ALC_DEVICE_SPECIFIER
:
2945 value
= alcDefaultName
;
2948 case ALC_ALL_DEVICES_SPECIFIER
:
2949 if(VerifyDevice(&Device
))
2951 value
= alstr_get_cstr(Device
->DeviceName
);
2952 ALCdevice_DecRef(Device
);
2956 ProbeAllDevicesList();
2957 value
= alstr_get_cstr(alcAllDevicesList
);
2961 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2962 if(VerifyDevice(&Device
))
2964 value
= alstr_get_cstr(Device
->DeviceName
);
2965 ALCdevice_DecRef(Device
);
2969 ProbeCaptureDeviceList();
2970 value
= alstr_get_cstr(alcCaptureDeviceList
);
2974 /* Default devices are always first in the list */
2975 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2976 value
= alcDefaultName
;
2979 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2980 if(alstr_empty(alcAllDevicesList
))
2981 ProbeAllDevicesList();
2983 VerifyDevice(&Device
);
2985 free(alcDefaultAllDevicesSpecifier
);
2986 alcDefaultAllDevicesSpecifier
= strdup(alstr_get_cstr(alcAllDevicesList
));
2987 if(!alcDefaultAllDevicesSpecifier
)
2988 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2990 value
= alcDefaultAllDevicesSpecifier
;
2991 if(Device
) ALCdevice_DecRef(Device
);
2994 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2995 if(alstr_empty(alcCaptureDeviceList
))
2996 ProbeCaptureDeviceList();
2998 VerifyDevice(&Device
);
3000 free(alcCaptureDefaultDeviceSpecifier
);
3001 alcCaptureDefaultDeviceSpecifier
= strdup(alstr_get_cstr(alcCaptureDeviceList
));
3002 if(!alcCaptureDefaultDeviceSpecifier
)
3003 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
3005 value
= alcCaptureDefaultDeviceSpecifier
;
3006 if(Device
) ALCdevice_DecRef(Device
);
3009 case ALC_EXTENSIONS
:
3010 if(!VerifyDevice(&Device
))
3011 value
= alcNoDeviceExtList
;
3014 value
= alcExtensionList
;
3015 ALCdevice_DecRef(Device
);
3019 case ALC_HRTF_SPECIFIER_SOFT
:
3020 if(!VerifyDevice(&Device
))
3021 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3024 almtx_lock(&Device
->BackendLock
);
3025 value
= (Device
->HrtfHandle
? alstr_get_cstr(Device
->HrtfName
) : "");
3026 almtx_unlock(&Device
->BackendLock
);
3027 ALCdevice_DecRef(Device
);
3032 VerifyDevice(&Device
);
3033 alcSetError(Device
, ALC_INVALID_ENUM
);
3034 if(Device
) ALCdevice_DecRef(Device
);
3042 static inline ALCsizei
NumAttrsForDevice(ALCdevice
*device
)
3044 if(device
->Type
== Loopback
&& device
->FmtChans
== DevFmtAmbi3D
)
3049 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3053 if(size
<= 0 || values
== NULL
)
3055 alcSetError(device
, ALC_INVALID_VALUE
);
3063 case ALC_MAJOR_VERSION
:
3064 values
[0] = alcMajorVersion
;
3066 case ALC_MINOR_VERSION
:
3067 values
[0] = alcMinorVersion
;
3070 case ALC_ATTRIBUTES_SIZE
:
3071 case ALC_ALL_ATTRIBUTES
:
3075 case ALC_MONO_SOURCES
:
3076 case ALC_STEREO_SOURCES
:
3077 case ALC_CAPTURE_SAMPLES
:
3078 case ALC_FORMAT_CHANNELS_SOFT
:
3079 case ALC_FORMAT_TYPE_SOFT
:
3080 case ALC_AMBISONIC_LAYOUT_SOFT
:
3081 case ALC_AMBISONIC_SCALING_SOFT
:
3082 case ALC_AMBISONIC_ORDER_SOFT
:
3083 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3087 alcSetError(NULL
, ALC_INVALID_ENUM
);
3093 if(device
->Type
== Capture
)
3097 case ALC_CAPTURE_SAMPLES
:
3098 almtx_lock(&device
->BackendLock
);
3099 values
[0] = V0(device
->Backend
,availableSamples
)();
3100 almtx_unlock(&device
->BackendLock
);
3104 values
[0] = device
->Connected
;
3108 alcSetError(device
, ALC_INVALID_ENUM
);
3117 case ALC_MAJOR_VERSION
:
3118 values
[0] = alcMajorVersion
;
3121 case ALC_MINOR_VERSION
:
3122 values
[0] = alcMinorVersion
;
3125 case ALC_EFX_MAJOR_VERSION
:
3126 values
[0] = alcEFXMajorVersion
;
3129 case ALC_EFX_MINOR_VERSION
:
3130 values
[0] = alcEFXMinorVersion
;
3133 case ALC_ATTRIBUTES_SIZE
:
3134 values
[0] = NumAttrsForDevice(device
);
3137 case ALC_ALL_ATTRIBUTES
:
3138 if(size
< NumAttrsForDevice(device
))
3140 alcSetError(device
, ALC_INVALID_VALUE
);
3145 almtx_lock(&device
->BackendLock
);
3146 values
[i
++] = ALC_FREQUENCY
;
3147 values
[i
++] = device
->Frequency
;
3149 if(device
->Type
!= Loopback
)
3151 values
[i
++] = ALC_REFRESH
;
3152 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3154 values
[i
++] = ALC_SYNC
;
3155 values
[i
++] = ALC_FALSE
;
3159 if(device
->FmtChans
== DevFmtAmbi3D
)
3161 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3162 values
[i
++] = device
->AmbiLayout
;
3164 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3165 values
[i
++] = device
->AmbiScale
;
3167 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3168 values
[i
++] = device
->AmbiOrder
;
3171 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3172 values
[i
++] = device
->FmtChans
;
3174 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3175 values
[i
++] = device
->FmtType
;
3178 values
[i
++] = ALC_MONO_SOURCES
;
3179 values
[i
++] = device
->NumMonoSources
;
3181 values
[i
++] = ALC_STEREO_SOURCES
;
3182 values
[i
++] = device
->NumStereoSources
;
3184 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3185 values
[i
++] = device
->NumAuxSends
;
3187 values
[i
++] = ALC_HRTF_SOFT
;
3188 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3190 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3191 values
[i
++] = device
->HrtfStatus
;
3193 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3194 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3195 almtx_unlock(&device
->BackendLock
);
3201 values
[0] = device
->Frequency
;
3205 if(device
->Type
== Loopback
)
3207 alcSetError(device
, ALC_INVALID_DEVICE
);
3210 almtx_lock(&device
->BackendLock
);
3211 values
[0] = device
->Frequency
/ device
->UpdateSize
;
3212 almtx_unlock(&device
->BackendLock
);
3216 if(device
->Type
== Loopback
)
3218 alcSetError(device
, ALC_INVALID_DEVICE
);
3221 values
[0] = ALC_FALSE
;
3224 case ALC_FORMAT_CHANNELS_SOFT
:
3225 if(device
->Type
!= Loopback
)
3227 alcSetError(device
, ALC_INVALID_DEVICE
);
3230 values
[0] = device
->FmtChans
;
3233 case ALC_FORMAT_TYPE_SOFT
:
3234 if(device
->Type
!= Loopback
)
3236 alcSetError(device
, ALC_INVALID_DEVICE
);
3239 values
[0] = device
->FmtType
;
3242 case ALC_AMBISONIC_LAYOUT_SOFT
:
3243 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3245 alcSetError(device
, ALC_INVALID_DEVICE
);
3248 values
[0] = device
->AmbiLayout
;
3251 case ALC_AMBISONIC_SCALING_SOFT
:
3252 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3254 alcSetError(device
, ALC_INVALID_DEVICE
);
3257 values
[0] = device
->AmbiScale
;
3260 case ALC_AMBISONIC_ORDER_SOFT
:
3261 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3263 alcSetError(device
, ALC_INVALID_DEVICE
);
3266 values
[0] = device
->AmbiOrder
;
3269 case ALC_MONO_SOURCES
:
3270 values
[0] = device
->NumMonoSources
;
3273 case ALC_STEREO_SOURCES
:
3274 values
[0] = device
->NumStereoSources
;
3277 case ALC_MAX_AUXILIARY_SENDS
:
3278 values
[0] = device
->NumAuxSends
;
3282 values
[0] = device
->Connected
;
3286 values
[0] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3289 case ALC_HRTF_STATUS_SOFT
:
3290 values
[0] = device
->HrtfStatus
;
3293 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
3294 almtx_lock(&device
->BackendLock
);
3295 FreeHrtfList(&device
->HrtfList
);
3296 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
3297 values
[0] = (ALCint
)VECTOR_SIZE(device
->HrtfList
);
3298 almtx_unlock(&device
->BackendLock
);
3301 case ALC_OUTPUT_LIMITER_SOFT
:
3302 values
[0] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3306 alcSetError(device
, ALC_INVALID_ENUM
);
3314 * Returns information about the device and the version of OpenAL
3316 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3318 VerifyDevice(&device
);
3319 if(size
<= 0 || values
== NULL
)
3320 alcSetError(device
, ALC_INVALID_VALUE
);
3322 GetIntegerv(device
, param
, size
, values
);
3323 if(device
) ALCdevice_DecRef(device
);
3326 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
3331 VerifyDevice(&device
);
3332 if(size
<= 0 || values
== NULL
)
3333 alcSetError(device
, ALC_INVALID_VALUE
);
3334 else if(!device
|| device
->Type
== Capture
)
3336 ivals
= malloc(size
* sizeof(ALCint
));
3337 size
= GetIntegerv(device
, pname
, size
, ivals
);
3338 for(i
= 0;i
< size
;i
++)
3339 values
[i
] = ivals
[i
];
3342 else /* render device */
3351 case ALC_ATTRIBUTES_SIZE
:
3352 *values
= NumAttrsForDevice(device
)+4;
3355 case ALC_ALL_ATTRIBUTES
:
3356 if(size
< NumAttrsForDevice(device
)+4)
3357 alcSetError(device
, ALC_INVALID_VALUE
);
3361 almtx_lock(&device
->BackendLock
);
3362 values
[i
++] = ALC_FREQUENCY
;
3363 values
[i
++] = device
->Frequency
;
3365 if(device
->Type
!= Loopback
)
3367 values
[i
++] = ALC_REFRESH
;
3368 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3370 values
[i
++] = ALC_SYNC
;
3371 values
[i
++] = ALC_FALSE
;
3375 if(device
->FmtChans
== DevFmtAmbi3D
)
3377 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3378 values
[i
++] = device
->AmbiLayout
;
3380 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3381 values
[i
++] = device
->AmbiScale
;
3383 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3384 values
[i
++] = device
->AmbiOrder
;
3387 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3388 values
[i
++] = device
->FmtChans
;
3390 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3391 values
[i
++] = device
->FmtType
;
3394 values
[i
++] = ALC_MONO_SOURCES
;
3395 values
[i
++] = device
->NumMonoSources
;
3397 values
[i
++] = ALC_STEREO_SOURCES
;
3398 values
[i
++] = device
->NumStereoSources
;
3400 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3401 values
[i
++] = device
->NumAuxSends
;
3403 values
[i
++] = ALC_HRTF_SOFT
;
3404 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3406 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3407 values
[i
++] = device
->HrtfStatus
;
3409 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3410 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3412 clock
= V0(device
->Backend
,getClockLatency
)();
3413 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3414 values
[i
++] = clock
.ClockTime
;
3416 values
[i
++] = ALC_DEVICE_LATENCY_SOFT
;
3417 values
[i
++] = clock
.Latency
;
3418 almtx_unlock(&device
->BackendLock
);
3424 case ALC_DEVICE_CLOCK_SOFT
:
3425 almtx_lock(&device
->BackendLock
);
3427 while(((refcount
=ReadRef(&device
->MixCount
))&1) != 0)
3429 basecount
= device
->ClockBase
;
3430 samplecount
= device
->SamplesDone
;
3431 } while(refcount
!= ReadRef(&device
->MixCount
));
3432 *values
= basecount
+ (samplecount
*DEVICE_CLOCK_RES
/device
->Frequency
);
3433 almtx_unlock(&device
->BackendLock
);
3436 case ALC_DEVICE_LATENCY_SOFT
:
3437 almtx_lock(&device
->BackendLock
);
3438 clock
= V0(device
->Backend
,getClockLatency
)();
3439 almtx_unlock(&device
->BackendLock
);
3440 *values
= clock
.Latency
;
3443 case ALC_DEVICE_CLOCK_LATENCY_SOFT
:
3445 alcSetError(device
, ALC_INVALID_VALUE
);
3448 almtx_lock(&device
->BackendLock
);
3449 clock
= V0(device
->Backend
,getClockLatency
)();
3450 almtx_unlock(&device
->BackendLock
);
3451 values
[0] = clock
.ClockTime
;
3452 values
[1] = clock
.Latency
;
3457 ivals
= malloc(size
* sizeof(ALCint
));
3458 size
= GetIntegerv(device
, pname
, size
, ivals
);
3459 for(i
= 0;i
< size
;i
++)
3460 values
[i
] = ivals
[i
];
3466 ALCdevice_DecRef(device
);
3470 /* alcIsExtensionPresent
3472 * Determines if there is support for a particular extension
3474 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3476 ALCboolean bResult
= ALC_FALSE
;
3478 VerifyDevice(&device
);
3481 alcSetError(device
, ALC_INVALID_VALUE
);
3484 size_t len
= strlen(extName
);
3485 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3488 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3489 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3494 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3498 } while(isspace(*ptr
));
3503 ALCdevice_DecRef(device
);
3508 /* alcGetProcAddress
3510 * Retrieves the function address for a particular extension function
3512 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3514 ALCvoid
*ptr
= NULL
;
3518 VerifyDevice(&device
);
3519 alcSetError(device
, ALC_INVALID_VALUE
);
3520 if(device
) ALCdevice_DecRef(device
);
3525 for(i
= 0;i
< COUNTOF(alcFunctions
);i
++)
3527 if(strcmp(alcFunctions
[i
].funcName
, funcName
) == 0)
3529 ptr
= alcFunctions
[i
].address
;
3541 * Get the value for a particular ALC enumeration name
3543 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3549 VerifyDevice(&device
);
3550 alcSetError(device
, ALC_INVALID_VALUE
);
3551 if(device
) ALCdevice_DecRef(device
);
3556 for(i
= 0;i
< COUNTOF(alcEnumerations
);i
++)
3558 if(strcmp(alcEnumerations
[i
].enumName
, enumName
) == 0)
3560 val
= alcEnumerations
[i
].value
;
3572 * Create and attach a context to the given device.
3574 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3576 ALCcontext
*ALContext
;
3580 /* Explicitly hold the list lock while taking the BackendLock in case the
3581 * device is asynchronously destropyed, to ensure this new context is
3582 * properly cleaned up after being made.
3585 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3588 alcSetError(device
, ALC_INVALID_DEVICE
);
3589 if(device
) ALCdevice_DecRef(device
);
3592 almtx_lock(&device
->BackendLock
);
3595 ATOMIC_STORE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
3597 if(device
->Type
== Playback
&& DefaultEffect
.type
!= AL_EFFECT_NULL
)
3598 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
)+sizeof(ALeffectslot
));
3600 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3603 almtx_unlock(&device
->BackendLock
);
3605 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3606 ALCdevice_DecRef(device
);
3610 InitRef(&ALContext
->ref
, 1);
3611 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3612 ALContext
->DefaultSlot
= NULL
;
3614 ALContext
->Voices
= NULL
;
3615 ALContext
->VoiceCount
= 0;
3616 ALContext
->MaxVoices
= 0;
3617 ATOMIC_INIT(&ALContext
->ActiveAuxSlots
, NULL
);
3618 ALContext
->Device
= device
;
3620 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3622 almtx_unlock(&device
->BackendLock
);
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 if(DefaultEffect
.type
!= AL_EFFECT_NULL
&& device
->Type
== Playback
)
3641 ALContext
->DefaultSlot
= (ALeffectslot
*)(ALContext
->_listener_mem
+ sizeof(ALlistener
));
3642 if(InitEffectSlot(ALContext
->DefaultSlot
) != AL_NO_ERROR
)
3644 ALContext
->DefaultSlot
= NULL
;
3645 ERR("Failed to initialize the default effect slot\n");
3649 aluInitEffectPanning(ALContext
->DefaultSlot
);
3650 if(InitializeEffect(device
, ALContext
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3652 DeinitEffectSlot(ALContext
->DefaultSlot
);
3653 ALContext
->DefaultSlot
= NULL
;
3654 ERR("Failed to initialize the default effect\n");
3657 if(ALContext
->DefaultSlot
)
3659 ALeffectslot
*slot
= ALContext
->DefaultSlot
;
3660 ALeffectState
*state
= slot
->Effect
.State
;
3663 state
->OutBuffer
= device
->Dry
.Buffer
;
3664 state
->OutChannels
= device
->Dry
.NumChannels
;
3665 if(V(state
,deviceUpdate
)(device
) != AL_FALSE
)
3666 UpdateEffectSlotProps(slot
);
3669 DeinitEffectSlot(ALContext
->DefaultSlot
);
3670 ALContext
->DefaultSlot
= NULL
;
3676 ALCdevice_IncRef(ALContext
->Device
);
3677 InitContext(ALContext
);
3679 if(ConfigValueFloat(alstr_get_cstr(device
->DeviceName
), NULL
, "volume-adjust", &valf
))
3682 ERR("volume-adjust must be finite: %f\n", valf
);
3685 ALfloat db
= clampf(valf
, -24.0f
, 24.0f
);
3687 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf
, 24.0f
);
3688 ALContext
->GainBoost
= powf(10.0f
, db
/20.0f
);
3689 TRACE("volume-adjust gain: %f\n", ALContext
->GainBoost
);
3692 UpdateListenerProps(ALContext
);
3695 ALCcontext
*head
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
3697 ALContext
->next
= head
;
3698 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device
->ContextList
, &head
,
3701 almtx_unlock(&device
->BackendLock
);
3703 ALCdevice_DecRef(device
);
3705 TRACE("Created context %p\n", ALContext
);
3709 /* alcDestroyContext
3711 * Remove a context from its device
3713 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3718 if(!VerifyContext(&context
))
3721 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3725 Device
= context
->Device
;
3728 almtx_lock(&Device
->BackendLock
);
3729 if(!ReleaseContext(context
, Device
))
3731 V0(Device
->Backend
,stop
)();
3732 Device
->Flags
&= ~DEVICE_RUNNING
;
3734 almtx_unlock(&Device
->BackendLock
);
3738 ALCcontext_DecRef(context
);
3742 /* alcGetCurrentContext
3744 * Returns the currently active context on the calling thread
3746 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3748 ALCcontext
*Context
= altss_get(LocalContext
);
3749 if(!Context
) Context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
3753 /* alcGetThreadContext
3755 * Returns the currently active thread-local context
3757 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3759 return altss_get(LocalContext
);
3763 /* alcMakeContextCurrent
3765 * Makes the given context the active process-wide context, and removes the
3766 * thread-local context for the calling thread.
3768 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3770 /* context must be valid or NULL */
3771 if(context
&& !VerifyContext(&context
))
3773 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3776 /* context's reference count is already incremented */
3777 context
= ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext
, context
);
3778 if(context
) ALCcontext_DecRef(context
);
3780 if((context
=altss_get(LocalContext
)) != NULL
)
3782 altss_set(LocalContext
, NULL
);
3783 ALCcontext_DecRef(context
);
3789 /* alcSetThreadContext
3791 * Makes the given context the active context for the current thread
3793 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3797 /* context must be valid or NULL */
3798 if(context
&& !VerifyContext(&context
))
3800 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3803 /* context's reference count is already incremented */
3804 old
= altss_get(LocalContext
);
3805 altss_set(LocalContext
, context
);
3806 if(old
) ALCcontext_DecRef(old
);
3812 /* alcGetContextsDevice
3814 * Returns the device that a particular context is attached to
3816 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3820 if(!VerifyContext(&Context
))
3822 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3825 Device
= Context
->Device
;
3826 ALCcontext_DecRef(Context
);
3834 * Opens the named device.
3836 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3838 ALCbackendFactory
*factory
;
3846 if(!PlaybackBackend
.name
)
3848 alcSetError(NULL
, ALC_INVALID_VALUE
);
3852 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3854 /* Some old Windows apps hardcode these expecting OpenAL to use a
3855 * specific audio API, even when they're not enumerated. Creative's
3856 * router effectively ignores them too.
3858 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3859 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3864 device
= al_calloc(16, sizeof(ALCdevice
));
3867 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3872 InitRef(&device
->ref
, 1);
3873 device
->Connected
= ALC_TRUE
;
3874 device
->Type
= Playback
;
3875 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3878 device
->Bs2b
= NULL
;
3879 device
->Uhj_Encoder
= NULL
;
3880 device
->Hrtf
= NULL
;
3881 device
->HrtfHandle
= NULL
;
3882 VECTOR_INIT(device
->HrtfList
);
3883 AL_STRING_INIT(device
->HrtfName
);
3884 device
->Render_Mode
= NormalRender
;
3885 AL_STRING_INIT(device
->DeviceName
);
3886 device
->Dry
.Buffer
= NULL
;
3887 device
->Dry
.NumChannels
= 0;
3888 device
->FOAOut
.Buffer
= NULL
;
3889 device
->FOAOut
.NumChannels
= 0;
3890 device
->RealOut
.Buffer
= NULL
;
3891 device
->RealOut
.NumChannels
= 0;
3892 device
->Limiter
= NULL
;
3893 device
->AvgSpeakerDist
= 0.0f
;
3895 ATOMIC_INIT(&device
->ContextList
, NULL
);
3897 device
->ClockBase
= 0;
3898 device
->SamplesDone
= 0;
3900 device
->SourcesMax
= 256;
3901 device
->AuxiliaryEffectSlotMax
= 64;
3902 device
->NumAuxSends
= DEFAULT_SENDS
;
3904 InitUIntMap(&device
->BufferMap
, INT_MAX
);
3905 InitUIntMap(&device
->EffectMap
, INT_MAX
);
3906 InitUIntMap(&device
->FilterMap
, INT_MAX
);
3908 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
3910 device
->ChannelDelay
[i
].Gain
= 1.0f
;
3911 device
->ChannelDelay
[i
].Length
= 0;
3912 device
->ChannelDelay
[i
].Buffer
= NULL
;
3916 device
->FmtChans
= DevFmtChannelsDefault
;
3917 device
->FmtType
= DevFmtTypeDefault
;
3918 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3919 device
->IsHeadphones
= AL_FALSE
;
3920 device
->AmbiLayout
= AmbiLayout_Default
;
3921 device
->AmbiScale
= AmbiNorm_Default
;
3922 device
->NumUpdates
= 3;
3923 device
->UpdateSize
= 1024;
3925 factory
= PlaybackBackend
.getFactory();
3926 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3927 if(!device
->Backend
)
3930 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3935 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3937 static const struct {
3938 const char name
[16];
3939 enum DevFmtChannels chans
;
3942 { "mono", DevFmtMono
, 0 },
3943 { "stereo", DevFmtStereo
, 0 },
3944 { "quad", DevFmtQuad
, 0 },
3945 { "surround51", DevFmtX51
, 0 },
3946 { "surround61", DevFmtX61
, 0 },
3947 { "surround71", DevFmtX71
, 0 },
3948 { "surround51rear", DevFmtX51Rear
, 0 },
3949 { "ambi1", DevFmtAmbi3D
, 1 },
3950 { "ambi2", DevFmtAmbi3D
, 2 },
3951 { "ambi3", DevFmtAmbi3D
, 3 },
3955 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3957 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3959 device
->FmtChans
= chanlist
[i
].chans
;
3960 device
->AmbiOrder
= chanlist
[i
].order
;
3961 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3965 if(i
== COUNTOF(chanlist
))
3966 ERR("Unsupported channels: %s\n", fmt
);
3968 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3970 static const struct {
3971 const char name
[16];
3972 enum DevFmtType type
;
3974 { "int8", DevFmtByte
},
3975 { "uint8", DevFmtUByte
},
3976 { "int16", DevFmtShort
},
3977 { "uint16", DevFmtUShort
},
3978 { "int32", DevFmtInt
},
3979 { "uint32", DevFmtUInt
},
3980 { "float32", DevFmtFloat
},
3984 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3986 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3988 device
->FmtType
= typelist
[i
].type
;
3989 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3993 if(i
== COUNTOF(typelist
))
3994 ERR("Unsupported sample-type: %s\n", fmt
);
3997 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3999 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4000 if(device
->Frequency
< MIN_OUTPUT_RATE
)
4001 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
4002 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
4005 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
4006 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
4008 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
4009 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
4010 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
4011 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
4013 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
4014 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4016 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4017 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4019 if(ConfigValueInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
))
4020 device
->NumAuxSends
= clampi(
4021 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4024 device
->NumStereoSources
= 1;
4025 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4027 // Find a playback device to open
4028 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4030 DELETE_OBJ(device
->Backend
);
4032 alcSetError(NULL
, err
);
4035 almtx_init(&device
->BackendLock
, almtx_plain
);
4037 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "ambi-format", &fmt
))
4039 if(strcasecmp(fmt
, "fuma") == 0)
4041 device
->AmbiLayout
= AmbiLayout_FuMa
;
4042 device
->AmbiScale
= AmbiNorm_FuMa
;
4044 else if(strcasecmp(fmt
, "acn+sn3d") == 0)
4046 device
->AmbiLayout
= AmbiLayout_ACN
;
4047 device
->AmbiScale
= AmbiNorm_SN3D
;
4049 else if(strcasecmp(fmt
, "acn+n3d") == 0)
4051 device
->AmbiLayout
= AmbiLayout_ACN
;
4052 device
->AmbiScale
= AmbiNorm_N3D
;
4055 ERR("Unsupported ambi-format: %s\n", fmt
);
4058 device
->Limiter
= CreateDeviceLimiter(device
);
4061 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4063 device
->next
= head
;
4064 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4067 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4073 * Closes the given device.
4075 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
4077 ALCdevice
*iter
, *origdev
;
4081 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4085 } while((iter
=iter
->next
) != NULL
);
4086 if(!iter
|| iter
->Type
== Capture
)
4088 alcSetError(iter
, ALC_INVALID_DEVICE
);
4092 almtx_lock(&device
->BackendLock
);
4095 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4097 ALCdevice
*volatile*list
= &origdev
->next
;
4102 *list
= (*list
)->next
;
4105 list
= &(*list
)->next
;
4110 ctx
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
4113 ALCcontext
*next
= ctx
->next
;
4114 WARN("Releasing context %p\n", ctx
);
4115 ReleaseContext(ctx
, device
);
4118 if((device
->Flags
&DEVICE_RUNNING
))
4119 V0(device
->Backend
,stop
)();
4120 device
->Flags
&= ~DEVICE_RUNNING
;
4121 almtx_unlock(&device
->BackendLock
);
4123 ALCdevice_DecRef(device
);
4129 /************************************************
4130 * ALC capture functions
4131 ************************************************/
4132 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
4134 ALCbackendFactory
*factory
;
4135 ALCdevice
*device
= NULL
;
4141 if(!CaptureBackend
.name
)
4143 alcSetError(NULL
, ALC_INVALID_VALUE
);
4149 alcSetError(NULL
, ALC_INVALID_VALUE
);
4153 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
4156 device
= al_calloc(16, sizeof(ALCdevice
));
4159 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4164 InitRef(&device
->ref
, 1);
4165 device
->Connected
= ALC_TRUE
;
4166 device
->Type
= Capture
;
4168 device
->Hrtf
= NULL
;
4169 device
->HrtfHandle
= NULL
;
4170 VECTOR_INIT(device
->HrtfList
);
4171 AL_STRING_INIT(device
->HrtfName
);
4173 AL_STRING_INIT(device
->DeviceName
);
4174 device
->Dry
.Buffer
= NULL
;
4175 device
->Dry
.NumChannels
= 0;
4176 device
->FOAOut
.Buffer
= NULL
;
4177 device
->FOAOut
.NumChannels
= 0;
4178 device
->RealOut
.Buffer
= NULL
;
4179 device
->RealOut
.NumChannels
= 0;
4181 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4182 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4183 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4185 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4187 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4188 device
->ChannelDelay
[i
].Length
= 0;
4189 device
->ChannelDelay
[i
].Buffer
= NULL
;
4192 factory
= CaptureBackend
.getFactory();
4193 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
4194 if(!device
->Backend
)
4197 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4201 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4202 device
->Frequency
= frequency
;
4204 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
4205 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
4208 alcSetError(NULL
, ALC_INVALID_ENUM
);
4211 device
->IsHeadphones
= AL_FALSE
;
4212 device
->AmbiOrder
= 0;
4213 device
->AmbiLayout
= AmbiLayout_Default
;
4214 device
->AmbiScale
= AmbiNorm_Default
;
4216 device
->UpdateSize
= samples
;
4217 device
->NumUpdates
= 1;
4219 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4220 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
4221 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
4223 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4226 alcSetError(NULL
, err
);
4229 almtx_init(&device
->BackendLock
, almtx_plain
);
4232 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4234 device
->next
= head
;
4235 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4238 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4242 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
4244 ALCdevice
*iter
, *origdev
;
4247 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4251 } while((iter
=iter
->next
) != NULL
);
4252 if(!iter
|| iter
->Type
!= Capture
)
4254 alcSetError(iter
, ALC_INVALID_DEVICE
);
4260 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4262 ALCdevice
*volatile*list
= &origdev
->next
;
4267 *list
= (*list
)->next
;
4270 list
= &(*list
)->next
;
4275 ALCdevice_DecRef(device
);
4280 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
4282 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4283 alcSetError(device
, ALC_INVALID_DEVICE
);
4286 almtx_lock(&device
->BackendLock
);
4287 if(!device
->Connected
)
4288 alcSetError(device
, ALC_INVALID_DEVICE
);
4289 else if(!(device
->Flags
&DEVICE_RUNNING
))
4291 if(V0(device
->Backend
,start
)())
4292 device
->Flags
|= DEVICE_RUNNING
;
4295 aluHandleDisconnect(device
);
4296 alcSetError(device
, ALC_INVALID_DEVICE
);
4299 almtx_unlock(&device
->BackendLock
);
4302 if(device
) ALCdevice_DecRef(device
);
4305 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
4307 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4308 alcSetError(device
, ALC_INVALID_DEVICE
);
4311 almtx_lock(&device
->BackendLock
);
4312 if((device
->Flags
&DEVICE_RUNNING
))
4313 V0(device
->Backend
,stop
)();
4314 device
->Flags
&= ~DEVICE_RUNNING
;
4315 almtx_unlock(&device
->BackendLock
);
4318 if(device
) ALCdevice_DecRef(device
);
4321 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4323 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4324 alcSetError(device
, ALC_INVALID_DEVICE
);
4327 ALCenum err
= ALC_INVALID_VALUE
;
4329 almtx_lock(&device
->BackendLock
);
4330 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
4331 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
4332 almtx_unlock(&device
->BackendLock
);
4334 if(err
!= ALC_NO_ERROR
)
4335 alcSetError(device
, err
);
4337 if(device
) ALCdevice_DecRef(device
);
4341 /************************************************
4342 * ALC loopback functions
4343 ************************************************/
4345 /* alcLoopbackOpenDeviceSOFT
4347 * Open a loopback device, for manual rendering.
4349 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
4351 ALCbackendFactory
*factory
;
4357 /* Make sure the device name, if specified, is us. */
4358 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
4360 alcSetError(NULL
, ALC_INVALID_VALUE
);
4364 device
= al_calloc(16, sizeof(ALCdevice
));
4367 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4372 InitRef(&device
->ref
, 1);
4373 device
->Connected
= ALC_TRUE
;
4374 device
->Type
= Loopback
;
4375 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
4378 device
->Hrtf
= NULL
;
4379 device
->HrtfHandle
= NULL
;
4380 VECTOR_INIT(device
->HrtfList
);
4381 AL_STRING_INIT(device
->HrtfName
);
4382 device
->Bs2b
= NULL
;
4383 device
->Uhj_Encoder
= NULL
;
4384 device
->Render_Mode
= NormalRender
;
4385 AL_STRING_INIT(device
->DeviceName
);
4386 device
->Dry
.Buffer
= NULL
;
4387 device
->Dry
.NumChannels
= 0;
4388 device
->FOAOut
.Buffer
= NULL
;
4389 device
->FOAOut
.NumChannels
= 0;
4390 device
->RealOut
.Buffer
= NULL
;
4391 device
->RealOut
.NumChannels
= 0;
4392 device
->Limiter
= NULL
;
4393 device
->AvgSpeakerDist
= 0.0f
;
4395 ATOMIC_INIT(&device
->ContextList
, NULL
);
4397 device
->ClockBase
= 0;
4398 device
->SamplesDone
= 0;
4400 device
->SourcesMax
= 256;
4401 device
->AuxiliaryEffectSlotMax
= 64;
4402 device
->NumAuxSends
= DEFAULT_SENDS
;
4404 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4405 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4406 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4408 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4410 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4411 device
->ChannelDelay
[i
].Length
= 0;
4412 device
->ChannelDelay
[i
].Buffer
= NULL
;
4415 factory
= ALCloopbackFactory_getFactory();
4416 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
4417 if(!device
->Backend
)
4420 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4423 almtx_init(&device
->BackendLock
, almtx_plain
);
4426 device
->NumUpdates
= 0;
4427 device
->UpdateSize
= 0;
4429 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
4430 device
->FmtChans
= DevFmtChannelsDefault
;
4431 device
->FmtType
= DevFmtTypeDefault
;
4432 device
->IsHeadphones
= AL_FALSE
;
4433 device
->AmbiLayout
= AmbiLayout_Default
;
4434 device
->AmbiScale
= AmbiNorm_Default
;
4436 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
4437 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4439 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4440 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4442 if(ConfigValueInt(NULL
, NULL
, "sends", &device
->NumAuxSends
))
4443 device
->NumAuxSends
= clampi(
4444 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4447 device
->NumStereoSources
= 1;
4448 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4450 // Open the "backend"
4451 V(device
->Backend
,open
)("Loopback");
4453 device
->Limiter
= CreateDeviceLimiter(device
);
4456 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4458 device
->next
= head
;
4459 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4462 TRACE("Created device %p\n", device
);
4466 /* alcIsRenderFormatSupportedSOFT
4468 * Determines if the loopback device supports the given format for rendering.
4470 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
4472 ALCboolean ret
= ALC_FALSE
;
4474 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4475 alcSetError(device
, ALC_INVALID_DEVICE
);
4477 alcSetError(device
, ALC_INVALID_VALUE
);
4480 if(IsValidALCType(type
) && IsValidALCChannels(channels
) && freq
>= MIN_OUTPUT_RATE
)
4483 if(device
) ALCdevice_DecRef(device
);
4488 /* alcRenderSamplesSOFT
4490 * Renders some samples into a buffer, using the format last set by the
4491 * attributes given to alcCreateContext.
4493 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4495 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4496 alcSetError(device
, ALC_INVALID_DEVICE
);
4497 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
4498 alcSetError(device
, ALC_INVALID_VALUE
);
4501 V0(device
->Backend
,lock
)();
4502 aluMixData(device
, buffer
, samples
);
4503 V0(device
->Backend
,unlock
)();
4505 if(device
) ALCdevice_DecRef(device
);
4509 /************************************************
4510 * ALC loopback2 functions
4511 ************************************************/
4513 ALC_API ALCboolean ALC_APIENTRY
alcIsAmbisonicFormatSupportedSOFT(ALCdevice
*device
, ALCenum layout
, ALCenum scaling
, ALsizei order
)
4515 ALCboolean ret
= ALC_FALSE
;
4517 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4518 alcSetError(device
, ALC_INVALID_DEVICE
);
4520 alcSetError(device
, ALC_INVALID_VALUE
);
4523 if(IsValidAmbiLayout(layout
) && IsValidAmbiScaling(scaling
) && order
<= MAX_AMBI_ORDER
)
4526 if(device
) ALCdevice_DecRef(device
);
4531 /************************************************
4532 * ALC DSP pause/resume functions
4533 ************************************************/
4535 /* alcDevicePauseSOFT
4537 * Pause the DSP to stop audio processing.
4539 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
4541 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4542 alcSetError(device
, ALC_INVALID_DEVICE
);
4545 almtx_lock(&device
->BackendLock
);
4546 if((device
->Flags
&DEVICE_RUNNING
))
4547 V0(device
->Backend
,stop
)();
4548 device
->Flags
&= ~DEVICE_RUNNING
;
4549 device
->Flags
|= DEVICE_PAUSED
;
4550 almtx_unlock(&device
->BackendLock
);
4552 if(device
) ALCdevice_DecRef(device
);
4555 /* alcDeviceResumeSOFT
4557 * Resume the DSP to restart audio processing.
4559 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
4561 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4562 alcSetError(device
, ALC_INVALID_DEVICE
);
4565 almtx_lock(&device
->BackendLock
);
4566 if((device
->Flags
&DEVICE_PAUSED
))
4568 device
->Flags
&= ~DEVICE_PAUSED
;
4569 if(ATOMIC_LOAD_SEQ(&device
->ContextList
) != NULL
)
4571 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4572 device
->Flags
|= DEVICE_RUNNING
;
4575 alcSetError(device
, ALC_INVALID_DEVICE
);
4576 V0(device
->Backend
,lock
)();
4577 aluHandleDisconnect(device
);
4578 V0(device
->Backend
,unlock
)();
4582 almtx_unlock(&device
->BackendLock
);
4584 if(device
) ALCdevice_DecRef(device
);
4588 /************************************************
4589 * ALC HRTF functions
4590 ************************************************/
4592 /* alcGetStringiSOFT
4594 * Gets a string parameter at the given index.
4596 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4598 const ALCchar
*str
= NULL
;
4600 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4601 alcSetError(device
, ALC_INVALID_DEVICE
);
4602 else switch(paramName
)
4604 case ALC_HRTF_SPECIFIER_SOFT
:
4605 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->HrtfList
))
4606 str
= alstr_get_cstr(VECTOR_ELEM(device
->HrtfList
, index
).name
);
4608 alcSetError(device
, ALC_INVALID_VALUE
);
4612 alcSetError(device
, ALC_INVALID_ENUM
);
4615 if(device
) ALCdevice_DecRef(device
);
4620 /* alcResetDeviceSOFT
4622 * Resets the given device output, using the specified attribute list.
4624 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4629 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4632 alcSetError(device
, ALC_INVALID_DEVICE
);
4633 if(device
) ALCdevice_DecRef(device
);
4636 almtx_lock(&device
->BackendLock
);
4639 err
= UpdateDeviceParams(device
, attribs
);
4640 almtx_unlock(&device
->BackendLock
);
4642 if(err
!= ALC_NO_ERROR
)
4644 alcSetError(device
, err
);
4645 if(err
== ALC_INVALID_DEVICE
)
4647 V0(device
->Backend
,lock
)();
4648 aluHandleDisconnect(device
);
4649 V0(device
->Backend
,unlock
)();
4651 ALCdevice_DecRef(device
);
4654 ALCdevice_DecRef(device
);