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 if(Context
->DefaultSlot
)
2554 auxslots
= al_calloc(DEF_ALIGN
, FAM_SIZE(struct ALeffectslotArray
, slot
, 1));
2555 auxslots
->count
= 1;
2556 auxslots
->slot
[0] = Context
->DefaultSlot
;
2560 auxslots
= al_calloc(DEF_ALIGN
, sizeof(struct ALeffectslotArray
));
2561 auxslots
->count
= 0;
2563 ATOMIC_INIT(&Context
->ActiveAuxSlots
, auxslots
);
2566 Context
->DistanceModel
= DefaultDistanceModel
;
2567 Context
->SourceDistanceModel
= AL_FALSE
;
2568 Context
->DopplerFactor
= 1.0f
;
2569 Context
->DopplerVelocity
= 1.0f
;
2570 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2571 ATOMIC_INIT(&Context
->DeferUpdates
, AL_FALSE
);
2573 Context
->ExtensionList
= alExtList
;
2579 * Cleans up the context, and destroys any remaining objects the app failed to
2580 * delete. Called once there's no more references on the context.
2582 static void FreeContext(ALCcontext
*context
)
2584 ALlistener
*listener
= context
->Listener
;
2585 struct ALeffectslotArray
*auxslots
;
2586 struct ALlistenerProps
*lprops
;
2590 TRACE("%p\n", context
);
2592 if(context
->DefaultSlot
)
2594 DeinitEffectSlot(context
->DefaultSlot
);
2595 context
->DefaultSlot
= NULL
;
2598 auxslots
= ATOMIC_EXCHANGE_PTR(&context
->ActiveAuxSlots
, NULL
, almemory_order_relaxed
);
2601 if(context
->SourceMap
.size
> 0)
2603 WARN("(%p) Deleting %d Source%s\n", context
, context
->SourceMap
.size
,
2604 (context
->SourceMap
.size
==1)?"":"s");
2605 ReleaseALSources(context
);
2607 ResetUIntMap(&context
->SourceMap
);
2609 if(context
->EffectSlotMap
.size
> 0)
2611 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context
, context
->EffectSlotMap
.size
,
2612 (context
->EffectSlotMap
.size
==1)?"":"s");
2613 ReleaseALAuxiliaryEffectSlots(context
);
2615 ResetUIntMap(&context
->EffectSlotMap
);
2617 for(i
= 0;i
< context
->VoiceCount
;i
++)
2618 DeinitVoice(context
->Voices
[i
]);
2619 al_free(context
->Voices
);
2620 context
->Voices
= NULL
;
2621 context
->VoiceCount
= 0;
2622 context
->MaxVoices
= 0;
2624 if((lprops
=ATOMIC_LOAD(&listener
->Update
, almemory_order_acquire
)) != NULL
)
2626 TRACE("Freed unapplied listener update %p\n", lprops
);
2630 lprops
= ATOMIC_LOAD(&listener
->FreeList
, almemory_order_acquire
);
2633 struct ALlistenerProps
*next
= ATOMIC_LOAD(&lprops
->next
, almemory_order_acquire
);
2638 TRACE("Freed "SZFMT
" listener property object%s\n", count
, (count
==1)?"":"s");
2640 ALCdevice_DecRef(context
->Device
);
2641 context
->Device
= NULL
;
2643 //Invalidate context
2644 memset(context
, 0, sizeof(ALCcontext
));
2650 * Removes the context reference from the given device and removes it from
2651 * being current on the running thread or globally. Returns true if other
2652 * contexts still exist on the device.
2654 static bool ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2656 ALCcontext
*origctx
, *newhead
;
2659 if(altss_get(LocalContext
) == context
)
2661 WARN("%p released while current on thread\n", context
);
2662 altss_set(LocalContext
, NULL
);
2663 ALCcontext_DecRef(context
);
2667 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext
, &origctx
, NULL
))
2668 ALCcontext_DecRef(context
);
2670 ALCdevice_Lock(device
);
2672 newhead
= context
->next
;
2673 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device
->ContextList
, &origctx
, newhead
))
2675 ALCcontext
*volatile*list
= &origctx
->next
;
2678 if(*list
== context
)
2680 *list
= (*list
)->next
;
2683 list
= &(*list
)->next
;
2688 ALCdevice_Unlock(device
);
2690 ALCcontext_DecRef(context
);
2694 void ALCcontext_IncRef(ALCcontext
*context
)
2696 uint ref
= IncrementRef(&context
->ref
);
2697 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2700 void ALCcontext_DecRef(ALCcontext
*context
)
2702 uint ref
= DecrementRef(&context
->ref
);
2703 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2704 if(ref
== 0) FreeContext(context
);
2707 static void ReleaseThreadCtx(void *ptr
)
2709 ALCcontext
*context
= ptr
;
2710 uint ref
= DecrementRef(&context
->ref
);
2711 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2712 ERR("Context %p current for thread being destroyed, possible leak!\n", context
);
2717 * Checks that the given context is valid, and increments its reference count.
2719 static ALCboolean
VerifyContext(ALCcontext
**context
)
2724 dev
= ATOMIC_LOAD_SEQ(&DeviceList
);
2727 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
, almemory_order_acquire
);
2732 ALCcontext_IncRef(ctx
);
2749 * Returns the currently active context for this thread, and adds a reference
2750 * without locking it.
2752 ALCcontext
*GetContextRef(void)
2754 ALCcontext
*context
;
2756 context
= altss_get(LocalContext
);
2758 ALCcontext_IncRef(context
);
2762 context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
2764 ALCcontext_IncRef(context
);
2772 void AllocateVoices(ALCcontext
*context
, ALsizei num_voices
, ALsizei old_sends
)
2774 ALCdevice
*device
= context
->Device
;
2775 ALsizei num_sends
= device
->NumAuxSends
;
2776 struct ALvoiceProps
*props
;
2777 size_t sizeof_props
;
2778 size_t sizeof_voice
;
2784 if(num_voices
== context
->MaxVoices
&& num_sends
== old_sends
)
2787 /* Allocate the voice pointers, voices, and the voices' stored source
2788 * property set (including the dynamically-sized Send[] array) in one
2791 sizeof_voice
= RoundUp(FAM_SIZE(ALvoice
, Send
, num_sends
), 16);
2792 sizeof_props
= RoundUp(FAM_SIZE(struct ALvoiceProps
, Send
, num_sends
), 16);
2793 size
= sizeof(ALvoice
*) + sizeof_voice
+ sizeof_props
;
2795 voices
= al_calloc(16, RoundUp(size
*num_voices
, 16));
2796 /* The voice and property objects are stored interleaved since they're
2799 voice
= (ALvoice
*)((char*)voices
+ RoundUp(num_voices
*sizeof(ALvoice
*), 16));
2800 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2804 const ALsizei v_count
= mini(context
->VoiceCount
, num_voices
);
2805 const ALsizei s_count
= mini(old_sends
, num_sends
);
2807 for(;v
< v_count
;v
++)
2809 ALvoice
*old_voice
= context
->Voices
[v
];
2812 /* Copy the old voice data and source property set to the new
2815 *voice
= *old_voice
;
2816 for(i
= 0;i
< s_count
;i
++)
2817 voice
->Send
[i
] = old_voice
->Send
[i
];
2818 *props
= *(old_voice
->Props
);
2819 for(i
= 0;i
< s_count
;i
++)
2820 props
->Send
[i
] = old_voice
->Props
->Send
[i
];
2822 /* Set this voice's property set pointer and voice reference. */
2823 voice
->Props
= props
;
2826 /* Increment pointers to the next storage space. */
2827 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2828 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2830 /* Deinit any left over voices that weren't copied over to the new
2831 * array. NOTE: If this does anything, v equals num_voices and
2832 * num_voices is less than VoiceCount, so the following loop won't do
2835 for(;v
< context
->VoiceCount
;v
++)
2836 DeinitVoice(context
->Voices
[v
]);
2838 /* Finish setting the voices' property set pointers and references. */
2839 for(;v
< num_voices
;v
++)
2841 ATOMIC_INIT(&voice
->Update
, NULL
);
2842 ATOMIC_INIT(&voice
->FreeList
, NULL
);
2844 voice
->Props
= props
;
2847 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2848 props
= (struct ALvoiceProps
*)((char*)voice
+ sizeof_voice
);
2851 al_free(context
->Voices
);
2852 context
->Voices
= voices
;
2853 context
->MaxVoices
= num_voices
;
2854 context
->VoiceCount
= mini(context
->VoiceCount
, num_voices
);
2858 /************************************************
2859 * Standard ALC functions
2860 ************************************************/
2864 * Return last ALC generated error code for the given device
2866 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2870 if(VerifyDevice(&device
))
2872 errorCode
= ATOMIC_EXCHANGE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
2873 ALCdevice_DecRef(device
);
2876 errorCode
= ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError
, ALC_NO_ERROR
);
2882 /* alcSuspendContext
2884 * Suspends updates for the given context
2886 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2891 if(!VerifyContext(&context
))
2892 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2895 ALCcontext_DeferUpdates(context
);
2896 ALCcontext_DecRef(context
);
2900 /* alcProcessContext
2902 * Resumes processing updates for the given context
2904 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2909 if(!VerifyContext(&context
))
2910 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2913 ALCcontext_ProcessUpdates(context
);
2914 ALCcontext_DecRef(context
);
2921 * Returns information about the device, and error strings
2923 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2925 const ALCchar
*value
= NULL
;
2933 case ALC_INVALID_ENUM
:
2934 value
= alcErrInvalidEnum
;
2937 case ALC_INVALID_VALUE
:
2938 value
= alcErrInvalidValue
;
2941 case ALC_INVALID_DEVICE
:
2942 value
= alcErrInvalidDevice
;
2945 case ALC_INVALID_CONTEXT
:
2946 value
= alcErrInvalidContext
;
2949 case ALC_OUT_OF_MEMORY
:
2950 value
= alcErrOutOfMemory
;
2953 case ALC_DEVICE_SPECIFIER
:
2954 value
= alcDefaultName
;
2957 case ALC_ALL_DEVICES_SPECIFIER
:
2958 if(VerifyDevice(&Device
))
2960 value
= alstr_get_cstr(Device
->DeviceName
);
2961 ALCdevice_DecRef(Device
);
2965 ProbeAllDevicesList();
2966 value
= alstr_get_cstr(alcAllDevicesList
);
2970 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2971 if(VerifyDevice(&Device
))
2973 value
= alstr_get_cstr(Device
->DeviceName
);
2974 ALCdevice_DecRef(Device
);
2978 ProbeCaptureDeviceList();
2979 value
= alstr_get_cstr(alcCaptureDeviceList
);
2983 /* Default devices are always first in the list */
2984 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2985 value
= alcDefaultName
;
2988 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2989 if(alstr_empty(alcAllDevicesList
))
2990 ProbeAllDevicesList();
2992 VerifyDevice(&Device
);
2994 free(alcDefaultAllDevicesSpecifier
);
2995 alcDefaultAllDevicesSpecifier
= strdup(alstr_get_cstr(alcAllDevicesList
));
2996 if(!alcDefaultAllDevicesSpecifier
)
2997 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2999 value
= alcDefaultAllDevicesSpecifier
;
3000 if(Device
) ALCdevice_DecRef(Device
);
3003 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
3004 if(alstr_empty(alcCaptureDeviceList
))
3005 ProbeCaptureDeviceList();
3007 VerifyDevice(&Device
);
3009 free(alcCaptureDefaultDeviceSpecifier
);
3010 alcCaptureDefaultDeviceSpecifier
= strdup(alstr_get_cstr(alcCaptureDeviceList
));
3011 if(!alcCaptureDefaultDeviceSpecifier
)
3012 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
3014 value
= alcCaptureDefaultDeviceSpecifier
;
3015 if(Device
) ALCdevice_DecRef(Device
);
3018 case ALC_EXTENSIONS
:
3019 if(!VerifyDevice(&Device
))
3020 value
= alcNoDeviceExtList
;
3023 value
= alcExtensionList
;
3024 ALCdevice_DecRef(Device
);
3028 case ALC_HRTF_SPECIFIER_SOFT
:
3029 if(!VerifyDevice(&Device
))
3030 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3033 almtx_lock(&Device
->BackendLock
);
3034 value
= (Device
->HrtfHandle
? alstr_get_cstr(Device
->HrtfName
) : "");
3035 almtx_unlock(&Device
->BackendLock
);
3036 ALCdevice_DecRef(Device
);
3041 VerifyDevice(&Device
);
3042 alcSetError(Device
, ALC_INVALID_ENUM
);
3043 if(Device
) ALCdevice_DecRef(Device
);
3051 static inline ALCsizei
NumAttrsForDevice(ALCdevice
*device
)
3053 if(device
->Type
== Loopback
&& device
->FmtChans
== DevFmtAmbi3D
)
3058 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3062 if(size
<= 0 || values
== NULL
)
3064 alcSetError(device
, ALC_INVALID_VALUE
);
3072 case ALC_MAJOR_VERSION
:
3073 values
[0] = alcMajorVersion
;
3075 case ALC_MINOR_VERSION
:
3076 values
[0] = alcMinorVersion
;
3079 case ALC_ATTRIBUTES_SIZE
:
3080 case ALC_ALL_ATTRIBUTES
:
3084 case ALC_MONO_SOURCES
:
3085 case ALC_STEREO_SOURCES
:
3086 case ALC_CAPTURE_SAMPLES
:
3087 case ALC_FORMAT_CHANNELS_SOFT
:
3088 case ALC_FORMAT_TYPE_SOFT
:
3089 case ALC_AMBISONIC_LAYOUT_SOFT
:
3090 case ALC_AMBISONIC_SCALING_SOFT
:
3091 case ALC_AMBISONIC_ORDER_SOFT
:
3092 alcSetError(NULL
, ALC_INVALID_DEVICE
);
3096 alcSetError(NULL
, ALC_INVALID_ENUM
);
3102 if(device
->Type
== Capture
)
3106 case ALC_CAPTURE_SAMPLES
:
3107 almtx_lock(&device
->BackendLock
);
3108 values
[0] = V0(device
->Backend
,availableSamples
)();
3109 almtx_unlock(&device
->BackendLock
);
3113 values
[0] = device
->Connected
;
3117 alcSetError(device
, ALC_INVALID_ENUM
);
3126 case ALC_MAJOR_VERSION
:
3127 values
[0] = alcMajorVersion
;
3130 case ALC_MINOR_VERSION
:
3131 values
[0] = alcMinorVersion
;
3134 case ALC_EFX_MAJOR_VERSION
:
3135 values
[0] = alcEFXMajorVersion
;
3138 case ALC_EFX_MINOR_VERSION
:
3139 values
[0] = alcEFXMinorVersion
;
3142 case ALC_ATTRIBUTES_SIZE
:
3143 values
[0] = NumAttrsForDevice(device
);
3146 case ALC_ALL_ATTRIBUTES
:
3147 if(size
< NumAttrsForDevice(device
))
3149 alcSetError(device
, ALC_INVALID_VALUE
);
3154 almtx_lock(&device
->BackendLock
);
3155 values
[i
++] = ALC_FREQUENCY
;
3156 values
[i
++] = device
->Frequency
;
3158 if(device
->Type
!= Loopback
)
3160 values
[i
++] = ALC_REFRESH
;
3161 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3163 values
[i
++] = ALC_SYNC
;
3164 values
[i
++] = ALC_FALSE
;
3168 if(device
->FmtChans
== DevFmtAmbi3D
)
3170 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3171 values
[i
++] = device
->AmbiLayout
;
3173 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3174 values
[i
++] = device
->AmbiScale
;
3176 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3177 values
[i
++] = device
->AmbiOrder
;
3180 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3181 values
[i
++] = device
->FmtChans
;
3183 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3184 values
[i
++] = device
->FmtType
;
3187 values
[i
++] = ALC_MONO_SOURCES
;
3188 values
[i
++] = device
->NumMonoSources
;
3190 values
[i
++] = ALC_STEREO_SOURCES
;
3191 values
[i
++] = device
->NumStereoSources
;
3193 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3194 values
[i
++] = device
->NumAuxSends
;
3196 values
[i
++] = ALC_HRTF_SOFT
;
3197 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3199 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3200 values
[i
++] = device
->HrtfStatus
;
3202 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3203 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3204 almtx_unlock(&device
->BackendLock
);
3210 values
[0] = device
->Frequency
;
3214 if(device
->Type
== Loopback
)
3216 alcSetError(device
, ALC_INVALID_DEVICE
);
3219 almtx_lock(&device
->BackendLock
);
3220 values
[0] = device
->Frequency
/ device
->UpdateSize
;
3221 almtx_unlock(&device
->BackendLock
);
3225 if(device
->Type
== Loopback
)
3227 alcSetError(device
, ALC_INVALID_DEVICE
);
3230 values
[0] = ALC_FALSE
;
3233 case ALC_FORMAT_CHANNELS_SOFT
:
3234 if(device
->Type
!= Loopback
)
3236 alcSetError(device
, ALC_INVALID_DEVICE
);
3239 values
[0] = device
->FmtChans
;
3242 case ALC_FORMAT_TYPE_SOFT
:
3243 if(device
->Type
!= Loopback
)
3245 alcSetError(device
, ALC_INVALID_DEVICE
);
3248 values
[0] = device
->FmtType
;
3251 case ALC_AMBISONIC_LAYOUT_SOFT
:
3252 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3254 alcSetError(device
, ALC_INVALID_DEVICE
);
3257 values
[0] = device
->AmbiLayout
;
3260 case ALC_AMBISONIC_SCALING_SOFT
:
3261 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3263 alcSetError(device
, ALC_INVALID_DEVICE
);
3266 values
[0] = device
->AmbiScale
;
3269 case ALC_AMBISONIC_ORDER_SOFT
:
3270 if(device
->Type
!= Loopback
|| device
->FmtChans
!= DevFmtAmbi3D
)
3272 alcSetError(device
, ALC_INVALID_DEVICE
);
3275 values
[0] = device
->AmbiOrder
;
3278 case ALC_MONO_SOURCES
:
3279 values
[0] = device
->NumMonoSources
;
3282 case ALC_STEREO_SOURCES
:
3283 values
[0] = device
->NumStereoSources
;
3286 case ALC_MAX_AUXILIARY_SENDS
:
3287 values
[0] = device
->NumAuxSends
;
3291 values
[0] = device
->Connected
;
3295 values
[0] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3298 case ALC_HRTF_STATUS_SOFT
:
3299 values
[0] = device
->HrtfStatus
;
3302 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
3303 almtx_lock(&device
->BackendLock
);
3304 FreeHrtfList(&device
->HrtfList
);
3305 device
->HrtfList
= EnumerateHrtf(device
->DeviceName
);
3306 values
[0] = (ALCint
)VECTOR_SIZE(device
->HrtfList
);
3307 almtx_unlock(&device
->BackendLock
);
3310 case ALC_OUTPUT_LIMITER_SOFT
:
3311 values
[0] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3315 alcSetError(device
, ALC_INVALID_ENUM
);
3323 * Returns information about the device and the version of OpenAL
3325 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3327 VerifyDevice(&device
);
3328 if(size
<= 0 || values
== NULL
)
3329 alcSetError(device
, ALC_INVALID_VALUE
);
3331 GetIntegerv(device
, param
, size
, values
);
3332 if(device
) ALCdevice_DecRef(device
);
3335 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
3340 VerifyDevice(&device
);
3341 if(size
<= 0 || values
== NULL
)
3342 alcSetError(device
, ALC_INVALID_VALUE
);
3343 else if(!device
|| device
->Type
== Capture
)
3345 ivals
= malloc(size
* sizeof(ALCint
));
3346 size
= GetIntegerv(device
, pname
, size
, ivals
);
3347 for(i
= 0;i
< size
;i
++)
3348 values
[i
] = ivals
[i
];
3351 else /* render device */
3360 case ALC_ATTRIBUTES_SIZE
:
3361 *values
= NumAttrsForDevice(device
)+4;
3364 case ALC_ALL_ATTRIBUTES
:
3365 if(size
< NumAttrsForDevice(device
)+4)
3366 alcSetError(device
, ALC_INVALID_VALUE
);
3370 almtx_lock(&device
->BackendLock
);
3371 values
[i
++] = ALC_FREQUENCY
;
3372 values
[i
++] = device
->Frequency
;
3374 if(device
->Type
!= Loopback
)
3376 values
[i
++] = ALC_REFRESH
;
3377 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3379 values
[i
++] = ALC_SYNC
;
3380 values
[i
++] = ALC_FALSE
;
3384 if(device
->FmtChans
== DevFmtAmbi3D
)
3386 values
[i
++] = ALC_AMBISONIC_LAYOUT_SOFT
;
3387 values
[i
++] = device
->AmbiLayout
;
3389 values
[i
++] = ALC_AMBISONIC_SCALING_SOFT
;
3390 values
[i
++] = device
->AmbiScale
;
3392 values
[i
++] = ALC_AMBISONIC_ORDER_SOFT
;
3393 values
[i
++] = device
->AmbiOrder
;
3396 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3397 values
[i
++] = device
->FmtChans
;
3399 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3400 values
[i
++] = device
->FmtType
;
3403 values
[i
++] = ALC_MONO_SOURCES
;
3404 values
[i
++] = device
->NumMonoSources
;
3406 values
[i
++] = ALC_STEREO_SOURCES
;
3407 values
[i
++] = device
->NumStereoSources
;
3409 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3410 values
[i
++] = device
->NumAuxSends
;
3412 values
[i
++] = ALC_HRTF_SOFT
;
3413 values
[i
++] = (device
->HrtfHandle
? ALC_TRUE
: ALC_FALSE
);
3415 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3416 values
[i
++] = device
->HrtfStatus
;
3418 values
[i
++] = ALC_OUTPUT_LIMITER_SOFT
;
3419 values
[i
++] = device
->Limiter
? ALC_TRUE
: ALC_FALSE
;
3421 clock
= V0(device
->Backend
,getClockLatency
)();
3422 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3423 values
[i
++] = clock
.ClockTime
;
3425 values
[i
++] = ALC_DEVICE_LATENCY_SOFT
;
3426 values
[i
++] = clock
.Latency
;
3427 almtx_unlock(&device
->BackendLock
);
3433 case ALC_DEVICE_CLOCK_SOFT
:
3434 almtx_lock(&device
->BackendLock
);
3436 while(((refcount
=ReadRef(&device
->MixCount
))&1) != 0)
3438 basecount
= device
->ClockBase
;
3439 samplecount
= device
->SamplesDone
;
3440 } while(refcount
!= ReadRef(&device
->MixCount
));
3441 *values
= basecount
+ (samplecount
*DEVICE_CLOCK_RES
/device
->Frequency
);
3442 almtx_unlock(&device
->BackendLock
);
3445 case ALC_DEVICE_LATENCY_SOFT
:
3446 almtx_lock(&device
->BackendLock
);
3447 clock
= V0(device
->Backend
,getClockLatency
)();
3448 almtx_unlock(&device
->BackendLock
);
3449 *values
= clock
.Latency
;
3452 case ALC_DEVICE_CLOCK_LATENCY_SOFT
:
3454 alcSetError(device
, ALC_INVALID_VALUE
);
3457 almtx_lock(&device
->BackendLock
);
3458 clock
= V0(device
->Backend
,getClockLatency
)();
3459 almtx_unlock(&device
->BackendLock
);
3460 values
[0] = clock
.ClockTime
;
3461 values
[1] = clock
.Latency
;
3466 ivals
= malloc(size
* sizeof(ALCint
));
3467 size
= GetIntegerv(device
, pname
, size
, ivals
);
3468 for(i
= 0;i
< size
;i
++)
3469 values
[i
] = ivals
[i
];
3475 ALCdevice_DecRef(device
);
3479 /* alcIsExtensionPresent
3481 * Determines if there is support for a particular extension
3483 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3485 ALCboolean bResult
= ALC_FALSE
;
3487 VerifyDevice(&device
);
3490 alcSetError(device
, ALC_INVALID_VALUE
);
3493 size_t len
= strlen(extName
);
3494 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3497 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3498 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3503 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3507 } while(isspace(*ptr
));
3512 ALCdevice_DecRef(device
);
3517 /* alcGetProcAddress
3519 * Retrieves the function address for a particular extension function
3521 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3523 ALCvoid
*ptr
= NULL
;
3527 VerifyDevice(&device
);
3528 alcSetError(device
, ALC_INVALID_VALUE
);
3529 if(device
) ALCdevice_DecRef(device
);
3534 for(i
= 0;i
< COUNTOF(alcFunctions
);i
++)
3536 if(strcmp(alcFunctions
[i
].funcName
, funcName
) == 0)
3538 ptr
= alcFunctions
[i
].address
;
3550 * Get the value for a particular ALC enumeration name
3552 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3558 VerifyDevice(&device
);
3559 alcSetError(device
, ALC_INVALID_VALUE
);
3560 if(device
) ALCdevice_DecRef(device
);
3565 for(i
= 0;i
< COUNTOF(alcEnumerations
);i
++)
3567 if(strcmp(alcEnumerations
[i
].enumName
, enumName
) == 0)
3569 val
= alcEnumerations
[i
].value
;
3581 * Create and attach a context to the given device.
3583 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3585 ALCcontext
*ALContext
;
3589 /* Explicitly hold the list lock while taking the BackendLock in case the
3590 * device is asynchronously destropyed, to ensure this new context is
3591 * properly cleaned up after being made.
3594 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3597 alcSetError(device
, ALC_INVALID_DEVICE
);
3598 if(device
) ALCdevice_DecRef(device
);
3601 almtx_lock(&device
->BackendLock
);
3604 ATOMIC_STORE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
3606 if(device
->Type
== Playback
&& DefaultEffect
.type
!= AL_EFFECT_NULL
)
3607 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
)+sizeof(ALeffectslot
));
3609 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3612 almtx_unlock(&device
->BackendLock
);
3614 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3615 ALCdevice_DecRef(device
);
3619 InitRef(&ALContext
->ref
, 1);
3620 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3621 ALContext
->DefaultSlot
= NULL
;
3623 ALContext
->Voices
= NULL
;
3624 ALContext
->VoiceCount
= 0;
3625 ALContext
->MaxVoices
= 0;
3626 ATOMIC_INIT(&ALContext
->ActiveAuxSlots
, NULL
);
3627 ALContext
->Device
= device
;
3629 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3631 almtx_unlock(&device
->BackendLock
);
3636 alcSetError(device
, err
);
3637 if(err
== ALC_INVALID_DEVICE
)
3639 V0(device
->Backend
,lock
)();
3640 aluHandleDisconnect(device
);
3641 V0(device
->Backend
,unlock
)();
3643 ALCdevice_DecRef(device
);
3646 AllocateVoices(ALContext
, 256, device
->NumAuxSends
);
3648 if(DefaultEffect
.type
!= AL_EFFECT_NULL
&& device
->Type
== Playback
)
3650 ALContext
->DefaultSlot
= (ALeffectslot
*)(ALContext
->_listener_mem
+ sizeof(ALlistener
));
3651 if(InitEffectSlot(ALContext
->DefaultSlot
) == AL_NO_ERROR
)
3652 aluInitEffectPanning(ALContext
->DefaultSlot
);
3655 ALContext
->DefaultSlot
= NULL
;
3656 ERR("Failed to initialize the default effect slot\n");
3660 ALCdevice_IncRef(ALContext
->Device
);
3661 InitContext(ALContext
);
3663 if(ConfigValueFloat(alstr_get_cstr(device
->DeviceName
), NULL
, "volume-adjust", &valf
))
3666 ERR("volume-adjust must be finite: %f\n", valf
);
3669 ALfloat db
= clampf(valf
, -24.0f
, 24.0f
);
3671 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf
, 24.0f
);
3672 ALContext
->GainBoost
= powf(10.0f
, db
/20.0f
);
3673 TRACE("volume-adjust gain: %f\n", ALContext
->GainBoost
);
3676 UpdateListenerProps(ALContext
);
3679 ALCcontext
*head
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
3681 ALContext
->next
= head
;
3682 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device
->ContextList
, &head
,
3685 almtx_unlock(&device
->BackendLock
);
3687 if(ALContext
->DefaultSlot
)
3689 if(InitializeEffect(device
, ALContext
->DefaultSlot
, &DefaultEffect
) == AL_NO_ERROR
)
3690 UpdateEffectSlotProps(ALContext
->DefaultSlot
);
3692 ERR("Failed to initialize the default effect\n");
3695 ALCdevice_DecRef(device
);
3697 TRACE("Created context %p\n", ALContext
);
3701 /* alcDestroyContext
3703 * Remove a context from its device
3705 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3710 if(!VerifyContext(&context
))
3713 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3717 Device
= context
->Device
;
3720 almtx_lock(&Device
->BackendLock
);
3721 if(!ReleaseContext(context
, Device
))
3723 V0(Device
->Backend
,stop
)();
3724 Device
->Flags
&= ~DEVICE_RUNNING
;
3726 almtx_unlock(&Device
->BackendLock
);
3730 ALCcontext_DecRef(context
);
3734 /* alcGetCurrentContext
3736 * Returns the currently active context on the calling thread
3738 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3740 ALCcontext
*Context
= altss_get(LocalContext
);
3741 if(!Context
) Context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
3745 /* alcGetThreadContext
3747 * Returns the currently active thread-local context
3749 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3751 return altss_get(LocalContext
);
3755 /* alcMakeContextCurrent
3757 * Makes the given context the active process-wide context, and removes the
3758 * thread-local context for the calling thread.
3760 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3762 /* context must be valid or NULL */
3763 if(context
&& !VerifyContext(&context
))
3765 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3768 /* context's reference count is already incremented */
3769 context
= ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext
, context
);
3770 if(context
) ALCcontext_DecRef(context
);
3772 if((context
=altss_get(LocalContext
)) != NULL
)
3774 altss_set(LocalContext
, NULL
);
3775 ALCcontext_DecRef(context
);
3781 /* alcSetThreadContext
3783 * Makes the given context the active context for the current thread
3785 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3789 /* context must be valid or NULL */
3790 if(context
&& !VerifyContext(&context
))
3792 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3795 /* context's reference count is already incremented */
3796 old
= altss_get(LocalContext
);
3797 altss_set(LocalContext
, context
);
3798 if(old
) ALCcontext_DecRef(old
);
3804 /* alcGetContextsDevice
3806 * Returns the device that a particular context is attached to
3808 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3812 if(!VerifyContext(&Context
))
3814 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3817 Device
= Context
->Device
;
3818 ALCcontext_DecRef(Context
);
3826 * Opens the named device.
3828 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3830 ALCbackendFactory
*factory
;
3838 if(!PlaybackBackend
.name
)
3840 alcSetError(NULL
, ALC_INVALID_VALUE
);
3844 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3846 /* Some old Windows apps hardcode these expecting OpenAL to use a
3847 * specific audio API, even when they're not enumerated. Creative's
3848 * router effectively ignores them too.
3850 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3851 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3856 device
= al_calloc(16, sizeof(ALCdevice
));
3859 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3864 InitRef(&device
->ref
, 1);
3865 device
->Connected
= ALC_TRUE
;
3866 device
->Type
= Playback
;
3867 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3870 device
->Bs2b
= NULL
;
3871 device
->Uhj_Encoder
= NULL
;
3872 device
->Hrtf
= NULL
;
3873 device
->HrtfHandle
= NULL
;
3874 VECTOR_INIT(device
->HrtfList
);
3875 AL_STRING_INIT(device
->HrtfName
);
3876 device
->Render_Mode
= NormalRender
;
3877 AL_STRING_INIT(device
->DeviceName
);
3878 device
->Dry
.Buffer
= NULL
;
3879 device
->Dry
.NumChannels
= 0;
3880 device
->FOAOut
.Buffer
= NULL
;
3881 device
->FOAOut
.NumChannels
= 0;
3882 device
->RealOut
.Buffer
= NULL
;
3883 device
->RealOut
.NumChannels
= 0;
3884 device
->Limiter
= NULL
;
3885 device
->AvgSpeakerDist
= 0.0f
;
3887 ATOMIC_INIT(&device
->ContextList
, NULL
);
3889 device
->ClockBase
= 0;
3890 device
->SamplesDone
= 0;
3892 device
->SourcesMax
= 256;
3893 device
->AuxiliaryEffectSlotMax
= 64;
3894 device
->NumAuxSends
= DEFAULT_SENDS
;
3896 InitUIntMap(&device
->BufferMap
, INT_MAX
);
3897 InitUIntMap(&device
->EffectMap
, INT_MAX
);
3898 InitUIntMap(&device
->FilterMap
, INT_MAX
);
3900 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
3902 device
->ChannelDelay
[i
].Gain
= 1.0f
;
3903 device
->ChannelDelay
[i
].Length
= 0;
3904 device
->ChannelDelay
[i
].Buffer
= NULL
;
3908 device
->FmtChans
= DevFmtChannelsDefault
;
3909 device
->FmtType
= DevFmtTypeDefault
;
3910 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3911 device
->IsHeadphones
= AL_FALSE
;
3912 device
->AmbiLayout
= AmbiLayout_Default
;
3913 device
->AmbiScale
= AmbiNorm_Default
;
3914 device
->NumUpdates
= 3;
3915 device
->UpdateSize
= 1024;
3917 factory
= PlaybackBackend
.getFactory();
3918 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3919 if(!device
->Backend
)
3922 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3927 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3929 static const struct {
3930 const char name
[16];
3931 enum DevFmtChannels chans
;
3934 { "mono", DevFmtMono
, 0 },
3935 { "stereo", DevFmtStereo
, 0 },
3936 { "quad", DevFmtQuad
, 0 },
3937 { "surround51", DevFmtX51
, 0 },
3938 { "surround61", DevFmtX61
, 0 },
3939 { "surround71", DevFmtX71
, 0 },
3940 { "surround51rear", DevFmtX51Rear
, 0 },
3941 { "ambi1", DevFmtAmbi3D
, 1 },
3942 { "ambi2", DevFmtAmbi3D
, 2 },
3943 { "ambi3", DevFmtAmbi3D
, 3 },
3947 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3949 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3951 device
->FmtChans
= chanlist
[i
].chans
;
3952 device
->AmbiOrder
= chanlist
[i
].order
;
3953 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3957 if(i
== COUNTOF(chanlist
))
3958 ERR("Unsupported channels: %s\n", fmt
);
3960 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3962 static const struct {
3963 const char name
[16];
3964 enum DevFmtType type
;
3966 { "int8", DevFmtByte
},
3967 { "uint8", DevFmtUByte
},
3968 { "int16", DevFmtShort
},
3969 { "uint16", DevFmtUShort
},
3970 { "int32", DevFmtInt
},
3971 { "uint32", DevFmtUInt
},
3972 { "float32", DevFmtFloat
},
3976 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3978 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3980 device
->FmtType
= typelist
[i
].type
;
3981 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3985 if(i
== COUNTOF(typelist
))
3986 ERR("Unsupported sample-type: %s\n", fmt
);
3989 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3991 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3992 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3993 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3994 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3997 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3998 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
4000 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
4001 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
4002 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
4003 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
4005 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
4006 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4008 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4009 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4011 if(ConfigValueInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
))
4012 device
->NumAuxSends
= clampi(
4013 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4016 device
->NumStereoSources
= 1;
4017 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4019 // Find a playback device to open
4020 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4022 DELETE_OBJ(device
->Backend
);
4024 alcSetError(NULL
, err
);
4027 almtx_init(&device
->BackendLock
, almtx_plain
);
4029 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "ambi-format", &fmt
))
4031 if(strcasecmp(fmt
, "fuma") == 0)
4033 device
->AmbiLayout
= AmbiLayout_FuMa
;
4034 device
->AmbiScale
= AmbiNorm_FuMa
;
4036 else if(strcasecmp(fmt
, "acn+sn3d") == 0)
4038 device
->AmbiLayout
= AmbiLayout_ACN
;
4039 device
->AmbiScale
= AmbiNorm_SN3D
;
4041 else if(strcasecmp(fmt
, "acn+n3d") == 0)
4043 device
->AmbiLayout
= AmbiLayout_ACN
;
4044 device
->AmbiScale
= AmbiNorm_N3D
;
4047 ERR("Unsupported ambi-format: %s\n", fmt
);
4050 device
->Limiter
= CreateDeviceLimiter(device
);
4053 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4055 device
->next
= head
;
4056 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4059 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4065 * Closes the given device.
4067 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
4069 ALCdevice
*iter
, *origdev
;
4073 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4077 } while((iter
=iter
->next
) != NULL
);
4078 if(!iter
|| iter
->Type
== Capture
)
4080 alcSetError(iter
, ALC_INVALID_DEVICE
);
4084 almtx_lock(&device
->BackendLock
);
4087 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4089 ALCdevice
*volatile*list
= &origdev
->next
;
4094 *list
= (*list
)->next
;
4097 list
= &(*list
)->next
;
4102 ctx
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
4105 ALCcontext
*next
= ctx
->next
;
4106 WARN("Releasing context %p\n", ctx
);
4107 ReleaseContext(ctx
, device
);
4110 if((device
->Flags
&DEVICE_RUNNING
))
4111 V0(device
->Backend
,stop
)();
4112 device
->Flags
&= ~DEVICE_RUNNING
;
4113 almtx_unlock(&device
->BackendLock
);
4115 ALCdevice_DecRef(device
);
4121 /************************************************
4122 * ALC capture functions
4123 ************************************************/
4124 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
4126 ALCbackendFactory
*factory
;
4127 ALCdevice
*device
= NULL
;
4133 if(!CaptureBackend
.name
)
4135 alcSetError(NULL
, ALC_INVALID_VALUE
);
4141 alcSetError(NULL
, ALC_INVALID_VALUE
);
4145 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
4148 device
= al_calloc(16, sizeof(ALCdevice
));
4151 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4156 InitRef(&device
->ref
, 1);
4157 device
->Connected
= ALC_TRUE
;
4158 device
->Type
= Capture
;
4160 device
->Hrtf
= NULL
;
4161 device
->HrtfHandle
= NULL
;
4162 VECTOR_INIT(device
->HrtfList
);
4163 AL_STRING_INIT(device
->HrtfName
);
4165 AL_STRING_INIT(device
->DeviceName
);
4166 device
->Dry
.Buffer
= NULL
;
4167 device
->Dry
.NumChannels
= 0;
4168 device
->FOAOut
.Buffer
= NULL
;
4169 device
->FOAOut
.NumChannels
= 0;
4170 device
->RealOut
.Buffer
= NULL
;
4171 device
->RealOut
.NumChannels
= 0;
4173 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4174 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4175 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4177 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4179 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4180 device
->ChannelDelay
[i
].Length
= 0;
4181 device
->ChannelDelay
[i
].Buffer
= NULL
;
4184 factory
= CaptureBackend
.getFactory();
4185 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
4186 if(!device
->Backend
)
4189 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4193 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4194 device
->Frequency
= frequency
;
4196 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
4197 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
4200 alcSetError(NULL
, ALC_INVALID_ENUM
);
4203 device
->IsHeadphones
= AL_FALSE
;
4204 device
->AmbiOrder
= 0;
4205 device
->AmbiLayout
= AmbiLayout_Default
;
4206 device
->AmbiScale
= AmbiNorm_Default
;
4208 device
->UpdateSize
= samples
;
4209 device
->NumUpdates
= 1;
4211 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4212 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
4213 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
4215 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4218 alcSetError(NULL
, err
);
4221 almtx_init(&device
->BackendLock
, almtx_plain
);
4224 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4226 device
->next
= head
;
4227 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4230 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4234 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
4236 ALCdevice
*iter
, *origdev
;
4239 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4243 } while((iter
=iter
->next
) != NULL
);
4244 if(!iter
|| iter
->Type
!= Capture
)
4246 alcSetError(iter
, ALC_INVALID_DEVICE
);
4252 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4254 ALCdevice
*volatile*list
= &origdev
->next
;
4259 *list
= (*list
)->next
;
4262 list
= &(*list
)->next
;
4267 ALCdevice_DecRef(device
);
4272 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
4274 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4275 alcSetError(device
, ALC_INVALID_DEVICE
);
4278 almtx_lock(&device
->BackendLock
);
4279 if(!device
->Connected
)
4280 alcSetError(device
, ALC_INVALID_DEVICE
);
4281 else if(!(device
->Flags
&DEVICE_RUNNING
))
4283 if(V0(device
->Backend
,start
)())
4284 device
->Flags
|= DEVICE_RUNNING
;
4287 aluHandleDisconnect(device
);
4288 alcSetError(device
, ALC_INVALID_DEVICE
);
4291 almtx_unlock(&device
->BackendLock
);
4294 if(device
) ALCdevice_DecRef(device
);
4297 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
4299 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4300 alcSetError(device
, ALC_INVALID_DEVICE
);
4303 almtx_lock(&device
->BackendLock
);
4304 if((device
->Flags
&DEVICE_RUNNING
))
4305 V0(device
->Backend
,stop
)();
4306 device
->Flags
&= ~DEVICE_RUNNING
;
4307 almtx_unlock(&device
->BackendLock
);
4310 if(device
) ALCdevice_DecRef(device
);
4313 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4315 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4316 alcSetError(device
, ALC_INVALID_DEVICE
);
4319 ALCenum err
= ALC_INVALID_VALUE
;
4321 almtx_lock(&device
->BackendLock
);
4322 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
4323 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
4324 almtx_unlock(&device
->BackendLock
);
4326 if(err
!= ALC_NO_ERROR
)
4327 alcSetError(device
, err
);
4329 if(device
) ALCdevice_DecRef(device
);
4333 /************************************************
4334 * ALC loopback functions
4335 ************************************************/
4337 /* alcLoopbackOpenDeviceSOFT
4339 * Open a loopback device, for manual rendering.
4341 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
4343 ALCbackendFactory
*factory
;
4349 /* Make sure the device name, if specified, is us. */
4350 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
4352 alcSetError(NULL
, ALC_INVALID_VALUE
);
4356 device
= al_calloc(16, sizeof(ALCdevice
));
4359 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4364 InitRef(&device
->ref
, 1);
4365 device
->Connected
= ALC_TRUE
;
4366 device
->Type
= Loopback
;
4367 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
4370 device
->Hrtf
= NULL
;
4371 device
->HrtfHandle
= NULL
;
4372 VECTOR_INIT(device
->HrtfList
);
4373 AL_STRING_INIT(device
->HrtfName
);
4374 device
->Bs2b
= NULL
;
4375 device
->Uhj_Encoder
= NULL
;
4376 device
->Render_Mode
= NormalRender
;
4377 AL_STRING_INIT(device
->DeviceName
);
4378 device
->Dry
.Buffer
= NULL
;
4379 device
->Dry
.NumChannels
= 0;
4380 device
->FOAOut
.Buffer
= NULL
;
4381 device
->FOAOut
.NumChannels
= 0;
4382 device
->RealOut
.Buffer
= NULL
;
4383 device
->RealOut
.NumChannels
= 0;
4384 device
->Limiter
= NULL
;
4385 device
->AvgSpeakerDist
= 0.0f
;
4387 ATOMIC_INIT(&device
->ContextList
, NULL
);
4389 device
->ClockBase
= 0;
4390 device
->SamplesDone
= 0;
4392 device
->SourcesMax
= 256;
4393 device
->AuxiliaryEffectSlotMax
= 64;
4394 device
->NumAuxSends
= DEFAULT_SENDS
;
4396 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4397 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4398 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4400 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4402 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4403 device
->ChannelDelay
[i
].Length
= 0;
4404 device
->ChannelDelay
[i
].Buffer
= NULL
;
4407 factory
= ALCloopbackFactory_getFactory();
4408 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
4409 if(!device
->Backend
)
4412 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4415 almtx_init(&device
->BackendLock
, almtx_plain
);
4418 device
->NumUpdates
= 0;
4419 device
->UpdateSize
= 0;
4421 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
4422 device
->FmtChans
= DevFmtChannelsDefault
;
4423 device
->FmtType
= DevFmtTypeDefault
;
4424 device
->IsHeadphones
= AL_FALSE
;
4425 device
->AmbiLayout
= AmbiLayout_Default
;
4426 device
->AmbiScale
= AmbiNorm_Default
;
4428 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
4429 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4431 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4432 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4434 if(ConfigValueInt(NULL
, NULL
, "sends", &device
->NumAuxSends
))
4435 device
->NumAuxSends
= clampi(
4436 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4439 device
->NumStereoSources
= 1;
4440 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4442 // Open the "backend"
4443 V(device
->Backend
,open
)("Loopback");
4445 device
->Limiter
= CreateDeviceLimiter(device
);
4448 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4450 device
->next
= head
;
4451 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4454 TRACE("Created device %p\n", device
);
4458 /* alcIsRenderFormatSupportedSOFT
4460 * Determines if the loopback device supports the given format for rendering.
4462 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
4464 ALCboolean ret
= ALC_FALSE
;
4466 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4467 alcSetError(device
, ALC_INVALID_DEVICE
);
4469 alcSetError(device
, ALC_INVALID_VALUE
);
4472 if(IsValidALCType(type
) && IsValidALCChannels(channels
) && freq
>= MIN_OUTPUT_RATE
)
4475 if(device
) ALCdevice_DecRef(device
);
4480 /* alcRenderSamplesSOFT
4482 * Renders some samples into a buffer, using the format last set by the
4483 * attributes given to alcCreateContext.
4485 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4487 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4488 alcSetError(device
, ALC_INVALID_DEVICE
);
4489 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
4490 alcSetError(device
, ALC_INVALID_VALUE
);
4493 V0(device
->Backend
,lock
)();
4494 aluMixData(device
, buffer
, samples
);
4495 V0(device
->Backend
,unlock
)();
4497 if(device
) ALCdevice_DecRef(device
);
4501 /************************************************
4502 * ALC loopback2 functions
4503 ************************************************/
4505 ALC_API ALCboolean ALC_APIENTRY
alcIsAmbisonicFormatSupportedSOFT(ALCdevice
*device
, ALCenum layout
, ALCenum scaling
, ALsizei order
)
4507 ALCboolean ret
= ALC_FALSE
;
4509 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4510 alcSetError(device
, ALC_INVALID_DEVICE
);
4512 alcSetError(device
, ALC_INVALID_VALUE
);
4515 if(IsValidAmbiLayout(layout
) && IsValidAmbiScaling(scaling
) && order
<= MAX_AMBI_ORDER
)
4518 if(device
) ALCdevice_DecRef(device
);
4523 /************************************************
4524 * ALC DSP pause/resume functions
4525 ************************************************/
4527 /* alcDevicePauseSOFT
4529 * Pause the DSP to stop audio processing.
4531 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
4533 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4534 alcSetError(device
, ALC_INVALID_DEVICE
);
4537 almtx_lock(&device
->BackendLock
);
4538 if((device
->Flags
&DEVICE_RUNNING
))
4539 V0(device
->Backend
,stop
)();
4540 device
->Flags
&= ~DEVICE_RUNNING
;
4541 device
->Flags
|= DEVICE_PAUSED
;
4542 almtx_unlock(&device
->BackendLock
);
4544 if(device
) ALCdevice_DecRef(device
);
4547 /* alcDeviceResumeSOFT
4549 * Resume the DSP to restart audio processing.
4551 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
4553 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4554 alcSetError(device
, ALC_INVALID_DEVICE
);
4557 almtx_lock(&device
->BackendLock
);
4558 if((device
->Flags
&DEVICE_PAUSED
))
4560 device
->Flags
&= ~DEVICE_PAUSED
;
4561 if(ATOMIC_LOAD_SEQ(&device
->ContextList
) != NULL
)
4563 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4564 device
->Flags
|= DEVICE_RUNNING
;
4567 alcSetError(device
, ALC_INVALID_DEVICE
);
4568 V0(device
->Backend
,lock
)();
4569 aluHandleDisconnect(device
);
4570 V0(device
->Backend
,unlock
)();
4574 almtx_unlock(&device
->BackendLock
);
4576 if(device
) ALCdevice_DecRef(device
);
4580 /************************************************
4581 * ALC HRTF functions
4582 ************************************************/
4584 /* alcGetStringiSOFT
4586 * Gets a string parameter at the given index.
4588 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4590 const ALCchar
*str
= NULL
;
4592 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4593 alcSetError(device
, ALC_INVALID_DEVICE
);
4594 else switch(paramName
)
4596 case ALC_HRTF_SPECIFIER_SOFT
:
4597 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->HrtfList
))
4598 str
= alstr_get_cstr(VECTOR_ELEM(device
->HrtfList
, index
).name
);
4600 alcSetError(device
, ALC_INVALID_VALUE
);
4604 alcSetError(device
, ALC_INVALID_ENUM
);
4607 if(device
) ALCdevice_DecRef(device
);
4612 /* alcResetDeviceSOFT
4614 * Resets the given device output, using the specified attribute list.
4616 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4621 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4624 alcSetError(device
, ALC_INVALID_DEVICE
);
4625 if(device
) ALCdevice_DecRef(device
);
4628 almtx_lock(&device
->BackendLock
);
4631 err
= UpdateDeviceParams(device
, attribs
);
4632 almtx_unlock(&device
->BackendLock
);
4634 if(err
!= ALC_NO_ERROR
)
4636 alcSetError(device
, err
);
4637 if(err
== ALC_INVALID_DEVICE
)
4639 V0(device
->Backend
,lock
)();
4640 aluHandleDisconnect(device
);
4641 V0(device
->Backend
,unlock
)();
4643 ALCdevice_DecRef(device
);
4646 ALCdevice_DecRef(device
);