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
)
3653 ALContext
->DefaultSlot
= NULL
;
3654 ERR("Failed to initialize the default effect slot\n");
3658 aluInitEffectPanning(ALContext
->DefaultSlot
);
3659 if(InitializeEffect(device
, ALContext
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3661 DeinitEffectSlot(ALContext
->DefaultSlot
);
3662 ALContext
->DefaultSlot
= NULL
;
3663 ERR("Failed to initialize the default effect\n");
3666 if(ALContext
->DefaultSlot
)
3668 ALeffectslot
*slot
= ALContext
->DefaultSlot
;
3669 ALeffectState
*state
= slot
->Effect
.State
;
3672 state
->OutBuffer
= device
->Dry
.Buffer
;
3673 state
->OutChannels
= device
->Dry
.NumChannels
;
3674 if(V(state
,deviceUpdate
)(device
) != AL_FALSE
)
3675 UpdateEffectSlotProps(slot
);
3678 DeinitEffectSlot(ALContext
->DefaultSlot
);
3679 ALContext
->DefaultSlot
= NULL
;
3685 ALCdevice_IncRef(ALContext
->Device
);
3686 InitContext(ALContext
);
3688 if(ConfigValueFloat(alstr_get_cstr(device
->DeviceName
), NULL
, "volume-adjust", &valf
))
3691 ERR("volume-adjust must be finite: %f\n", valf
);
3694 ALfloat db
= clampf(valf
, -24.0f
, 24.0f
);
3696 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf
, 24.0f
);
3697 ALContext
->GainBoost
= powf(10.0f
, db
/20.0f
);
3698 TRACE("volume-adjust gain: %f\n", ALContext
->GainBoost
);
3701 UpdateListenerProps(ALContext
);
3704 ALCcontext
*head
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
3706 ALContext
->next
= head
;
3707 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device
->ContextList
, &head
,
3710 almtx_unlock(&device
->BackendLock
);
3712 ALCdevice_DecRef(device
);
3714 TRACE("Created context %p\n", ALContext
);
3718 /* alcDestroyContext
3720 * Remove a context from its device
3722 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3727 if(!VerifyContext(&context
))
3730 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3734 Device
= context
->Device
;
3737 almtx_lock(&Device
->BackendLock
);
3738 if(!ReleaseContext(context
, Device
))
3740 V0(Device
->Backend
,stop
)();
3741 Device
->Flags
&= ~DEVICE_RUNNING
;
3743 almtx_unlock(&Device
->BackendLock
);
3747 ALCcontext_DecRef(context
);
3751 /* alcGetCurrentContext
3753 * Returns the currently active context on the calling thread
3755 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3757 ALCcontext
*Context
= altss_get(LocalContext
);
3758 if(!Context
) Context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
3762 /* alcGetThreadContext
3764 * Returns the currently active thread-local context
3766 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3768 return altss_get(LocalContext
);
3772 /* alcMakeContextCurrent
3774 * Makes the given context the active process-wide context, and removes the
3775 * thread-local context for the calling thread.
3777 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3779 /* context must be valid or NULL */
3780 if(context
&& !VerifyContext(&context
))
3782 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3785 /* context's reference count is already incremented */
3786 context
= ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext
, context
);
3787 if(context
) ALCcontext_DecRef(context
);
3789 if((context
=altss_get(LocalContext
)) != NULL
)
3791 altss_set(LocalContext
, NULL
);
3792 ALCcontext_DecRef(context
);
3798 /* alcSetThreadContext
3800 * Makes the given context the active context for the current thread
3802 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3806 /* context must be valid or NULL */
3807 if(context
&& !VerifyContext(&context
))
3809 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3812 /* context's reference count is already incremented */
3813 old
= altss_get(LocalContext
);
3814 altss_set(LocalContext
, context
);
3815 if(old
) ALCcontext_DecRef(old
);
3821 /* alcGetContextsDevice
3823 * Returns the device that a particular context is attached to
3825 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3829 if(!VerifyContext(&Context
))
3831 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3834 Device
= Context
->Device
;
3835 ALCcontext_DecRef(Context
);
3843 * Opens the named device.
3845 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3847 ALCbackendFactory
*factory
;
3855 if(!PlaybackBackend
.name
)
3857 alcSetError(NULL
, ALC_INVALID_VALUE
);
3861 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3863 /* Some old Windows apps hardcode these expecting OpenAL to use a
3864 * specific audio API, even when they're not enumerated. Creative's
3865 * router effectively ignores them too.
3867 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3868 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3873 device
= al_calloc(16, sizeof(ALCdevice
));
3876 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3881 InitRef(&device
->ref
, 1);
3882 device
->Connected
= ALC_TRUE
;
3883 device
->Type
= Playback
;
3884 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3887 device
->Bs2b
= NULL
;
3888 device
->Uhj_Encoder
= NULL
;
3889 device
->Hrtf
= NULL
;
3890 device
->HrtfHandle
= NULL
;
3891 VECTOR_INIT(device
->HrtfList
);
3892 AL_STRING_INIT(device
->HrtfName
);
3893 device
->Render_Mode
= NormalRender
;
3894 AL_STRING_INIT(device
->DeviceName
);
3895 device
->Dry
.Buffer
= NULL
;
3896 device
->Dry
.NumChannels
= 0;
3897 device
->FOAOut
.Buffer
= NULL
;
3898 device
->FOAOut
.NumChannels
= 0;
3899 device
->RealOut
.Buffer
= NULL
;
3900 device
->RealOut
.NumChannels
= 0;
3901 device
->Limiter
= NULL
;
3902 device
->AvgSpeakerDist
= 0.0f
;
3904 ATOMIC_INIT(&device
->ContextList
, NULL
);
3906 device
->ClockBase
= 0;
3907 device
->SamplesDone
= 0;
3909 device
->SourcesMax
= 256;
3910 device
->AuxiliaryEffectSlotMax
= 64;
3911 device
->NumAuxSends
= DEFAULT_SENDS
;
3913 InitUIntMap(&device
->BufferMap
, INT_MAX
);
3914 InitUIntMap(&device
->EffectMap
, INT_MAX
);
3915 InitUIntMap(&device
->FilterMap
, INT_MAX
);
3917 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
3919 device
->ChannelDelay
[i
].Gain
= 1.0f
;
3920 device
->ChannelDelay
[i
].Length
= 0;
3921 device
->ChannelDelay
[i
].Buffer
= NULL
;
3925 device
->FmtChans
= DevFmtChannelsDefault
;
3926 device
->FmtType
= DevFmtTypeDefault
;
3927 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3928 device
->IsHeadphones
= AL_FALSE
;
3929 device
->AmbiLayout
= AmbiLayout_Default
;
3930 device
->AmbiScale
= AmbiNorm_Default
;
3931 device
->NumUpdates
= 3;
3932 device
->UpdateSize
= 1024;
3934 factory
= PlaybackBackend
.getFactory();
3935 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3936 if(!device
->Backend
)
3939 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3944 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3946 static const struct {
3947 const char name
[16];
3948 enum DevFmtChannels chans
;
3951 { "mono", DevFmtMono
, 0 },
3952 { "stereo", DevFmtStereo
, 0 },
3953 { "quad", DevFmtQuad
, 0 },
3954 { "surround51", DevFmtX51
, 0 },
3955 { "surround61", DevFmtX61
, 0 },
3956 { "surround71", DevFmtX71
, 0 },
3957 { "surround51rear", DevFmtX51Rear
, 0 },
3958 { "ambi1", DevFmtAmbi3D
, 1 },
3959 { "ambi2", DevFmtAmbi3D
, 2 },
3960 { "ambi3", DevFmtAmbi3D
, 3 },
3964 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3966 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3968 device
->FmtChans
= chanlist
[i
].chans
;
3969 device
->AmbiOrder
= chanlist
[i
].order
;
3970 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3974 if(i
== COUNTOF(chanlist
))
3975 ERR("Unsupported channels: %s\n", fmt
);
3977 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3979 static const struct {
3980 const char name
[16];
3981 enum DevFmtType type
;
3983 { "int8", DevFmtByte
},
3984 { "uint8", DevFmtUByte
},
3985 { "int16", DevFmtShort
},
3986 { "uint16", DevFmtUShort
},
3987 { "int32", DevFmtInt
},
3988 { "uint32", DevFmtUInt
},
3989 { "float32", DevFmtFloat
},
3993 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3995 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3997 device
->FmtType
= typelist
[i
].type
;
3998 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
4002 if(i
== COUNTOF(typelist
))
4003 ERR("Unsupported sample-type: %s\n", fmt
);
4006 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
4008 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4009 if(device
->Frequency
< MIN_OUTPUT_RATE
)
4010 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
4011 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
4014 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
4015 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
4017 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
4018 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
4019 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
4020 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
4022 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
4023 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4025 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4026 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4028 if(ConfigValueInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
))
4029 device
->NumAuxSends
= clampi(
4030 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4033 device
->NumStereoSources
= 1;
4034 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4036 // Find a playback device to open
4037 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4039 DELETE_OBJ(device
->Backend
);
4041 alcSetError(NULL
, err
);
4044 almtx_init(&device
->BackendLock
, almtx_plain
);
4046 if(ConfigValueStr(alstr_get_cstr(device
->DeviceName
), NULL
, "ambi-format", &fmt
))
4048 if(strcasecmp(fmt
, "fuma") == 0)
4050 device
->AmbiLayout
= AmbiLayout_FuMa
;
4051 device
->AmbiScale
= AmbiNorm_FuMa
;
4053 else if(strcasecmp(fmt
, "acn+sn3d") == 0)
4055 device
->AmbiLayout
= AmbiLayout_ACN
;
4056 device
->AmbiScale
= AmbiNorm_SN3D
;
4058 else if(strcasecmp(fmt
, "acn+n3d") == 0)
4060 device
->AmbiLayout
= AmbiLayout_ACN
;
4061 device
->AmbiScale
= AmbiNorm_N3D
;
4064 ERR("Unsupported ambi-format: %s\n", fmt
);
4067 device
->Limiter
= CreateDeviceLimiter(device
);
4070 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4072 device
->next
= head
;
4073 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4076 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4082 * Closes the given device.
4084 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
4086 ALCdevice
*iter
, *origdev
;
4090 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4094 } while((iter
=iter
->next
) != NULL
);
4095 if(!iter
|| iter
->Type
== Capture
)
4097 alcSetError(iter
, ALC_INVALID_DEVICE
);
4101 almtx_lock(&device
->BackendLock
);
4104 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4106 ALCdevice
*volatile*list
= &origdev
->next
;
4111 *list
= (*list
)->next
;
4114 list
= &(*list
)->next
;
4119 ctx
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
4122 ALCcontext
*next
= ctx
->next
;
4123 WARN("Releasing context %p\n", ctx
);
4124 ReleaseContext(ctx
, device
);
4127 if((device
->Flags
&DEVICE_RUNNING
))
4128 V0(device
->Backend
,stop
)();
4129 device
->Flags
&= ~DEVICE_RUNNING
;
4130 almtx_unlock(&device
->BackendLock
);
4132 ALCdevice_DecRef(device
);
4138 /************************************************
4139 * ALC capture functions
4140 ************************************************/
4141 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
4143 ALCbackendFactory
*factory
;
4144 ALCdevice
*device
= NULL
;
4150 if(!CaptureBackend
.name
)
4152 alcSetError(NULL
, ALC_INVALID_VALUE
);
4158 alcSetError(NULL
, ALC_INVALID_VALUE
);
4162 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
4165 device
= al_calloc(16, sizeof(ALCdevice
));
4168 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4173 InitRef(&device
->ref
, 1);
4174 device
->Connected
= ALC_TRUE
;
4175 device
->Type
= Capture
;
4177 device
->Hrtf
= NULL
;
4178 device
->HrtfHandle
= NULL
;
4179 VECTOR_INIT(device
->HrtfList
);
4180 AL_STRING_INIT(device
->HrtfName
);
4182 AL_STRING_INIT(device
->DeviceName
);
4183 device
->Dry
.Buffer
= NULL
;
4184 device
->Dry
.NumChannels
= 0;
4185 device
->FOAOut
.Buffer
= NULL
;
4186 device
->FOAOut
.NumChannels
= 0;
4187 device
->RealOut
.Buffer
= NULL
;
4188 device
->RealOut
.NumChannels
= 0;
4190 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4191 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4192 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4194 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4196 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4197 device
->ChannelDelay
[i
].Length
= 0;
4198 device
->ChannelDelay
[i
].Buffer
= NULL
;
4201 factory
= CaptureBackend
.getFactory();
4202 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
4203 if(!device
->Backend
)
4206 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4210 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
4211 device
->Frequency
= frequency
;
4213 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
4214 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
4217 alcSetError(NULL
, ALC_INVALID_ENUM
);
4220 device
->IsHeadphones
= AL_FALSE
;
4221 device
->AmbiOrder
= 0;
4222 device
->AmbiLayout
= AmbiLayout_Default
;
4223 device
->AmbiScale
= AmbiNorm_Default
;
4225 device
->UpdateSize
= samples
;
4226 device
->NumUpdates
= 1;
4228 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4229 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
4230 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
4232 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
4235 alcSetError(NULL
, err
);
4238 almtx_init(&device
->BackendLock
, almtx_plain
);
4241 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4243 device
->next
= head
;
4244 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4247 TRACE("Created device %p, \"%s\"\n", device
, alstr_get_cstr(device
->DeviceName
));
4251 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
4253 ALCdevice
*iter
, *origdev
;
4256 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
4260 } while((iter
=iter
->next
) != NULL
);
4261 if(!iter
|| iter
->Type
!= Capture
)
4263 alcSetError(iter
, ALC_INVALID_DEVICE
);
4269 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList
, &origdev
, device
->next
))
4271 ALCdevice
*volatile*list
= &origdev
->next
;
4276 *list
= (*list
)->next
;
4279 list
= &(*list
)->next
;
4284 ALCdevice_DecRef(device
);
4289 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
4291 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4292 alcSetError(device
, ALC_INVALID_DEVICE
);
4295 almtx_lock(&device
->BackendLock
);
4296 if(!device
->Connected
)
4297 alcSetError(device
, ALC_INVALID_DEVICE
);
4298 else if(!(device
->Flags
&DEVICE_RUNNING
))
4300 if(V0(device
->Backend
,start
)())
4301 device
->Flags
|= DEVICE_RUNNING
;
4304 aluHandleDisconnect(device
);
4305 alcSetError(device
, ALC_INVALID_DEVICE
);
4308 almtx_unlock(&device
->BackendLock
);
4311 if(device
) ALCdevice_DecRef(device
);
4314 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
4316 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4317 alcSetError(device
, ALC_INVALID_DEVICE
);
4320 almtx_lock(&device
->BackendLock
);
4321 if((device
->Flags
&DEVICE_RUNNING
))
4322 V0(device
->Backend
,stop
)();
4323 device
->Flags
&= ~DEVICE_RUNNING
;
4324 almtx_unlock(&device
->BackendLock
);
4327 if(device
) ALCdevice_DecRef(device
);
4330 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4332 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4333 alcSetError(device
, ALC_INVALID_DEVICE
);
4336 ALCenum err
= ALC_INVALID_VALUE
;
4338 almtx_lock(&device
->BackendLock
);
4339 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
4340 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
4341 almtx_unlock(&device
->BackendLock
);
4343 if(err
!= ALC_NO_ERROR
)
4344 alcSetError(device
, err
);
4346 if(device
) ALCdevice_DecRef(device
);
4350 /************************************************
4351 * ALC loopback functions
4352 ************************************************/
4354 /* alcLoopbackOpenDeviceSOFT
4356 * Open a loopback device, for manual rendering.
4358 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
4360 ALCbackendFactory
*factory
;
4366 /* Make sure the device name, if specified, is us. */
4367 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
4369 alcSetError(NULL
, ALC_INVALID_VALUE
);
4373 device
= al_calloc(16, sizeof(ALCdevice
));
4376 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4381 InitRef(&device
->ref
, 1);
4382 device
->Connected
= ALC_TRUE
;
4383 device
->Type
= Loopback
;
4384 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
4387 device
->Hrtf
= NULL
;
4388 device
->HrtfHandle
= NULL
;
4389 VECTOR_INIT(device
->HrtfList
);
4390 AL_STRING_INIT(device
->HrtfName
);
4391 device
->Bs2b
= NULL
;
4392 device
->Uhj_Encoder
= NULL
;
4393 device
->Render_Mode
= NormalRender
;
4394 AL_STRING_INIT(device
->DeviceName
);
4395 device
->Dry
.Buffer
= NULL
;
4396 device
->Dry
.NumChannels
= 0;
4397 device
->FOAOut
.Buffer
= NULL
;
4398 device
->FOAOut
.NumChannels
= 0;
4399 device
->RealOut
.Buffer
= NULL
;
4400 device
->RealOut
.NumChannels
= 0;
4401 device
->Limiter
= NULL
;
4402 device
->AvgSpeakerDist
= 0.0f
;
4404 ATOMIC_INIT(&device
->ContextList
, NULL
);
4406 device
->ClockBase
= 0;
4407 device
->SamplesDone
= 0;
4409 device
->SourcesMax
= 256;
4410 device
->AuxiliaryEffectSlotMax
= 64;
4411 device
->NumAuxSends
= DEFAULT_SENDS
;
4413 InitUIntMap(&device
->BufferMap
, INT_MAX
);
4414 InitUIntMap(&device
->EffectMap
, INT_MAX
);
4415 InitUIntMap(&device
->FilterMap
, INT_MAX
);
4417 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
4419 device
->ChannelDelay
[i
].Gain
= 1.0f
;
4420 device
->ChannelDelay
[i
].Length
= 0;
4421 device
->ChannelDelay
[i
].Buffer
= NULL
;
4424 factory
= ALCloopbackFactory_getFactory();
4425 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
4426 if(!device
->Backend
)
4429 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4432 almtx_init(&device
->BackendLock
, almtx_plain
);
4435 device
->NumUpdates
= 0;
4436 device
->UpdateSize
= 0;
4438 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
4439 device
->FmtChans
= DevFmtChannelsDefault
;
4440 device
->FmtType
= DevFmtTypeDefault
;
4441 device
->IsHeadphones
= AL_FALSE
;
4442 device
->AmbiLayout
= AmbiLayout_Default
;
4443 device
->AmbiScale
= AmbiNorm_Default
;
4445 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
4446 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4448 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4449 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4451 if(ConfigValueInt(NULL
, NULL
, "sends", &device
->NumAuxSends
))
4452 device
->NumAuxSends
= clampi(
4453 DEFAULT_SENDS
, 0, clampi(device
->NumAuxSends
, 0, MAX_SENDS
)
4456 device
->NumStereoSources
= 1;
4457 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4459 // Open the "backend"
4460 V(device
->Backend
,open
)("Loopback");
4462 device
->Limiter
= CreateDeviceLimiter(device
);
4465 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4467 device
->next
= head
;
4468 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList
, &head
, device
));
4471 TRACE("Created device %p\n", device
);
4475 /* alcIsRenderFormatSupportedSOFT
4477 * Determines if the loopback device supports the given format for rendering.
4479 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
4481 ALCboolean ret
= ALC_FALSE
;
4483 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4484 alcSetError(device
, ALC_INVALID_DEVICE
);
4486 alcSetError(device
, ALC_INVALID_VALUE
);
4489 if(IsValidALCType(type
) && IsValidALCChannels(channels
) && freq
>= MIN_OUTPUT_RATE
)
4492 if(device
) ALCdevice_DecRef(device
);
4497 /* alcRenderSamplesSOFT
4499 * Renders some samples into a buffer, using the format last set by the
4500 * attributes given to alcCreateContext.
4502 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4504 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4505 alcSetError(device
, ALC_INVALID_DEVICE
);
4506 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
4507 alcSetError(device
, ALC_INVALID_VALUE
);
4510 V0(device
->Backend
,lock
)();
4511 aluMixData(device
, buffer
, samples
);
4512 V0(device
->Backend
,unlock
)();
4514 if(device
) ALCdevice_DecRef(device
);
4518 /************************************************
4519 * ALC loopback2 functions
4520 ************************************************/
4522 ALC_API ALCboolean ALC_APIENTRY
alcIsAmbisonicFormatSupportedSOFT(ALCdevice
*device
, ALCenum layout
, ALCenum scaling
, ALsizei order
)
4524 ALCboolean ret
= ALC_FALSE
;
4526 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4527 alcSetError(device
, ALC_INVALID_DEVICE
);
4529 alcSetError(device
, ALC_INVALID_VALUE
);
4532 if(IsValidAmbiLayout(layout
) && IsValidAmbiScaling(scaling
) && order
<= MAX_AMBI_ORDER
)
4535 if(device
) ALCdevice_DecRef(device
);
4540 /************************************************
4541 * ALC DSP pause/resume functions
4542 ************************************************/
4544 /* alcDevicePauseSOFT
4546 * Pause the DSP to stop audio processing.
4548 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
4550 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4551 alcSetError(device
, ALC_INVALID_DEVICE
);
4554 almtx_lock(&device
->BackendLock
);
4555 if((device
->Flags
&DEVICE_RUNNING
))
4556 V0(device
->Backend
,stop
)();
4557 device
->Flags
&= ~DEVICE_RUNNING
;
4558 device
->Flags
|= DEVICE_PAUSED
;
4559 almtx_unlock(&device
->BackendLock
);
4561 if(device
) ALCdevice_DecRef(device
);
4564 /* alcDeviceResumeSOFT
4566 * Resume the DSP to restart audio processing.
4568 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
4570 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4571 alcSetError(device
, ALC_INVALID_DEVICE
);
4574 almtx_lock(&device
->BackendLock
);
4575 if((device
->Flags
&DEVICE_PAUSED
))
4577 device
->Flags
&= ~DEVICE_PAUSED
;
4578 if(ATOMIC_LOAD_SEQ(&device
->ContextList
) != NULL
)
4580 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4581 device
->Flags
|= DEVICE_RUNNING
;
4584 alcSetError(device
, ALC_INVALID_DEVICE
);
4585 V0(device
->Backend
,lock
)();
4586 aluHandleDisconnect(device
);
4587 V0(device
->Backend
,unlock
)();
4591 almtx_unlock(&device
->BackendLock
);
4593 if(device
) ALCdevice_DecRef(device
);
4597 /************************************************
4598 * ALC HRTF functions
4599 ************************************************/
4601 /* alcGetStringiSOFT
4603 * Gets a string parameter at the given index.
4605 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4607 const ALCchar
*str
= NULL
;
4609 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4610 alcSetError(device
, ALC_INVALID_DEVICE
);
4611 else switch(paramName
)
4613 case ALC_HRTF_SPECIFIER_SOFT
:
4614 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->HrtfList
))
4615 str
= alstr_get_cstr(VECTOR_ELEM(device
->HrtfList
, index
).name
);
4617 alcSetError(device
, ALC_INVALID_VALUE
);
4621 alcSetError(device
, ALC_INVALID_ENUM
);
4624 if(device
) ALCdevice_DecRef(device
);
4629 /* alcResetDeviceSOFT
4631 * Resets the given device output, using the specified attribute list.
4633 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4638 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4641 alcSetError(device
, ALC_INVALID_DEVICE
);
4642 if(device
) ALCdevice_DecRef(device
);
4645 almtx_lock(&device
->BackendLock
);
4648 err
= UpdateDeviceParams(device
, attribs
);
4649 almtx_unlock(&device
->BackendLock
);
4651 if(err
!= ALC_NO_ERROR
)
4653 alcSetError(device
, err
);
4654 if(err
== ALC_INVALID_DEVICE
)
4656 V0(device
->Backend
,lock
)();
4657 aluHandleDisconnect(device
);
4658 V0(device
->Backend
,unlock
)();
4660 ALCdevice_DecRef(device
);
4663 ALCdevice_DecRef(device
);