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);
57 ALCboolean (*Init
)(BackendFuncs
*);
59 void (*Probe
)(enum DevProbe
);
63 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
64 static struct BackendInfo BackendList
[] = {
66 { "jack", ALCjackBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
68 #ifdef HAVE_PULSEAUDIO
69 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
72 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
75 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
78 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
81 { "solaris", ALCsolarisBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
84 { "sndio", ALCsndioBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
87 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
90 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
93 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
96 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
99 { "port", ALCportBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
102 { "opensl", ALCopenslBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
105 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
107 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
110 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
114 static struct BackendInfo PlaybackBackend
;
115 static struct BackendInfo CaptureBackend
;
118 /************************************************
119 * Functions, enums, and errors
120 ************************************************/
121 typedef struct ALCfunction
{
122 const ALCchar
*funcName
;
126 typedef struct ALCenums
{
127 const ALCchar
*enumName
;
131 #define DECL(x) { #x, (ALCvoid*)(x) }
132 static const ALCfunction alcFunctions
[] = {
133 DECL(alcCreateContext
),
134 DECL(alcMakeContextCurrent
),
135 DECL(alcProcessContext
),
136 DECL(alcSuspendContext
),
137 DECL(alcDestroyContext
),
138 DECL(alcGetCurrentContext
),
139 DECL(alcGetContextsDevice
),
141 DECL(alcCloseDevice
),
143 DECL(alcIsExtensionPresent
),
144 DECL(alcGetProcAddress
),
145 DECL(alcGetEnumValue
),
147 DECL(alcGetIntegerv
),
148 DECL(alcCaptureOpenDevice
),
149 DECL(alcCaptureCloseDevice
),
150 DECL(alcCaptureStart
),
151 DECL(alcCaptureStop
),
152 DECL(alcCaptureSamples
),
154 DECL(alcSetThreadContext
),
155 DECL(alcGetThreadContext
),
157 DECL(alcLoopbackOpenDeviceSOFT
),
158 DECL(alcIsRenderFormatSupportedSOFT
),
159 DECL(alcRenderSamplesSOFT
),
161 DECL(alcDevicePauseSOFT
),
162 DECL(alcDeviceResumeSOFT
),
164 DECL(alcGetStringiSOFT
),
165 DECL(alcResetDeviceSOFT
),
167 DECL(alcGetInteger64vSOFT
),
182 DECL(alIsExtensionPresent
),
183 DECL(alGetProcAddress
),
184 DECL(alGetEnumValue
),
191 DECL(alGetListenerf
),
192 DECL(alGetListener3f
),
193 DECL(alGetListenerfv
),
194 DECL(alGetListeneri
),
195 DECL(alGetListener3i
),
196 DECL(alGetListeneriv
),
198 DECL(alDeleteSources
),
214 DECL(alSourceRewindv
),
215 DECL(alSourcePausev
),
218 DECL(alSourceRewind
),
220 DECL(alSourceQueueBuffers
),
221 DECL(alSourceUnqueueBuffers
),
223 DECL(alDeleteBuffers
),
238 DECL(alDopplerFactor
),
239 DECL(alDopplerVelocity
),
240 DECL(alSpeedOfSound
),
241 DECL(alDistanceModel
),
244 DECL(alDeleteFilters
),
255 DECL(alDeleteEffects
),
265 DECL(alGenAuxiliaryEffectSlots
),
266 DECL(alDeleteAuxiliaryEffectSlots
),
267 DECL(alIsAuxiliaryEffectSlot
),
268 DECL(alAuxiliaryEffectSloti
),
269 DECL(alAuxiliaryEffectSlotiv
),
270 DECL(alAuxiliaryEffectSlotf
),
271 DECL(alAuxiliaryEffectSlotfv
),
272 DECL(alGetAuxiliaryEffectSloti
),
273 DECL(alGetAuxiliaryEffectSlotiv
),
274 DECL(alGetAuxiliaryEffectSlotf
),
275 DECL(alGetAuxiliaryEffectSlotfv
),
277 DECL(alDeferUpdatesSOFT
),
278 DECL(alProcessUpdatesSOFT
),
281 DECL(alSource3dSOFT
),
282 DECL(alSourcedvSOFT
),
283 DECL(alGetSourcedSOFT
),
284 DECL(alGetSource3dSOFT
),
285 DECL(alGetSourcedvSOFT
),
286 DECL(alSourcei64SOFT
),
287 DECL(alSource3i64SOFT
),
288 DECL(alSourcei64vSOFT
),
289 DECL(alGetSourcei64SOFT
),
290 DECL(alGetSource3i64SOFT
),
291 DECL(alGetSourcei64vSOFT
),
293 DECL(alBufferSamplesSOFT
),
294 DECL(alGetBufferSamplesSOFT
),
295 DECL(alIsBufferFormatSupportedSOFT
),
301 #define DECL(x) { #x, (x) }
302 static const ALCenums enumeration
[] = {
307 DECL(ALC_MAJOR_VERSION
),
308 DECL(ALC_MINOR_VERSION
),
309 DECL(ALC_ATTRIBUTES_SIZE
),
310 DECL(ALC_ALL_ATTRIBUTES
),
311 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
312 DECL(ALC_DEVICE_SPECIFIER
),
313 DECL(ALC_ALL_DEVICES_SPECIFIER
),
314 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
315 DECL(ALC_EXTENSIONS
),
319 DECL(ALC_MONO_SOURCES
),
320 DECL(ALC_STEREO_SOURCES
),
321 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
322 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
323 DECL(ALC_CAPTURE_SAMPLES
),
326 DECL(ALC_EFX_MAJOR_VERSION
),
327 DECL(ALC_EFX_MINOR_VERSION
),
328 DECL(ALC_MAX_AUXILIARY_SENDS
),
330 DECL(ALC_FORMAT_CHANNELS_SOFT
),
331 DECL(ALC_FORMAT_TYPE_SOFT
),
334 DECL(ALC_STEREO_SOFT
),
336 DECL(ALC_5POINT1_SOFT
),
337 DECL(ALC_6POINT1_SOFT
),
338 DECL(ALC_7POINT1_SOFT
),
341 DECL(ALC_UNSIGNED_BYTE_SOFT
),
342 DECL(ALC_SHORT_SOFT
),
343 DECL(ALC_UNSIGNED_SHORT_SOFT
),
345 DECL(ALC_UNSIGNED_INT_SOFT
),
346 DECL(ALC_FLOAT_SOFT
),
349 DECL(ALC_DONT_CARE_SOFT
),
350 DECL(ALC_HRTF_STATUS_SOFT
),
351 DECL(ALC_HRTF_DISABLED_SOFT
),
352 DECL(ALC_HRTF_ENABLED_SOFT
),
353 DECL(ALC_HRTF_DENIED_SOFT
),
354 DECL(ALC_HRTF_REQUIRED_SOFT
),
355 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
356 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
357 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
358 DECL(ALC_HRTF_SPECIFIER_SOFT
),
359 DECL(ALC_HRTF_ID_SOFT
),
362 DECL(ALC_INVALID_DEVICE
),
363 DECL(ALC_INVALID_CONTEXT
),
364 DECL(ALC_INVALID_ENUM
),
365 DECL(ALC_INVALID_VALUE
),
366 DECL(ALC_OUT_OF_MEMORY
),
374 DECL(AL_SOURCE_RELATIVE
),
375 DECL(AL_CONE_INNER_ANGLE
),
376 DECL(AL_CONE_OUTER_ANGLE
),
386 DECL(AL_ORIENTATION
),
387 DECL(AL_REFERENCE_DISTANCE
),
388 DECL(AL_ROLLOFF_FACTOR
),
389 DECL(AL_CONE_OUTER_GAIN
),
390 DECL(AL_MAX_DISTANCE
),
392 DECL(AL_SAMPLE_OFFSET
),
393 DECL(AL_BYTE_OFFSET
),
394 DECL(AL_SOURCE_TYPE
),
397 DECL(AL_UNDETERMINED
),
398 DECL(AL_METERS_PER_UNIT
),
399 DECL(AL_LOOP_POINTS_SOFT
),
400 DECL(AL_DIRECT_CHANNELS_SOFT
),
402 DECL(AL_DIRECT_FILTER
),
403 DECL(AL_AUXILIARY_SEND_FILTER
),
404 DECL(AL_AIR_ABSORPTION_FACTOR
),
405 DECL(AL_ROOM_ROLLOFF_FACTOR
),
406 DECL(AL_CONE_OUTER_GAINHF
),
407 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
408 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
409 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
411 DECL(AL_SOURCE_STATE
),
417 DECL(AL_BUFFERS_QUEUED
),
418 DECL(AL_BUFFERS_PROCESSED
),
420 DECL(AL_FORMAT_MONO8
),
421 DECL(AL_FORMAT_MONO16
),
422 DECL(AL_FORMAT_MONO_FLOAT32
),
423 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
424 DECL(AL_FORMAT_STEREO8
),
425 DECL(AL_FORMAT_STEREO16
),
426 DECL(AL_FORMAT_STEREO_FLOAT32
),
427 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
428 DECL(AL_FORMAT_MONO_IMA4
),
429 DECL(AL_FORMAT_STEREO_IMA4
),
430 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
431 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
432 DECL(AL_FORMAT_QUAD8_LOKI
),
433 DECL(AL_FORMAT_QUAD16_LOKI
),
434 DECL(AL_FORMAT_QUAD8
),
435 DECL(AL_FORMAT_QUAD16
),
436 DECL(AL_FORMAT_QUAD32
),
437 DECL(AL_FORMAT_51CHN8
),
438 DECL(AL_FORMAT_51CHN16
),
439 DECL(AL_FORMAT_51CHN32
),
440 DECL(AL_FORMAT_61CHN8
),
441 DECL(AL_FORMAT_61CHN16
),
442 DECL(AL_FORMAT_61CHN32
),
443 DECL(AL_FORMAT_71CHN8
),
444 DECL(AL_FORMAT_71CHN16
),
445 DECL(AL_FORMAT_71CHN32
),
446 DECL(AL_FORMAT_REAR8
),
447 DECL(AL_FORMAT_REAR16
),
448 DECL(AL_FORMAT_REAR32
),
449 DECL(AL_FORMAT_MONO_MULAW
),
450 DECL(AL_FORMAT_MONO_MULAW_EXT
),
451 DECL(AL_FORMAT_STEREO_MULAW
),
452 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
453 DECL(AL_FORMAT_QUAD_MULAW
),
454 DECL(AL_FORMAT_51CHN_MULAW
),
455 DECL(AL_FORMAT_61CHN_MULAW
),
456 DECL(AL_FORMAT_71CHN_MULAW
),
457 DECL(AL_FORMAT_REAR_MULAW
),
458 DECL(AL_FORMAT_MONO_ALAW_EXT
),
459 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
461 DECL(AL_FORMAT_BFORMAT2D_8
),
462 DECL(AL_FORMAT_BFORMAT2D_16
),
463 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
464 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
465 DECL(AL_FORMAT_BFORMAT3D_8
),
466 DECL(AL_FORMAT_BFORMAT3D_16
),
467 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
468 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
471 DECL(AL_MONO16_SOFT
),
472 DECL(AL_MONO32F_SOFT
),
473 DECL(AL_STEREO8_SOFT
),
474 DECL(AL_STEREO16_SOFT
),
475 DECL(AL_STEREO32F_SOFT
),
477 DECL(AL_QUAD16_SOFT
),
478 DECL(AL_QUAD32F_SOFT
),
480 DECL(AL_REAR16_SOFT
),
481 DECL(AL_REAR32F_SOFT
),
482 DECL(AL_5POINT1_8_SOFT
),
483 DECL(AL_5POINT1_16_SOFT
),
484 DECL(AL_5POINT1_32F_SOFT
),
485 DECL(AL_6POINT1_8_SOFT
),
486 DECL(AL_6POINT1_16_SOFT
),
487 DECL(AL_6POINT1_32F_SOFT
),
488 DECL(AL_7POINT1_8_SOFT
),
489 DECL(AL_7POINT1_16_SOFT
),
490 DECL(AL_7POINT1_32F_SOFT
),
491 DECL(AL_BFORMAT2D_8_SOFT
),
492 DECL(AL_BFORMAT2D_16_SOFT
),
493 DECL(AL_BFORMAT2D_32F_SOFT
),
494 DECL(AL_BFORMAT3D_8_SOFT
),
495 DECL(AL_BFORMAT3D_16_SOFT
),
496 DECL(AL_BFORMAT3D_32F_SOFT
),
499 DECL(AL_STEREO_SOFT
),
502 DECL(AL_5POINT1_SOFT
),
503 DECL(AL_6POINT1_SOFT
),
504 DECL(AL_7POINT1_SOFT
),
505 DECL(AL_BFORMAT2D_SOFT
),
506 DECL(AL_BFORMAT3D_SOFT
),
509 DECL(AL_UNSIGNED_BYTE_SOFT
),
511 DECL(AL_UNSIGNED_SHORT_SOFT
),
513 DECL(AL_UNSIGNED_INT_SOFT
),
515 DECL(AL_DOUBLE_SOFT
),
517 DECL(AL_UNSIGNED_BYTE3_SOFT
),
524 DECL(AL_INTERNAL_FORMAT_SOFT
),
525 DECL(AL_BYTE_LENGTH_SOFT
),
526 DECL(AL_SAMPLE_LENGTH_SOFT
),
527 DECL(AL_SEC_LENGTH_SOFT
),
528 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
529 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
531 DECL(AL_SOURCE_RADIUS
),
533 DECL(AL_STEREO_ANGLES
),
540 DECL(AL_INVALID_NAME
),
541 DECL(AL_INVALID_ENUM
),
542 DECL(AL_INVALID_VALUE
),
543 DECL(AL_INVALID_OPERATION
),
544 DECL(AL_OUT_OF_MEMORY
),
551 DECL(AL_DOPPLER_FACTOR
),
552 DECL(AL_DOPPLER_VELOCITY
),
553 DECL(AL_DISTANCE_MODEL
),
554 DECL(AL_SPEED_OF_SOUND
),
555 DECL(AL_SOURCE_DISTANCE_MODEL
),
556 DECL(AL_DEFERRED_UPDATES_SOFT
),
557 DECL(AL_GAIN_LIMIT_SOFT
),
559 DECL(AL_INVERSE_DISTANCE
),
560 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
561 DECL(AL_LINEAR_DISTANCE
),
562 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
563 DECL(AL_EXPONENT_DISTANCE
),
564 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
566 DECL(AL_FILTER_TYPE
),
567 DECL(AL_FILTER_NULL
),
568 DECL(AL_FILTER_LOWPASS
),
569 DECL(AL_FILTER_HIGHPASS
),
570 DECL(AL_FILTER_BANDPASS
),
572 DECL(AL_LOWPASS_GAIN
),
573 DECL(AL_LOWPASS_GAINHF
),
575 DECL(AL_HIGHPASS_GAIN
),
576 DECL(AL_HIGHPASS_GAINLF
),
578 DECL(AL_BANDPASS_GAIN
),
579 DECL(AL_BANDPASS_GAINHF
),
580 DECL(AL_BANDPASS_GAINLF
),
582 DECL(AL_EFFECT_TYPE
),
583 DECL(AL_EFFECT_NULL
),
584 DECL(AL_EFFECT_REVERB
),
585 DECL(AL_EFFECT_EAXREVERB
),
586 DECL(AL_EFFECT_CHORUS
),
587 DECL(AL_EFFECT_DISTORTION
),
588 DECL(AL_EFFECT_ECHO
),
589 DECL(AL_EFFECT_FLANGER
),
591 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
592 DECL(AL_EFFECT_VOCAL_MORPHER
),
593 DECL(AL_EFFECT_PITCH_SHIFTER
),
595 DECL(AL_EFFECT_RING_MODULATOR
),
597 DECL(AL_EFFECT_AUTOWAH
),
599 DECL(AL_EFFECT_COMPRESSOR
),
600 DECL(AL_EFFECT_EQUALIZER
),
601 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
602 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
604 DECL(AL_EFFECTSLOT_EFFECT
),
605 DECL(AL_EFFECTSLOT_GAIN
),
606 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
),
607 DECL(AL_EFFECTSLOT_NULL
),
609 DECL(AL_EAXREVERB_DENSITY
),
610 DECL(AL_EAXREVERB_DIFFUSION
),
611 DECL(AL_EAXREVERB_GAIN
),
612 DECL(AL_EAXREVERB_GAINHF
),
613 DECL(AL_EAXREVERB_GAINLF
),
614 DECL(AL_EAXREVERB_DECAY_TIME
),
615 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
616 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
617 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
618 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
619 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
620 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
621 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
622 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
623 DECL(AL_EAXREVERB_ECHO_TIME
),
624 DECL(AL_EAXREVERB_ECHO_DEPTH
),
625 DECL(AL_EAXREVERB_MODULATION_TIME
),
626 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
627 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
628 DECL(AL_EAXREVERB_HFREFERENCE
),
629 DECL(AL_EAXREVERB_LFREFERENCE
),
630 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
631 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
633 DECL(AL_REVERB_DENSITY
),
634 DECL(AL_REVERB_DIFFUSION
),
635 DECL(AL_REVERB_GAIN
),
636 DECL(AL_REVERB_GAINHF
),
637 DECL(AL_REVERB_DECAY_TIME
),
638 DECL(AL_REVERB_DECAY_HFRATIO
),
639 DECL(AL_REVERB_REFLECTIONS_GAIN
),
640 DECL(AL_REVERB_REFLECTIONS_DELAY
),
641 DECL(AL_REVERB_LATE_REVERB_GAIN
),
642 DECL(AL_REVERB_LATE_REVERB_DELAY
),
643 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
644 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
645 DECL(AL_REVERB_DECAY_HFLIMIT
),
647 DECL(AL_CHORUS_WAVEFORM
),
648 DECL(AL_CHORUS_PHASE
),
649 DECL(AL_CHORUS_RATE
),
650 DECL(AL_CHORUS_DEPTH
),
651 DECL(AL_CHORUS_FEEDBACK
),
652 DECL(AL_CHORUS_DELAY
),
654 DECL(AL_DISTORTION_EDGE
),
655 DECL(AL_DISTORTION_GAIN
),
656 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
657 DECL(AL_DISTORTION_EQCENTER
),
658 DECL(AL_DISTORTION_EQBANDWIDTH
),
661 DECL(AL_ECHO_LRDELAY
),
662 DECL(AL_ECHO_DAMPING
),
663 DECL(AL_ECHO_FEEDBACK
),
664 DECL(AL_ECHO_SPREAD
),
666 DECL(AL_FLANGER_WAVEFORM
),
667 DECL(AL_FLANGER_PHASE
),
668 DECL(AL_FLANGER_RATE
),
669 DECL(AL_FLANGER_DEPTH
),
670 DECL(AL_FLANGER_FEEDBACK
),
671 DECL(AL_FLANGER_DELAY
),
673 DECL(AL_RING_MODULATOR_FREQUENCY
),
674 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
675 DECL(AL_RING_MODULATOR_WAVEFORM
),
677 DECL(AL_COMPRESSOR_ONOFF
),
679 DECL(AL_EQUALIZER_LOW_GAIN
),
680 DECL(AL_EQUALIZER_LOW_CUTOFF
),
681 DECL(AL_EQUALIZER_MID1_GAIN
),
682 DECL(AL_EQUALIZER_MID1_CENTER
),
683 DECL(AL_EQUALIZER_MID1_WIDTH
),
684 DECL(AL_EQUALIZER_MID2_GAIN
),
685 DECL(AL_EQUALIZER_MID2_CENTER
),
686 DECL(AL_EQUALIZER_MID2_WIDTH
),
687 DECL(AL_EQUALIZER_HIGH_GAIN
),
688 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
690 DECL(AL_DEDICATED_GAIN
),
696 static const ALCchar alcNoError
[] = "No Error";
697 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
698 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
699 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
700 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
701 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
704 /************************************************
706 ************************************************/
708 /* Enumerated device names */
709 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
711 static al_string alcAllDevicesList
;
712 static al_string alcCaptureDeviceList
;
714 /* Default is always the first in the list */
715 static ALCchar
*alcDefaultAllDevicesSpecifier
;
716 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
718 /* Default context extensions */
719 static const ALchar alExtList
[] =
720 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
721 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
722 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
723 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
724 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
725 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
726 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length";
728 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
730 /* Thread-local current context */
731 static altss_t LocalContext
;
732 /* Process-wide current context */
733 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
735 /* Mixing thread piority level */
740 enum LogLevel LogLevel
= LogWarning
;
742 enum LogLevel LogLevel
= LogError
;
745 /* Flag to trap ALC device errors */
746 static ALCboolean TrapALCError
= ALC_FALSE
;
748 /* One-time configuration init control */
749 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
751 /* Default effect that applies to sources that don't have an effect on send 0 */
752 static ALeffect DefaultEffect
;
754 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
757 static ALCboolean SuspendDefers
= ALC_TRUE
;
760 /************************************************
762 ************************************************/
763 static const ALCchar alcNoDeviceExtList
[] =
764 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
765 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
766 static const ALCchar alcExtensionList
[] =
767 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
768 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
769 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
770 "ALC_SOFT_loopback ALC_SOFT_pause_device";
771 static const ALCint alcMajorVersion
= 1;
772 static const ALCint alcMinorVersion
= 1;
774 static const ALCint alcEFXMajorVersion
= 1;
775 static const ALCint alcEFXMinorVersion
= 0;
778 /************************************************
780 ************************************************/
781 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
783 static almtx_t ListLock
;
784 static inline void LockLists(void)
786 int ret
= almtx_lock(&ListLock
);
787 assert(ret
== althrd_success
);
789 static inline void UnlockLists(void)
791 int ret
= almtx_unlock(&ListLock
);
792 assert(ret
== althrd_success
);
795 /************************************************
796 * Library initialization
797 ************************************************/
799 static void alc_init(void);
800 static void alc_deinit(void);
801 static void alc_deinit_safe(void);
803 #ifndef AL_LIBTYPE_STATIC
804 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
808 case DLL_PROCESS_ATTACH
:
809 /* Pin the DLL so we won't get unloaded until the process terminates */
810 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
811 (WCHAR
*)hModule
, &hModule
);
815 case DLL_THREAD_DETACH
:
818 case DLL_PROCESS_DETACH
:
827 #elif defined(_MSC_VER)
828 #pragma section(".CRT$XCU",read)
829 static void alc_constructor(void);
830 static void alc_destructor(void);
831 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
833 static void alc_constructor(void)
835 atexit(alc_destructor
);
839 static void alc_destructor(void)
843 #elif defined(HAVE_GCC_DESTRUCTOR)
844 static void alc_init(void) __attribute__((constructor
));
845 static void alc_deinit(void) __attribute__((destructor
));
847 #error "No static initialization available on this platform!"
850 #elif defined(HAVE_GCC_DESTRUCTOR)
852 static void alc_init(void) __attribute__((constructor
));
853 static void alc_deinit(void) __attribute__((destructor
));
856 #error "No global initialization available on this platform!"
859 static void ReleaseThreadCtx(void *ptr
);
860 static void alc_init(void)
867 AL_STRING_INIT(alcAllDevicesList
);
868 AL_STRING_INIT(alcCaptureDeviceList
);
870 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
871 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
874 str
= getenv("__ALSOFT_REVERSE_Z");
875 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
878 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
879 assert(ret
== althrd_success
);
881 ret
= almtx_init(&ListLock
, almtx_recursive
);
882 assert(ret
== althrd_success
);
887 static void alc_initconfig(void)
889 const char *devs
, *str
;
894 str
= getenv("ALSOFT_LOGLEVEL");
897 long lvl
= strtol(str
, NULL
, 0);
898 if(lvl
>= NoLog
&& lvl
<= LogRef
)
902 str
= getenv("ALSOFT_LOGFILE");
905 FILE *logfile
= al_fopen(str
, "wt");
906 if(logfile
) LogFile
= logfile
;
907 else ERR("Failed to open log file '%s'\n", str
);
910 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION
,
911 ALSOFT_GIT_COMMIT_HASH
, ALSOFT_GIT_BRANCH
);
914 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
915 for(i
= 1;BackendList
[i
].name
;i
++)
916 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
917 TRACE("Supported backends: %s\n", buf
);
921 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
924 if(strcasecmp(str
, "ignore") == 0)
926 SuspendDefers
= ALC_FALSE
;
927 TRACE("Selected context suspend behavior, \"ignore\"\n");
930 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
934 #if defined(HAVE_SSE4_1)
935 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
936 #elif defined(HAVE_SSE3)
937 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
938 #elif defined(HAVE_SSE2)
939 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
940 #elif defined(HAVE_SSE)
941 capfilter
|= CPU_CAP_SSE
;
944 capfilter
|= CPU_CAP_NEON
;
946 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
948 if(strcasecmp(str
, "all") == 0)
953 const char *next
= str
;
957 while(isspace(str
[0]))
959 next
= strchr(str
, ',');
961 if(!str
[0] || str
[0] == ',')
964 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
965 while(len
> 0 && isspace(str
[len
-1]))
967 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
968 capfilter
&= ~CPU_CAP_SSE
;
969 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
970 capfilter
&= ~CPU_CAP_SSE2
;
971 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
972 capfilter
&= ~CPU_CAP_SSE3
;
973 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
974 capfilter
&= ~CPU_CAP_SSE4_1
;
975 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
976 capfilter
&= ~CPU_CAP_NEON
;
978 WARN("Invalid CPU extension \"%s\"\n", str
);
982 FillCPUCaps(capfilter
);
989 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
993 str
= getenv("ALSOFT_TRAP_ERROR");
994 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
996 TrapALError
= AL_TRUE
;
997 TrapALCError
= AL_TRUE
;
1001 str
= getenv("ALSOFT_TRAP_AL_ERROR");
1002 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1003 TrapALError
= AL_TRUE
;
1004 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
1006 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1007 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1008 TrapALCError
= ALC_TRUE
;
1009 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1012 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1013 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1015 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1017 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1018 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1022 const char *next
= devs
;
1023 int endlist
, delitem
;
1028 while(isspace(devs
[0]))
1030 next
= strchr(devs
, ',');
1032 delitem
= (devs
[0] == '-');
1033 if(devs
[0] == '-') devs
++;
1035 if(!devs
[0] || devs
[0] == ',')
1042 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1043 while(len
> 0 && isspace(devs
[len
-1]))
1045 for(n
= i
;BackendList
[n
].name
;n
++)
1047 if(len
== strlen(BackendList
[n
].name
) &&
1048 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1053 BackendList
[n
] = BackendList
[n
+1];
1055 } while(BackendList
[n
].name
);
1059 struct BackendInfo Bkp
= BackendList
[n
];
1062 BackendList
[n
] = BackendList
[n
-1];
1065 BackendList
[n
] = Bkp
;
1076 BackendList
[i
].name
= NULL
;
1077 BackendList
[i
].getFactory
= NULL
;
1078 BackendList
[i
].Init
= NULL
;
1079 BackendList
[i
].Deinit
= NULL
;
1080 BackendList
[i
].Probe
= NULL
;
1084 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1086 if(BackendList
[i
].getFactory
)
1088 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1089 if(!V0(factory
,init
)())
1091 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1095 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1096 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1098 PlaybackBackend
= BackendList
[i
];
1099 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1101 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1103 CaptureBackend
= BackendList
[i
];
1104 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1110 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1112 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1116 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1117 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1119 PlaybackBackend
= BackendList
[i
];
1120 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1122 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1124 CaptureBackend
= BackendList
[i
];
1125 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1129 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1133 if(!PlaybackBackend
.name
)
1134 WARN("No playback backend available!\n");
1135 if(!CaptureBackend
.name
)
1136 WARN("No capture backend available!\n");
1138 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1141 const char *next
= str
;
1145 next
= strchr(str
, ',');
1147 if(!str
[0] || next
== str
)
1150 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1151 for(n
= 0;EffectList
[n
].name
;n
++)
1153 if(len
== strlen(EffectList
[n
].name
) &&
1154 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1155 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1160 InitEffectFactoryMap();
1162 InitEffect(&DefaultEffect
);
1163 str
= getenv("ALSOFT_DEFAULT_REVERB");
1164 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1165 LoadReverbPreset(str
, &DefaultEffect
);
1167 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1172 static JavaVM
*gJavaVM
;
1173 static pthread_key_t gJVMThreadKey
;
1175 static void CleanupJNIEnv(void* UNUSED(ptr
))
1177 JCALL0(gJavaVM
,DetachCurrentThread
)();
1180 void *Android_GetJNIEnv(void)
1184 WARN("gJavaVM is NULL!\n");
1188 /* http://developer.android.com/guide/practices/jni.html
1190 * All threads are Linux threads, scheduled by the kernel. They're usually
1191 * started from managed code (using Thread.start), but they can also be
1192 * created elsewhere and then attached to the JavaVM. For example, a thread
1193 * started with pthread_create can be attached with the JNI
1194 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1195 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1196 * Attaching a natively-created thread causes a java.lang.Thread object to
1197 * be constructed and added to the "main" ThreadGroup, making it visible to
1198 * the debugger. Calling AttachCurrentThread on an already-attached thread
1201 JNIEnv
*env
= pthread_getspecific(gJVMThreadKey
);
1204 int status
= JCALL(gJavaVM
,AttachCurrentThread
)(&env
, NULL
);
1207 ERR("Failed to attach current thread\n");
1210 pthread_setspecific(gJVMThreadKey
, env
);
1215 /* Automatically called by JNI. */
1216 JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM
*jvm
, void* UNUSED(reserved
))
1222 if(JCALL(gJavaVM
,GetEnv
)(&env
, JNI_VERSION_1_4
) != JNI_OK
)
1224 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1228 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1229 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1231 if((err
=pthread_key_create(&gJVMThreadKey
, CleanupJNIEnv
)) != 0)
1232 ERR("pthread_key_create failed: %d\n", err
);
1233 pthread_setspecific(gJVMThreadKey
, env
);
1234 return JNI_VERSION_1_4
;
1240 /************************************************
1241 * Library deinitialization
1242 ************************************************/
1243 static void alc_cleanup(void)
1247 AL_STRING_DEINIT(alcAllDevicesList
);
1248 AL_STRING_DEINIT(alcCaptureDeviceList
);
1250 free(alcDefaultAllDevicesSpecifier
);
1251 alcDefaultAllDevicesSpecifier
= NULL
;
1252 free(alcCaptureDefaultDeviceSpecifier
);
1253 alcCaptureDefaultDeviceSpecifier
= NULL
;
1255 if((dev
=ATOMIC_EXCHANGE_SEQ(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1260 } while((dev
=dev
->next
) != NULL
);
1261 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1264 DeinitEffectFactoryMap();
1267 static void alc_deinit_safe(void)
1275 almtx_destroy(&ListLock
);
1276 altss_delete(LocalContext
);
1278 if(LogFile
!= stderr
)
1283 static void alc_deinit(void)
1289 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1290 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1292 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1294 if(!BackendList
[i
].getFactory
)
1295 BackendList
[i
].Deinit();
1298 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1299 V0(factory
,deinit
)();
1303 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1304 V0(factory
,deinit
)();
1311 /************************************************
1312 * Device enumeration
1313 ************************************************/
1314 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1319 al_string_clear(list
);
1321 if(backendinfo
->Probe
)
1322 backendinfo
->Probe(type
);
1323 else if(backendinfo
->getFactory
)
1325 ALCbackendFactory
*factory
= backendinfo
->getFactory();
1326 V(factory
,probe
)(type
);
1331 static void ProbeAllDevicesList(void)
1332 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1333 static void ProbeCaptureDeviceList(void)
1334 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1336 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1338 size_t len
= strlen(name
);
1340 al_string_append_range(devnames
, name
, name
+len
+1);
1342 void AppendAllDevicesList(const ALCchar
*name
)
1343 { AppendDevice(name
, &alcAllDevicesList
); }
1344 void AppendCaptureDeviceList(const ALCchar
*name
)
1345 { AppendDevice(name
, &alcCaptureDeviceList
); }
1348 /************************************************
1349 * Device format information
1350 ************************************************/
1351 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1355 case DevFmtByte
: return "Signed Byte";
1356 case DevFmtUByte
: return "Unsigned Byte";
1357 case DevFmtShort
: return "Signed Short";
1358 case DevFmtUShort
: return "Unsigned Short";
1359 case DevFmtInt
: return "Signed Int";
1360 case DevFmtUInt
: return "Unsigned Int";
1361 case DevFmtFloat
: return "Float";
1363 return "(unknown type)";
1365 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1369 case DevFmtMono
: return "Mono";
1370 case DevFmtStereo
: return "Stereo";
1371 case DevFmtQuad
: return "Quadraphonic";
1372 case DevFmtX51
: return "5.1 Surround";
1373 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1374 case DevFmtX61
: return "6.1 Surround";
1375 case DevFmtX71
: return "7.1 Surround";
1376 case DevFmtAmbi1
: return "Ambisonic (1st Order)";
1377 case DevFmtAmbi2
: return "Ambisonic (2nd Order)";
1378 case DevFmtAmbi3
: return "Ambisonic (3rd Order)";
1380 return "(unknown channels)";
1383 extern inline ALsizei
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1384 ALsizei
BytesFromDevFmt(enum DevFmtType type
)
1388 case DevFmtByte
: return sizeof(ALbyte
);
1389 case DevFmtUByte
: return sizeof(ALubyte
);
1390 case DevFmtShort
: return sizeof(ALshort
);
1391 case DevFmtUShort
: return sizeof(ALushort
);
1392 case DevFmtInt
: return sizeof(ALint
);
1393 case DevFmtUInt
: return sizeof(ALuint
);
1394 case DevFmtFloat
: return sizeof(ALfloat
);
1398 ALsizei
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1402 case DevFmtMono
: return 1;
1403 case DevFmtStereo
: return 2;
1404 case DevFmtQuad
: return 4;
1405 case DevFmtX51
: return 6;
1406 case DevFmtX51Rear
: return 6;
1407 case DevFmtX61
: return 7;
1408 case DevFmtX71
: return 8;
1409 case DevFmtAmbi1
: return 4;
1410 case DevFmtAmbi2
: return 9;
1411 case DevFmtAmbi3
: return 16;
1416 static ALboolean
DecomposeDevFormat(ALenum format
, enum DevFmtChannels
*chans
,
1417 enum DevFmtType
*type
)
1419 static const struct {
1421 enum DevFmtChannels channels
;
1422 enum DevFmtType type
;
1424 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1425 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1426 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1428 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1429 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1430 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1432 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1433 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1434 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1436 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1437 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1438 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1440 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1441 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1442 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1444 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1445 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1446 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1450 for(i
= 0;i
< COUNTOF(list
);i
++)
1452 if(list
[i
].format
== format
)
1454 *chans
= list
[i
].channels
;
1455 *type
= list
[i
].type
;
1463 static ALCboolean
IsValidALCType(ALCenum type
)
1468 case ALC_UNSIGNED_BYTE_SOFT
:
1469 case ALC_SHORT_SOFT
:
1470 case ALC_UNSIGNED_SHORT_SOFT
:
1472 case ALC_UNSIGNED_INT_SOFT
:
1473 case ALC_FLOAT_SOFT
:
1479 static ALCboolean
IsValidALCChannels(ALCenum channels
)
1484 case ALC_STEREO_SOFT
:
1486 case ALC_5POINT1_SOFT
:
1487 case ALC_6POINT1_SOFT
:
1488 case ALC_7POINT1_SOFT
:
1495 /************************************************
1496 * Miscellaneous ALC helpers
1497 ************************************************/
1499 void ALCdevice_Lock(ALCdevice
*device
)
1501 V0(device
->Backend
,lock
)();
1504 void ALCdevice_Unlock(ALCdevice
*device
)
1506 V0(device
->Backend
,unlock
)();
1510 /* SetDefaultWFXChannelOrder
1512 * Sets the default channel order used by WaveFormatEx.
1514 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1518 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1519 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1521 switch(device
->FmtChans
)
1524 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1527 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1528 device
->RealOut
.ChannelName
[1] = FrontRight
;
1531 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1532 device
->RealOut
.ChannelName
[1] = FrontRight
;
1533 device
->RealOut
.ChannelName
[2] = BackLeft
;
1534 device
->RealOut
.ChannelName
[3] = BackRight
;
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] = SideLeft
;
1542 device
->RealOut
.ChannelName
[5] = SideRight
;
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] = BackLeft
;
1550 device
->RealOut
.ChannelName
[5] = BackRight
;
1553 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1554 device
->RealOut
.ChannelName
[1] = FrontRight
;
1555 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1556 device
->RealOut
.ChannelName
[3] = LFE
;
1557 device
->RealOut
.ChannelName
[4] = BackCenter
;
1558 device
->RealOut
.ChannelName
[5] = SideLeft
;
1559 device
->RealOut
.ChannelName
[6] = SideRight
;
1562 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1563 device
->RealOut
.ChannelName
[1] = FrontRight
;
1564 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1565 device
->RealOut
.ChannelName
[3] = LFE
;
1566 device
->RealOut
.ChannelName
[4] = BackLeft
;
1567 device
->RealOut
.ChannelName
[5] = BackRight
;
1568 device
->RealOut
.ChannelName
[6] = SideLeft
;
1569 device
->RealOut
.ChannelName
[7] = SideRight
;
1572 device
->RealOut
.ChannelName
[0] = Aux0
;
1573 device
->RealOut
.ChannelName
[1] = Aux1
;
1574 device
->RealOut
.ChannelName
[2] = Aux2
;
1575 device
->RealOut
.ChannelName
[3] = Aux3
;
1578 device
->RealOut
.ChannelName
[0] = Aux0
;
1579 device
->RealOut
.ChannelName
[1] = Aux1
;
1580 device
->RealOut
.ChannelName
[2] = Aux2
;
1581 device
->RealOut
.ChannelName
[3] = Aux3
;
1582 device
->RealOut
.ChannelName
[4] = Aux4
;
1583 device
->RealOut
.ChannelName
[5] = Aux5
;
1584 device
->RealOut
.ChannelName
[6] = Aux6
;
1585 device
->RealOut
.ChannelName
[7] = Aux7
;
1586 device
->RealOut
.ChannelName
[8] = Aux8
;
1589 device
->RealOut
.ChannelName
[0] = Aux0
;
1590 device
->RealOut
.ChannelName
[1] = Aux1
;
1591 device
->RealOut
.ChannelName
[2] = Aux2
;
1592 device
->RealOut
.ChannelName
[3] = Aux3
;
1593 device
->RealOut
.ChannelName
[4] = Aux4
;
1594 device
->RealOut
.ChannelName
[5] = Aux5
;
1595 device
->RealOut
.ChannelName
[6] = Aux6
;
1596 device
->RealOut
.ChannelName
[7] = Aux7
;
1597 device
->RealOut
.ChannelName
[8] = Aux8
;
1598 device
->RealOut
.ChannelName
[9] = Aux9
;
1599 device
->RealOut
.ChannelName
[10] = Aux10
;
1600 device
->RealOut
.ChannelName
[11] = Aux11
;
1601 device
->RealOut
.ChannelName
[12] = Aux12
;
1602 device
->RealOut
.ChannelName
[13] = Aux13
;
1603 device
->RealOut
.ChannelName
[14] = Aux14
;
1604 device
->RealOut
.ChannelName
[15] = Aux15
;
1609 /* SetDefaultChannelOrder
1611 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1613 void SetDefaultChannelOrder(ALCdevice
*device
)
1617 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1618 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1620 switch(device
->FmtChans
)
1623 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1624 device
->RealOut
.ChannelName
[1] = FrontRight
;
1625 device
->RealOut
.ChannelName
[2] = BackLeft
;
1626 device
->RealOut
.ChannelName
[3] = BackRight
;
1627 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1628 device
->RealOut
.ChannelName
[5] = LFE
;
1631 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1632 device
->RealOut
.ChannelName
[1] = FrontRight
;
1633 device
->RealOut
.ChannelName
[2] = BackLeft
;
1634 device
->RealOut
.ChannelName
[3] = BackRight
;
1635 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1636 device
->RealOut
.ChannelName
[5] = LFE
;
1637 device
->RealOut
.ChannelName
[6] = SideLeft
;
1638 device
->RealOut
.ChannelName
[7] = SideRight
;
1641 /* Same as WFX order */
1650 SetDefaultWFXChannelOrder(device
);
1655 extern inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
);
1658 /* ALCcontext_DeferUpdates
1660 * Defers/suspends updates for the given context's listener and sources. This
1661 * does *NOT* stop mixing, but rather prevents certain property changes from
1664 void ALCcontext_DeferUpdates(ALCcontext
*context
, ALenum type
)
1666 ATOMIC_STORE_SEQ(&context
->DeferUpdates
, type
);
1669 /* ALCcontext_ProcessUpdates
1671 * Resumes update processing after being deferred.
1673 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1675 ALCdevice
*device
= context
->Device
;
1677 ReadLock(&context
->PropLock
);
1678 if(ATOMIC_EXCHANGE_SEQ(ALenum
, &context
->DeferUpdates
, AL_FALSE
))
1683 /* Tell the mixer to stop applying updates, then wait for any active
1684 * updating to finish, before providing updates.
1686 ATOMIC_STORE_SEQ(&context
->HoldUpdates
, AL_TRUE
);
1687 while(((updates
=ReadRef(&context
->UpdateCount
))&1) != 0)
1690 UpdateListenerProps(context
);
1691 UpdateAllEffectSlotProps(context
);
1693 LockUIntMapRead(&context
->SourceMap
);
1694 V0(device
->Backend
,lock
)();
1695 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1697 ALsource
*Source
= context
->SourceMap
.values
[pos
];
1700 if(Source
->OffsetType
!= AL_NONE
&& IsPlayingOrPaused(Source
))
1702 WriteLock(&Source
->queue_lock
);
1703 ApplyOffset(Source
);
1704 WriteUnlock(&Source
->queue_lock
);
1707 new_state
= Source
->new_state
;
1708 Source
->new_state
= AL_NONE
;
1710 SetSourceState(Source
, context
, new_state
);
1712 V0(device
->Backend
,unlock
)();
1713 UnlockUIntMapRead(&context
->SourceMap
);
1715 UpdateAllSourceProps(context
);
1717 /* Now with all updates declared, let the mixer continue applying them
1718 * so they all happen at once.
1720 ATOMIC_STORE_SEQ(&context
->HoldUpdates
, AL_FALSE
);
1722 ReadUnlock(&context
->PropLock
);
1728 * Stores the latest ALC device error
1730 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1735 /* DebugBreak() will cause an exception if there is no debugger */
1736 if(IsDebuggerPresent())
1738 #elif defined(SIGTRAP)
1744 ATOMIC_STORE_SEQ(&device
->LastError
, errorCode
);
1746 ATOMIC_STORE_SEQ(&LastNullDeviceError
, errorCode
);
1752 * Updates the device's base clock time with however many samples have been
1753 * done. This is used so frequency changes on the device don't cause the time
1754 * to jump forward or back.
1756 static inline void UpdateClockBase(ALCdevice
*device
)
1758 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1759 device
->SamplesDone
= 0;
1762 /* UpdateDeviceParams
1764 * Updates device parameters according to the attribute list (caller is
1765 * responsible for holding the list lock).
1767 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1769 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1770 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1771 const ALsizei old_sends
= device
->NumAuxSends
;
1772 ALsizei new_sends
= device
->NumAuxSends
;
1773 enum DevFmtChannels oldChans
;
1774 enum DevFmtType oldType
;
1775 ALboolean update_failed
;
1776 ALCsizei hrtf_id
= -1;
1777 ALCcontext
*context
;
1782 // Check for attributes
1783 if(device
->Type
== Loopback
)
1789 GotAll
= GotFreq
|GotChans
|GotType
1791 ALCuint freq
, numMono
, numStereo
;
1792 enum DevFmtChannels schans
;
1793 enum DevFmtType stype
;
1794 ALCuint attrIdx
= 0;
1800 WARN("Missing attributes for loopback device\n");
1801 return ALC_INVALID_VALUE
;
1804 numMono
= device
->NumMonoSources
;
1805 numStereo
= device
->NumStereoSources
;
1806 schans
= device
->FmtChans
;
1807 stype
= device
->FmtType
;
1808 freq
= device
->Frequency
;
1809 numSends
= old_sends
;
1811 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1812 while(attrList
[attrIdx
])
1814 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1816 ALCint val
= attrList
[attrIdx
+ 1];
1817 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT
, val
);
1818 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1819 return ALC_INVALID_VALUE
;
1824 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1826 ALCint val
= attrList
[attrIdx
+ 1];
1827 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT
, val
);
1828 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1829 return ALC_INVALID_VALUE
;
1834 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1836 freq
= attrList
[attrIdx
+ 1];
1837 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1838 if(freq
< MIN_OUTPUT_RATE
)
1839 return ALC_INVALID_VALUE
;
1843 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1845 numStereo
= attrList
[attrIdx
+ 1];
1846 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1847 if(numStereo
> device
->SourcesMax
)
1848 numStereo
= device
->SourcesMax
;
1850 numMono
= device
->SourcesMax
- numStereo
;
1853 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1855 numSends
= attrList
[attrIdx
+ 1];
1856 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1859 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1861 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1862 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1863 hrtf_appreq
= Hrtf_Disable
;
1864 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1865 hrtf_appreq
= Hrtf_Enable
;
1867 hrtf_appreq
= Hrtf_Default
;
1870 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1872 hrtf_id
= attrList
[attrIdx
+ 1];
1873 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1880 if(gotFmt
!= GotAll
)
1882 WARN("Missing format for loopback device\n");
1883 return ALC_INVALID_VALUE
;
1886 if((device
->Flags
&DEVICE_RUNNING
))
1887 V0(device
->Backend
,stop
)();
1888 device
->Flags
&= ~DEVICE_RUNNING
;
1890 UpdateClockBase(device
);
1892 device
->Frequency
= freq
;
1893 device
->FmtChans
= schans
;
1894 device
->FmtType
= stype
;
1895 device
->NumMonoSources
= numMono
;
1896 device
->NumStereoSources
= numStereo
;
1898 ConfigValueInt(NULL
, NULL
, "sends", &numSends
);
1899 new_sends
= clampi(numSends
, 0, MAX_SENDS
);
1901 else if(attrList
&& attrList
[0])
1903 ALCuint freq
, numMono
, numStereo
;
1904 ALCuint attrIdx
= 0;
1907 /* If a context is already running on the device, stop playback so the
1908 * device attributes can be updated. */
1909 if((device
->Flags
&DEVICE_RUNNING
))
1910 V0(device
->Backend
,stop
)();
1911 device
->Flags
&= ~DEVICE_RUNNING
;
1913 UpdateClockBase(device
);
1915 freq
= device
->Frequency
;
1916 numMono
= device
->NumMonoSources
;
1917 numStereo
= device
->NumStereoSources
;
1918 numSends
= old_sends
;
1920 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1921 while(attrList
[attrIdx
])
1923 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1925 freq
= attrList
[attrIdx
+ 1];
1926 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1927 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1930 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1932 numStereo
= attrList
[attrIdx
+ 1];
1933 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1934 if(numStereo
> device
->SourcesMax
)
1935 numStereo
= device
->SourcesMax
;
1937 numMono
= device
->SourcesMax
- numStereo
;
1940 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1942 numSends
= attrList
[attrIdx
+ 1];
1943 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1946 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1948 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1949 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1950 hrtf_appreq
= Hrtf_Disable
;
1951 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1952 hrtf_appreq
= Hrtf_Enable
;
1954 hrtf_appreq
= Hrtf_Default
;
1957 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1959 hrtf_id
= attrList
[attrIdx
+ 1];
1960 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1967 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1968 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1970 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1972 /* SSE and Neon do best with the update size being a multiple of 4 */
1973 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1974 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1976 device
->Frequency
= freq
;
1977 device
->NumMonoSources
= numMono
;
1978 device
->NumStereoSources
= numStereo
;
1980 ConfigValueInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1981 new_sends
= clampi(numSends
, 0, MAX_SENDS
);
1984 if((device
->Flags
&DEVICE_RUNNING
))
1985 return ALC_NO_ERROR
;
1987 al_free(device
->Uhj_Encoder
);
1988 device
->Uhj_Encoder
= NULL
;
1990 al_free(device
->Bs2b
);
1991 device
->Bs2b
= NULL
;
1993 al_free(device
->Dry
.Buffer
);
1994 device
->Dry
.Buffer
= NULL
;
1995 device
->Dry
.NumChannels
= 0;
1996 device
->FOAOut
.Buffer
= NULL
;
1997 device
->FOAOut
.NumChannels
= 0;
1998 device
->RealOut
.Buffer
= NULL
;
1999 device
->RealOut
.NumChannels
= 0;
2001 UpdateClockBase(device
);
2003 /*************************************************************************
2004 * Update device format request if HRTF is requested
2006 device
->Hrtf
.Status
= ALC_HRTF_DISABLED_SOFT
;
2007 if(device
->Type
!= Loopback
)
2010 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
2012 if(strcasecmp(hrtf
, "true") == 0)
2013 hrtf_userreq
= Hrtf_Enable
;
2014 else if(strcasecmp(hrtf
, "false") == 0)
2015 hrtf_userreq
= Hrtf_Disable
;
2016 else if(strcasecmp(hrtf
, "auto") != 0)
2017 ERR("Unexpected hrtf value: %s\n", hrtf
);
2020 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
2022 if(VECTOR_SIZE(device
->Hrtf
.List
) == 0)
2024 VECTOR_DEINIT(device
->Hrtf
.List
);
2025 device
->Hrtf
.List
= EnumerateHrtf(device
->DeviceName
);
2027 if(VECTOR_SIZE(device
->Hrtf
.List
) > 0)
2029 device
->FmtChans
= DevFmtStereo
;
2030 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf
.List
))
2031 device
->Frequency
= VECTOR_ELEM(device
->Hrtf
.List
, hrtf_id
).hrtf
->sampleRate
;
2033 device
->Frequency
= VECTOR_ELEM(device
->Hrtf
.List
, 0).hrtf
->sampleRate
;
2034 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
2038 hrtf_userreq
= Hrtf_Default
;
2039 hrtf_appreq
= Hrtf_Disable
;
2040 device
->Hrtf
.Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2044 else if(hrtf_appreq
== Hrtf_Enable
)
2046 size_t i
= VECTOR_SIZE(device
->Hrtf
.List
);
2047 /* Loopback device. We don't need to match to a specific HRTF entry
2048 * here. If the requested ID matches, we'll pick that later, if not,
2049 * we'll try to auto-select one anyway. Just make sure one exists
2052 if(device
->FmtChans
== DevFmtStereo
)
2054 if(VECTOR_SIZE(device
->Hrtf
.List
) == 0)
2056 VECTOR_DEINIT(device
->Hrtf
.List
);
2057 device
->Hrtf
.List
= EnumerateHrtf(device
->DeviceName
);
2059 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf
.List
);i
++)
2061 const struct Hrtf
*hrtf
= VECTOR_ELEM(device
->Hrtf
.List
, i
).hrtf
;
2062 if(hrtf
->sampleRate
== device
->Frequency
)
2066 if(i
== VECTOR_SIZE(device
->Hrtf
.List
))
2068 ERR("Requested format not HRTF compatible: %s, %uhz\n",
2069 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
2070 hrtf_appreq
= Hrtf_Disable
;
2071 device
->Hrtf
.Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2075 oldFreq
= device
->Frequency
;
2076 oldChans
= device
->FmtChans
;
2077 oldType
= device
->FmtType
;
2079 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2080 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
2081 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
2082 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
2083 device
->UpdateSize
, device
->NumUpdates
2086 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
2087 return ALC_INVALID_DEVICE
;
2089 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
2091 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
2092 DevFmtChannelsString(device
->FmtChans
));
2093 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
2095 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
2097 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
2098 DevFmtTypeString(device
->FmtType
));
2099 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
2101 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
2103 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
2104 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
2107 if((device
->UpdateSize
&3) != 0)
2109 if((CPUCapFlags
&CPU_CAP_SSE
))
2110 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2111 if((CPUCapFlags
&CPU_CAP_NEON
))
2112 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
2115 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2116 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
2117 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
2120 aluInitRenderer(device
, hrtf_id
, hrtf_appreq
, hrtf_userreq
);
2121 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device
->Dry
.NumChannels
,
2122 device
->FOAOut
.NumChannels
, device
->RealOut
.NumChannels
);
2124 /* Allocate extra channels for any post-filter output. */
2125 size
= (device
->Dry
.NumChannels
+ device
->FOAOut
.NumChannels
+
2126 device
->RealOut
.NumChannels
)*sizeof(device
->Dry
.Buffer
[0]);
2128 TRACE("Allocating "SZFMT
" channels, "SZFMT
" bytes\n", size
/sizeof(device
->Dry
.Buffer
[0]), size
);
2129 device
->Dry
.Buffer
= al_calloc(16, size
);
2130 if(!device
->Dry
.Buffer
)
2132 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2133 return ALC_INVALID_DEVICE
;
2136 if(device
->RealOut
.NumChannels
!= 0)
2137 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
+
2138 device
->FOAOut
.NumChannels
;
2141 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2142 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2145 if(device
->FOAOut
.NumChannels
!= 0)
2146 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2149 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
;
2150 device
->FOAOut
.NumChannels
= device
->Dry
.NumChannels
;
2153 /* Need to delay returning failure until replacement Send arrays have been
2154 * allocated with the appropriate size.
2156 device
->NumAuxSends
= new_sends
;
2157 update_failed
= AL_FALSE
;
2158 SetMixerFPUMode(&oldMode
);
2159 if(device
->DefaultSlot
)
2161 ALeffectslot
*slot
= device
->DefaultSlot
;
2162 ALeffectState
*state
= slot
->Effect
.State
;
2164 state
->OutBuffer
= device
->Dry
.Buffer
;
2165 state
->OutChannels
= device
->Dry
.NumChannels
;
2166 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2167 update_failed
= AL_TRUE
;
2169 UpdateEffectSlotProps(slot
);
2172 context
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
2177 WriteLock(&context
->PropLock
);
2178 LockUIntMapRead(&context
->EffectSlotMap
);
2179 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2181 ALeffectslot
*slot
= context
->EffectSlotMap
.values
[pos
];
2182 ALeffectState
*state
= slot
->Effect
.State
;
2184 state
->OutBuffer
= device
->Dry
.Buffer
;
2185 state
->OutChannels
= device
->Dry
.NumChannels
;
2186 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2187 update_failed
= AL_TRUE
;
2189 UpdateEffectSlotProps(slot
);
2191 UnlockUIntMapRead(&context
->EffectSlotMap
);
2193 LockUIntMapRead(&context
->SourceMap
);
2194 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2196 ALsource
*source
= context
->SourceMap
.values
[pos
];
2197 struct ALsourceProps
*props
;
2199 if(old_sends
!= device
->NumAuxSends
)
2201 ALvoid
*sends
= al_calloc(16, device
->NumAuxSends
*sizeof(source
->Send
[0]));
2204 memcpy(sends
, source
->Send
,
2205 mini(device
->NumAuxSends
, old_sends
)*sizeof(source
->Send
[0])
2207 for(s
= device
->NumAuxSends
;s
< old_sends
;s
++)
2209 if(source
->Send
[s
].Slot
)
2210 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2211 source
->Send
[s
].Slot
= NULL
;
2213 al_free(source
->Send
);
2214 source
->Send
= sends
;
2215 for(s
= old_sends
;s
< device
->NumAuxSends
;s
++)
2217 source
->Send
[s
].Slot
= NULL
;
2218 source
->Send
[s
].Gain
= 1.0f
;
2219 source
->Send
[s
].GainHF
= 1.0f
;
2220 source
->Send
[s
].HFReference
= LOWPASSFREQREF
;
2221 source
->Send
[s
].GainLF
= 1.0f
;
2222 source
->Send
[s
].LFReference
= HIGHPASSFREQREF
;
2226 source
->NeedsUpdate
= AL_TRUE
;
2228 /* Clear any pre-existing source property structs, in case the
2229 * number of auxiliary sends changed. Playing (or paused) sources
2230 * will have updates respecified in UpdateAllSourceProps.
2232 props
= ATOMIC_EXCHANGE_SEQ(struct ALsourceProps
*, &source
->Update
, NULL
);
2235 props
= ATOMIC_EXCHANGE(struct ALsourceProps
*, &source
->FreeList
, NULL
,
2236 almemory_order_relaxed
);
2239 struct ALsourceProps
*next
= ATOMIC_LOAD(&props
->next
, almemory_order_relaxed
);
2244 AllocateVoices(context
, context
->MaxVoices
, old_sends
);
2245 UnlockUIntMapRead(&context
->SourceMap
);
2247 UpdateListenerProps(context
);
2248 UpdateAllSourceProps(context
);
2249 WriteUnlock(&context
->PropLock
);
2251 context
= context
->next
;
2253 RestoreFPUMode(&oldMode
);
2255 return ALC_INVALID_DEVICE
;
2257 if(!(device
->Flags
&DEVICE_PAUSED
))
2259 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2260 return ALC_INVALID_DEVICE
;
2261 device
->Flags
|= DEVICE_RUNNING
;
2264 return ALC_NO_ERROR
;
2269 * Frees the device structure, and destroys any objects the app failed to
2270 * delete. Called once there's no more references on the device.
2272 static ALCvoid
FreeDevice(ALCdevice
*device
)
2274 TRACE("%p\n", device
);
2276 V0(device
->Backend
,close
)();
2277 DELETE_OBJ(device
->Backend
);
2278 device
->Backend
= NULL
;
2280 almtx_destroy(&device
->BackendLock
);
2282 if(device
->DefaultSlot
)
2284 DeinitEffectSlot(device
->DefaultSlot
);
2285 device
->DefaultSlot
= NULL
;
2288 if(device
->BufferMap
.size
> 0)
2290 WARN("(%p) Deleting %d Buffer%s\n", device
, device
->BufferMap
.size
,
2291 (device
->BufferMap
.size
==1)?"":"s");
2292 ReleaseALBuffers(device
);
2294 ResetUIntMap(&device
->BufferMap
);
2296 if(device
->EffectMap
.size
> 0)
2298 WARN("(%p) Deleting %d Effect%s\n", device
, device
->EffectMap
.size
,
2299 (device
->EffectMap
.size
==1)?"":"s");
2300 ReleaseALEffects(device
);
2302 ResetUIntMap(&device
->EffectMap
);
2304 if(device
->FilterMap
.size
> 0)
2306 WARN("(%p) Deleting %d Filter%s\n", device
, device
->FilterMap
.size
,
2307 (device
->FilterMap
.size
==1)?"":"s");
2308 ReleaseALFilters(device
);
2310 ResetUIntMap(&device
->FilterMap
);
2312 AL_STRING_DEINIT(device
->Hrtf
.Name
);
2313 FreeHrtfList(&device
->Hrtf
.List
);
2315 al_free(device
->Bs2b
);
2316 device
->Bs2b
= NULL
;
2318 al_free(device
->Uhj_Encoder
);
2319 device
->Uhj_Encoder
= NULL
;
2321 bformatdec_free(device
->AmbiDecoder
);
2322 device
->AmbiDecoder
= NULL
;
2324 ambiup_free(device
->AmbiUp
);
2325 device
->AmbiUp
= NULL
;
2327 AL_STRING_DEINIT(device
->DeviceName
);
2329 al_free(device
->Dry
.Buffer
);
2330 device
->Dry
.Buffer
= NULL
;
2331 device
->Dry
.NumChannels
= 0;
2332 device
->FOAOut
.Buffer
= NULL
;
2333 device
->FOAOut
.NumChannels
= 0;
2334 device
->RealOut
.Buffer
= NULL
;
2335 device
->RealOut
.NumChannels
= 0;
2341 void ALCdevice_IncRef(ALCdevice
*device
)
2344 ref
= IncrementRef(&device
->ref
);
2345 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2348 void ALCdevice_DecRef(ALCdevice
*device
)
2351 ref
= DecrementRef(&device
->ref
);
2352 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2353 if(ref
== 0) FreeDevice(device
);
2358 * Checks if the device handle is valid, and increments its ref count if so.
2360 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2362 ALCdevice
*tmpDevice
;
2365 tmpDevice
= ATOMIC_LOAD_SEQ(&DeviceList
);
2368 if(tmpDevice
== *device
)
2370 ALCdevice_IncRef(tmpDevice
);
2374 tmpDevice
= tmpDevice
->next
;
2385 * Initializes context fields
2387 static ALvoid
InitContext(ALCcontext
*Context
)
2389 ALlistener
*listener
= Context
->Listener
;
2391 //Initialise listener
2392 listener
->Gain
= 1.0f
;
2393 listener
->MetersPerUnit
= 1.0f
;
2394 listener
->Position
[0] = 0.0f
;
2395 listener
->Position
[1] = 0.0f
;
2396 listener
->Position
[2] = 0.0f
;
2397 listener
->Velocity
[0] = 0.0f
;
2398 listener
->Velocity
[1] = 0.0f
;
2399 listener
->Velocity
[2] = 0.0f
;
2400 listener
->Forward
[0] = 0.0f
;
2401 listener
->Forward
[1] = 0.0f
;
2402 listener
->Forward
[2] = -1.0f
;
2403 listener
->Up
[0] = 0.0f
;
2404 listener
->Up
[1] = 1.0f
;
2405 listener
->Up
[2] = 0.0f
;
2407 aluMatrixfSet(&listener
->Params
.Matrix
,
2408 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2409 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2410 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2411 0.0f
, 0.0f
, 0.0f
, 1.0f
2413 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2414 listener
->Params
.Gain
= 1.0f
;
2415 listener
->Params
.MetersPerUnit
= 1.0f
;
2416 listener
->Params
.DopplerFactor
= 1.0f
;
2417 listener
->Params
.SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2419 ATOMIC_INIT(&listener
->Update
, NULL
);
2420 ATOMIC_INIT(&listener
->FreeList
, NULL
);
2423 InitRef(&Context
->UpdateCount
, 0);
2424 ATOMIC_INIT(&Context
->HoldUpdates
, AL_FALSE
);
2425 Context
->GainBoost
= 1.0f
;
2426 RWLockInit(&Context
->PropLock
);
2427 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2428 InitUIntMap(&Context
->SourceMap
, Context
->Device
->SourcesMax
);
2429 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2432 Context
->DistanceModel
= DefaultDistanceModel
;
2433 Context
->SourceDistanceModel
= AL_FALSE
;
2434 Context
->DopplerFactor
= 1.0f
;
2435 Context
->DopplerVelocity
= 1.0f
;
2436 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2437 ATOMIC_INIT(&Context
->DeferUpdates
, AL_FALSE
);
2439 Context
->ExtensionList
= alExtList
;
2445 * Cleans up the context, and destroys any remaining objects the app failed to
2446 * delete. Called once there's no more references on the context.
2448 static void FreeContext(ALCcontext
*context
)
2450 ALlistener
*listener
= context
->Listener
;
2451 struct ALlistenerProps
*lprops
;
2454 TRACE("%p\n", context
);
2456 if(context
->SourceMap
.size
> 0)
2458 WARN("(%p) Deleting %d Source%s\n", context
, context
->SourceMap
.size
,
2459 (context
->SourceMap
.size
==1)?"":"s");
2460 ReleaseALSources(context
);
2462 ResetUIntMap(&context
->SourceMap
);
2464 if(context
->EffectSlotMap
.size
> 0)
2466 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context
, context
->EffectSlotMap
.size
,
2467 (context
->EffectSlotMap
.size
==1)?"":"s");
2468 ReleaseALAuxiliaryEffectSlots(context
);
2470 ResetUIntMap(&context
->EffectSlotMap
);
2472 al_free(context
->Voices
);
2473 context
->Voices
= NULL
;
2474 context
->VoiceCount
= 0;
2475 context
->MaxVoices
= 0;
2477 if((lprops
=ATOMIC_LOAD(&listener
->Update
, almemory_order_acquire
)) != NULL
)
2479 TRACE("Freed unapplied listener update %p\n", lprops
);
2483 lprops
= ATOMIC_LOAD(&listener
->FreeList
, almemory_order_acquire
);
2486 struct ALlistenerProps
*next
= ATOMIC_LOAD(&lprops
->next
, almemory_order_acquire
);
2491 TRACE("Freed "SZFMT
" listener property object%s\n", count
, (count
==1)?"":"s");
2493 ALCdevice_DecRef(context
->Device
);
2494 context
->Device
= NULL
;
2496 //Invalidate context
2497 memset(context
, 0, sizeof(ALCcontext
));
2503 * Removes the context reference from the given device and removes it from
2504 * being current on the running thread or globally.
2506 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2508 ALCcontext
*origctx
;
2510 if(altss_get(LocalContext
) == context
)
2512 WARN("%p released while current on thread\n", context
);
2513 altss_set(LocalContext
, NULL
);
2514 ALCcontext_DecRef(context
);
2518 if(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2519 ALCcontext_DecRef(context
);
2521 ALCdevice_Lock(device
);
2523 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext
*, &device
->ContextList
,
2524 &origctx
, context
->next
))
2526 ALCcontext
*volatile*list
= &origctx
->next
;
2529 if(*list
== context
)
2531 *list
= (*list
)->next
;
2534 list
= &(*list
)->next
;
2537 ALCdevice_Unlock(device
);
2539 ALCcontext_DecRef(context
);
2542 void ALCcontext_IncRef(ALCcontext
*context
)
2544 uint ref
= IncrementRef(&context
->ref
);
2545 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2548 void ALCcontext_DecRef(ALCcontext
*context
)
2550 uint ref
= DecrementRef(&context
->ref
);
2551 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2552 if(ref
== 0) FreeContext(context
);
2555 static void ReleaseThreadCtx(void *ptr
)
2557 ALCcontext
*context
= ptr
;
2558 uint ref
= DecrementRef(&context
->ref
);
2559 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2560 ERR("Context %p current for thread being destroyed, possible leak!\n", context
);
2565 * Checks that the given context is valid, and increments its reference count.
2567 static ALCboolean
VerifyContext(ALCcontext
**context
)
2572 dev
= ATOMIC_LOAD_SEQ(&DeviceList
);
2575 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
, almemory_order_acquire
);
2580 ALCcontext_IncRef(ctx
);
2597 * Returns the currently active context for this thread, and adds a reference
2598 * without locking it.
2600 ALCcontext
*GetContextRef(void)
2602 ALCcontext
*context
;
2604 context
= altss_get(LocalContext
);
2606 ALCcontext_IncRef(context
);
2610 context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
2612 ALCcontext_IncRef(context
);
2620 void AllocateVoices(ALCcontext
*context
, ALsizei num_voices
, ALsizei old_sends
)
2622 ALCdevice
*device
= context
->Device
;
2623 ALsizei num_sends
= device
->NumAuxSends
;
2624 struct ALsourceProps
*props
;
2625 size_t sizeof_props
;
2626 size_t sizeof_voice
;
2632 if(num_voices
== context
->MaxVoices
&& num_sends
== old_sends
)
2635 /* Allocate the voice pointers, voices, and the voices' stored source
2636 * property set (including the dynamically-sized Send[] array) in one
2639 sizeof_props
= RoundUp(offsetof(struct ALsourceProps
, Send
[num_sends
]), 16);
2640 sizeof_voice
= RoundUp(offsetof(ALvoice
, Send
[num_sends
]), 16);
2641 size
= sizeof(ALvoice
*) + sizeof_voice
+ sizeof_props
;
2643 voices
= al_calloc(16, RoundUp(size
*num_voices
, 16));
2644 /* The voice and property objects are stored interleaved since they're
2647 voice
= (ALvoice
*)((char*)voices
+ RoundUp(num_voices
*sizeof(ALvoice
*), 16));
2648 props
= (struct ALsourceProps
*)((char*)voice
+ sizeof_voice
);
2652 ALsizei v_count
= mini(context
->VoiceCount
, num_voices
);
2653 for(;v
< v_count
;v
++)
2655 ALsizei s_count
= mini(old_sends
, num_sends
);
2658 /* Copy the old voice data and source property set to the new
2661 *voice
= *(context
->Voices
[v
]);
2662 for(i
= 0;i
< s_count
;i
++)
2663 voice
->Send
[i
] = context
->Voices
[v
]->Send
[i
];
2664 *props
= *(context
->Voices
[v
]->Props
);
2665 for(i
= 0;i
< s_count
;i
++)
2666 props
->Send
[i
] = context
->Voices
[v
]->Props
->Send
[i
];
2668 /* Set this voice's property set pointer and voice reference. */
2669 voice
->Props
= props
;
2672 /* Increment pointers to the next storage space. */
2673 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2674 props
= (struct ALsourceProps
*)((char*)voice
+ sizeof_voice
);
2677 /* Finish setting the voices' property set pointers and references. */
2678 for(;v
< num_voices
;v
++)
2680 voice
->Props
= props
;
2683 voice
= (ALvoice
*)((char*)props
+ sizeof_props
);
2684 props
= (struct ALsourceProps
*)((char*)voice
+ sizeof_voice
);
2687 al_free(context
->Voices
);
2688 context
->Voices
= voices
;
2689 context
->MaxVoices
= num_voices
;
2690 context
->VoiceCount
= mini(context
->VoiceCount
, num_voices
);
2694 /************************************************
2695 * Standard ALC functions
2696 ************************************************/
2700 * Return last ALC generated error code for the given device
2702 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2706 if(VerifyDevice(&device
))
2708 errorCode
= ATOMIC_EXCHANGE_SEQ(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2709 ALCdevice_DecRef(device
);
2712 errorCode
= ATOMIC_EXCHANGE_SEQ(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2718 /* alcSuspendContext
2720 * Suspends updates for the given context
2722 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2727 if(!VerifyContext(&context
))
2728 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2731 ALCcontext_DeferUpdates(context
, DeferAllowPlay
);
2732 ALCcontext_DecRef(context
);
2736 /* alcProcessContext
2738 * Resumes processing updates for the given context
2740 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2745 if(!VerifyContext(&context
))
2746 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2749 ALCcontext_ProcessUpdates(context
);
2750 ALCcontext_DecRef(context
);
2757 * Returns information about the device, and error strings
2759 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2761 const ALCchar
*value
= NULL
;
2769 case ALC_INVALID_ENUM
:
2770 value
= alcErrInvalidEnum
;
2773 case ALC_INVALID_VALUE
:
2774 value
= alcErrInvalidValue
;
2777 case ALC_INVALID_DEVICE
:
2778 value
= alcErrInvalidDevice
;
2781 case ALC_INVALID_CONTEXT
:
2782 value
= alcErrInvalidContext
;
2785 case ALC_OUT_OF_MEMORY
:
2786 value
= alcErrOutOfMemory
;
2789 case ALC_DEVICE_SPECIFIER
:
2790 value
= alcDefaultName
;
2793 case ALC_ALL_DEVICES_SPECIFIER
:
2794 if(VerifyDevice(&Device
))
2796 value
= al_string_get_cstr(Device
->DeviceName
);
2797 ALCdevice_DecRef(Device
);
2801 ProbeAllDevicesList();
2802 value
= al_string_get_cstr(alcAllDevicesList
);
2806 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2807 if(VerifyDevice(&Device
))
2809 value
= al_string_get_cstr(Device
->DeviceName
);
2810 ALCdevice_DecRef(Device
);
2814 ProbeCaptureDeviceList();
2815 value
= al_string_get_cstr(alcCaptureDeviceList
);
2819 /* Default devices are always first in the list */
2820 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2821 value
= alcDefaultName
;
2824 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2825 if(al_string_empty(alcAllDevicesList
))
2826 ProbeAllDevicesList();
2828 VerifyDevice(&Device
);
2830 free(alcDefaultAllDevicesSpecifier
);
2831 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2832 if(!alcDefaultAllDevicesSpecifier
)
2833 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2835 value
= alcDefaultAllDevicesSpecifier
;
2836 if(Device
) ALCdevice_DecRef(Device
);
2839 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2840 if(al_string_empty(alcCaptureDeviceList
))
2841 ProbeCaptureDeviceList();
2843 VerifyDevice(&Device
);
2845 free(alcCaptureDefaultDeviceSpecifier
);
2846 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2847 if(!alcCaptureDefaultDeviceSpecifier
)
2848 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2850 value
= alcCaptureDefaultDeviceSpecifier
;
2851 if(Device
) ALCdevice_DecRef(Device
);
2854 case ALC_EXTENSIONS
:
2855 if(!VerifyDevice(&Device
))
2856 value
= alcNoDeviceExtList
;
2859 value
= alcExtensionList
;
2860 ALCdevice_DecRef(Device
);
2864 case ALC_HRTF_SPECIFIER_SOFT
:
2865 if(!VerifyDevice(&Device
))
2866 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2869 almtx_lock(&Device
->BackendLock
);
2870 value
= (Device
->Hrtf
.Handle
? al_string_get_cstr(Device
->Hrtf
.Name
) : "");
2871 almtx_unlock(&Device
->BackendLock
);
2872 ALCdevice_DecRef(Device
);
2877 VerifyDevice(&Device
);
2878 alcSetError(Device
, ALC_INVALID_ENUM
);
2879 if(Device
) ALCdevice_DecRef(Device
);
2887 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2891 if(size
<= 0 || values
== NULL
)
2893 alcSetError(device
, ALC_INVALID_VALUE
);
2901 case ALC_MAJOR_VERSION
:
2902 values
[0] = alcMajorVersion
;
2904 case ALC_MINOR_VERSION
:
2905 values
[0] = alcMinorVersion
;
2908 case ALC_ATTRIBUTES_SIZE
:
2909 case ALC_ALL_ATTRIBUTES
:
2913 case ALC_MONO_SOURCES
:
2914 case ALC_STEREO_SOURCES
:
2915 case ALC_CAPTURE_SAMPLES
:
2916 case ALC_FORMAT_CHANNELS_SOFT
:
2917 case ALC_FORMAT_TYPE_SOFT
:
2918 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2922 alcSetError(NULL
, ALC_INVALID_ENUM
);
2928 if(device
->Type
== Capture
)
2932 case ALC_CAPTURE_SAMPLES
:
2933 almtx_lock(&device
->BackendLock
);
2934 values
[0] = V0(device
->Backend
,availableSamples
)();
2935 almtx_unlock(&device
->BackendLock
);
2939 values
[0] = device
->Connected
;
2943 alcSetError(device
, ALC_INVALID_ENUM
);
2952 case ALC_MAJOR_VERSION
:
2953 values
[0] = alcMajorVersion
;
2956 case ALC_MINOR_VERSION
:
2957 values
[0] = alcMinorVersion
;
2960 case ALC_EFX_MAJOR_VERSION
:
2961 values
[0] = alcEFXMajorVersion
;
2964 case ALC_EFX_MINOR_VERSION
:
2965 values
[0] = alcEFXMinorVersion
;
2968 case ALC_ATTRIBUTES_SIZE
:
2972 case ALC_ALL_ATTRIBUTES
:
2975 alcSetError(device
, ALC_INVALID_VALUE
);
2980 almtx_lock(&device
->BackendLock
);
2981 values
[i
++] = ALC_FREQUENCY
;
2982 values
[i
++] = device
->Frequency
;
2984 if(device
->Type
!= Loopback
)
2986 values
[i
++] = ALC_REFRESH
;
2987 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2989 values
[i
++] = ALC_SYNC
;
2990 values
[i
++] = ALC_FALSE
;
2994 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2995 values
[i
++] = device
->FmtChans
;
2997 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2998 values
[i
++] = device
->FmtType
;
3001 values
[i
++] = ALC_MONO_SOURCES
;
3002 values
[i
++] = device
->NumMonoSources
;
3004 values
[i
++] = ALC_STEREO_SOURCES
;
3005 values
[i
++] = device
->NumStereoSources
;
3007 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3008 values
[i
++] = device
->NumAuxSends
;
3010 values
[i
++] = ALC_HRTF_SOFT
;
3011 values
[i
++] = (device
->Hrtf
.Handle
? ALC_TRUE
: ALC_FALSE
);
3013 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3014 values
[i
++] = device
->Hrtf
.Status
;
3015 almtx_unlock(&device
->BackendLock
);
3021 values
[0] = device
->Frequency
;
3025 if(device
->Type
== Loopback
)
3027 alcSetError(device
, ALC_INVALID_DEVICE
);
3030 almtx_lock(&device
->BackendLock
);
3031 values
[0] = device
->Frequency
/ device
->UpdateSize
;
3032 almtx_unlock(&device
->BackendLock
);
3036 if(device
->Type
== Loopback
)
3038 alcSetError(device
, ALC_INVALID_DEVICE
);
3041 values
[0] = ALC_FALSE
;
3044 case ALC_FORMAT_CHANNELS_SOFT
:
3045 if(device
->Type
!= Loopback
)
3047 alcSetError(device
, ALC_INVALID_DEVICE
);
3050 values
[0] = device
->FmtChans
;
3053 case ALC_FORMAT_TYPE_SOFT
:
3054 if(device
->Type
!= Loopback
)
3056 alcSetError(device
, ALC_INVALID_DEVICE
);
3059 values
[0] = device
->FmtType
;
3062 case ALC_MONO_SOURCES
:
3063 values
[0] = device
->NumMonoSources
;
3066 case ALC_STEREO_SOURCES
:
3067 values
[0] = device
->NumStereoSources
;
3070 case ALC_MAX_AUXILIARY_SENDS
:
3071 values
[0] = device
->NumAuxSends
;
3075 values
[0] = device
->Connected
;
3079 values
[0] = (device
->Hrtf
.Handle
? ALC_TRUE
: ALC_FALSE
);
3082 case ALC_HRTF_STATUS_SOFT
:
3083 values
[0] = device
->Hrtf
.Status
;
3086 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
3087 almtx_lock(&device
->BackendLock
);
3088 FreeHrtfList(&device
->Hrtf
.List
);
3089 device
->Hrtf
.List
= EnumerateHrtf(device
->DeviceName
);
3090 values
[0] = (ALCint
)VECTOR_SIZE(device
->Hrtf
.List
);
3091 almtx_unlock(&device
->BackendLock
);
3095 alcSetError(device
, ALC_INVALID_ENUM
);
3103 * Returns information about the device and the version of OpenAL
3105 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
3107 VerifyDevice(&device
);
3108 if(size
<= 0 || values
== NULL
)
3109 alcSetError(device
, ALC_INVALID_VALUE
);
3111 GetIntegerv(device
, param
, size
, values
);
3112 if(device
) ALCdevice_DecRef(device
);
3115 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
3120 VerifyDevice(&device
);
3121 if(size
<= 0 || values
== NULL
)
3122 alcSetError(device
, ALC_INVALID_VALUE
);
3123 else if(!device
|| device
->Type
== Capture
)
3125 ivals
= malloc(size
* sizeof(ALCint
));
3126 size
= GetIntegerv(device
, pname
, size
, ivals
);
3127 for(i
= 0;i
< size
;i
++)
3128 values
[i
] = ivals
[i
];
3131 else /* render device */
3140 case ALC_ATTRIBUTES_SIZE
:
3144 case ALC_ALL_ATTRIBUTES
:
3146 alcSetError(device
, ALC_INVALID_VALUE
);
3150 almtx_lock(&device
->BackendLock
);
3151 values
[i
++] = ALC_FREQUENCY
;
3152 values
[i
++] = device
->Frequency
;
3154 if(device
->Type
!= Loopback
)
3156 values
[i
++] = ALC_REFRESH
;
3157 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3159 values
[i
++] = ALC_SYNC
;
3160 values
[i
++] = ALC_FALSE
;
3164 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3165 values
[i
++] = device
->FmtChans
;
3167 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3168 values
[i
++] = device
->FmtType
;
3171 values
[i
++] = ALC_MONO_SOURCES
;
3172 values
[i
++] = device
->NumMonoSources
;
3174 values
[i
++] = ALC_STEREO_SOURCES
;
3175 values
[i
++] = device
->NumStereoSources
;
3177 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3178 values
[i
++] = device
->NumAuxSends
;
3180 values
[i
++] = ALC_HRTF_SOFT
;
3181 values
[i
++] = (device
->Hrtf
.Handle
? ALC_TRUE
: ALC_FALSE
);
3183 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3184 values
[i
++] = device
->Hrtf
.Status
;
3186 clock
= V0(device
->Backend
,getClockLatency
)();
3187 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3188 values
[i
++] = clock
.ClockTime
;
3190 values
[i
++] = ALC_DEVICE_LATENCY_SOFT
;
3191 values
[i
++] = clock
.Latency
;
3192 almtx_unlock(&device
->BackendLock
);
3198 case ALC_DEVICE_CLOCK_SOFT
:
3199 almtx_lock(&device
->BackendLock
);
3201 while(((refcount
=ReadRef(&device
->MixCount
))&1) != 0)
3203 basecount
= device
->ClockBase
;
3204 samplecount
= device
->SamplesDone
;
3205 } while(refcount
!= ReadRef(&device
->MixCount
));
3206 *values
= basecount
+ (samplecount
*DEVICE_CLOCK_RES
/device
->Frequency
);
3207 almtx_unlock(&device
->BackendLock
);
3210 case ALC_DEVICE_LATENCY_SOFT
:
3212 almtx_lock(&device
->BackendLock
);
3213 clock
= V0(device
->Backend
,getClockLatency
)();
3214 almtx_unlock(&device
->BackendLock
);
3215 *values
= clock
.Latency
;
3219 case ALC_DEVICE_CLOCK_LATENCY_SOFT
:
3221 alcSetError(device
, ALC_INVALID_VALUE
);
3225 almtx_lock(&device
->BackendLock
);
3226 clock
= V0(device
->Backend
,getClockLatency
)();
3227 almtx_unlock(&device
->BackendLock
);
3228 values
[0] = clock
.ClockTime
;
3229 values
[1] = clock
.Latency
;
3234 ivals
= malloc(size
* sizeof(ALCint
));
3235 size
= GetIntegerv(device
, pname
, size
, ivals
);
3236 for(i
= 0;i
< size
;i
++)
3237 values
[i
] = ivals
[i
];
3243 ALCdevice_DecRef(device
);
3247 /* alcIsExtensionPresent
3249 * Determines if there is support for a particular extension
3251 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3253 ALCboolean bResult
= ALC_FALSE
;
3255 VerifyDevice(&device
);
3258 alcSetError(device
, ALC_INVALID_VALUE
);
3261 size_t len
= strlen(extName
);
3262 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3265 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3266 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3271 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3275 } while(isspace(*ptr
));
3280 ALCdevice_DecRef(device
);
3285 /* alcGetProcAddress
3287 * Retrieves the function address for a particular extension function
3289 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3291 ALCvoid
*ptr
= NULL
;
3295 VerifyDevice(&device
);
3296 alcSetError(device
, ALC_INVALID_VALUE
);
3297 if(device
) ALCdevice_DecRef(device
);
3302 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3304 ptr
= alcFunctions
[i
].address
;
3313 * Get the value for a particular ALC enumeration name
3315 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3321 VerifyDevice(&device
);
3322 alcSetError(device
, ALC_INVALID_VALUE
);
3323 if(device
) ALCdevice_DecRef(device
);
3328 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3330 val
= enumeration
[i
].value
;
3339 * Create and attach a context to the given device.
3341 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3343 ALCcontext
*ALContext
;
3348 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3351 alcSetError(device
, ALC_INVALID_DEVICE
);
3352 if(device
) ALCdevice_DecRef(device
);
3355 almtx_lock(&device
->BackendLock
);
3358 ATOMIC_STORE_SEQ(&device
->LastError
, ALC_NO_ERROR
);
3360 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3363 InitRef(&ALContext
->ref
, 1);
3364 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3366 ALContext
->Device
= device
;
3367 ATOMIC_INIT(&ALContext
->ActiveAuxSlotList
, NULL
);
3369 ALContext
->Voices
= NULL
;
3370 ALContext
->MaxVoices
= 0;
3371 ALContext
->VoiceCount
= 0;
3372 AllocateVoices(ALContext
, 256, device
->NumAuxSends
);
3374 if(!ALContext
|| !ALContext
->Voices
)
3376 almtx_unlock(&device
->BackendLock
);
3380 al_free(ALContext
->Voices
);
3381 ALContext
->Voices
= NULL
;
3387 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3388 ALCdevice_DecRef(device
);
3392 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3394 almtx_unlock(&device
->BackendLock
);
3396 al_free(ALContext
->Voices
);
3397 ALContext
->Voices
= NULL
;
3402 alcSetError(device
, err
);
3403 if(err
== ALC_INVALID_DEVICE
)
3405 V0(device
->Backend
,lock
)();
3406 aluHandleDisconnect(device
);
3407 V0(device
->Backend
,unlock
)();
3409 ALCdevice_DecRef(device
);
3413 ALCdevice_IncRef(ALContext
->Device
);
3414 InitContext(ALContext
);
3416 if(ConfigValueFloat(al_string_get_cstr(device
->DeviceName
), NULL
, "volume-adjust", &valf
))
3419 ERR("volume-adjust must be finite: %f\n", valf
);
3422 ALfloat db
= clampf(valf
, -24.0f
, 24.0f
);
3424 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf
, 24.0f
);
3425 ALContext
->GainBoost
= powf(10.0f
, db
/20.0f
);
3426 TRACE("volume-adjust gain: %f\n", ALContext
->GainBoost
);
3429 UpdateListenerProps(ALContext
);
3432 ALCcontext
*head
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
3434 ALContext
->next
= head
;
3435 } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCcontext
*,
3436 &device
->ContextList
, &head
, ALContext
) == 0);
3438 almtx_unlock(&device
->BackendLock
);
3440 ALCdevice_DecRef(device
);
3442 TRACE("Created context %p\n", ALContext
);
3446 /* alcDestroyContext
3448 * Remove a context from its device
3450 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3455 /* alcGetContextsDevice sets an error for invalid contexts */
3456 Device
= alcGetContextsDevice(context
);
3459 almtx_lock(&Device
->BackendLock
);
3460 ReleaseContext(context
, Device
);
3461 if(!ATOMIC_LOAD_SEQ(&Device
->ContextList
))
3463 V0(Device
->Backend
,stop
)();
3464 Device
->Flags
&= ~DEVICE_RUNNING
;
3466 almtx_unlock(&Device
->BackendLock
);
3472 /* alcGetCurrentContext
3474 * Returns the currently active context on the calling thread
3476 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3478 ALCcontext
*Context
= altss_get(LocalContext
);
3479 if(!Context
) Context
= ATOMIC_LOAD_SEQ(&GlobalContext
);
3483 /* alcGetThreadContext
3485 * Returns the currently active thread-local context
3487 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3489 return altss_get(LocalContext
);
3493 /* alcMakeContextCurrent
3495 * Makes the given context the active process-wide context, and removes the
3496 * thread-local context for the calling thread.
3498 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3500 /* context must be valid or NULL */
3501 if(context
&& !VerifyContext(&context
))
3503 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3506 /* context's reference count is already incremented */
3507 context
= ATOMIC_EXCHANGE_SEQ(ALCcontext
*, &GlobalContext
, context
);
3508 if(context
) ALCcontext_DecRef(context
);
3510 if((context
=altss_get(LocalContext
)) != NULL
)
3512 altss_set(LocalContext
, NULL
);
3513 ALCcontext_DecRef(context
);
3519 /* alcSetThreadContext
3521 * Makes the given context the active context for the current thread
3523 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3527 /* context must be valid or NULL */
3528 if(context
&& !VerifyContext(&context
))
3530 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3533 /* context's reference count is already incremented */
3534 old
= altss_get(LocalContext
);
3535 altss_set(LocalContext
, context
);
3536 if(old
) ALCcontext_DecRef(old
);
3542 /* alcGetContextsDevice
3544 * Returns the device that a particular context is attached to
3546 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3550 if(!VerifyContext(&Context
))
3552 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3555 Device
= Context
->Device
;
3556 ALCcontext_DecRef(Context
);
3564 * Opens the named device.
3566 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3574 if(!PlaybackBackend
.name
)
3576 alcSetError(NULL
, ALC_INVALID_VALUE
);
3580 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3582 /* Some old Windows apps hardcode these expecting OpenAL to use a
3583 * specific audio API, even when they're not enumerated. Creative's
3584 * router effectively ignores them too.
3586 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3587 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3592 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3595 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3600 InitRef(&device
->ref
, 1);
3601 device
->Connected
= ALC_TRUE
;
3602 device
->Type
= Playback
;
3603 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3606 device
->Bs2b
= NULL
;
3607 device
->Uhj_Encoder
= NULL
;
3608 VECTOR_INIT(device
->Hrtf
.List
);
3609 AL_STRING_INIT(device
->Hrtf
.Name
);
3610 device
->Render_Mode
= NormalRender
;
3611 AL_STRING_INIT(device
->DeviceName
);
3612 device
->Dry
.Buffer
= NULL
;
3613 device
->Dry
.NumChannels
= 0;
3614 device
->FOAOut
.Buffer
= NULL
;
3615 device
->FOAOut
.NumChannels
= 0;
3616 device
->RealOut
.Buffer
= NULL
;
3617 device
->RealOut
.NumChannels
= 0;
3619 ATOMIC_INIT(&device
->ContextList
, NULL
);
3621 device
->ClockBase
= 0;
3622 device
->SamplesDone
= 0;
3624 device
->SourcesMax
= 256;
3625 device
->AuxiliaryEffectSlotMax
= 64;
3626 device
->NumAuxSends
= DEFAULT_SENDS
;
3628 InitUIntMap(&device
->BufferMap
, ~0);
3629 InitUIntMap(&device
->EffectMap
, ~0);
3630 InitUIntMap(&device
->FilterMap
, ~0);
3633 device
->FmtChans
= DevFmtChannelsDefault
;
3634 device
->FmtType
= DevFmtTypeDefault
;
3635 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3636 device
->IsHeadphones
= AL_FALSE
;
3637 device
->AmbiFmt
= AmbiFormat_Default
;
3638 device
->NumUpdates
= 4;
3639 device
->UpdateSize
= 1024;
3641 if(!PlaybackBackend
.getFactory
)
3642 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3643 ALCbackend_Playback
);
3646 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3647 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3649 if(!device
->Backend
)
3652 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3657 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3659 static const struct {
3660 const char name
[16];
3661 enum DevFmtChannels chans
;
3663 { "mono", DevFmtMono
},
3664 { "stereo", DevFmtStereo
},
3665 { "quad", DevFmtQuad
},
3666 { "surround51", DevFmtX51
},
3667 { "surround61", DevFmtX61
},
3668 { "surround71", DevFmtX71
},
3669 { "surround51rear", DevFmtX51Rear
},
3670 { "ambi1", DevFmtAmbi1
},
3671 { "ambi2", DevFmtAmbi2
},
3672 { "ambi3", DevFmtAmbi3
},
3676 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3678 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3680 device
->FmtChans
= chanlist
[i
].chans
;
3681 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3685 if(i
== COUNTOF(chanlist
))
3686 ERR("Unsupported channels: %s\n", fmt
);
3688 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3690 static const struct {
3691 const char name
[16];
3692 enum DevFmtType type
;
3694 { "int8", DevFmtByte
},
3695 { "uint8", DevFmtUByte
},
3696 { "int16", DevFmtShort
},
3697 { "uint16", DevFmtUShort
},
3698 { "int32", DevFmtInt
},
3699 { "uint32", DevFmtUInt
},
3700 { "float32", DevFmtFloat
},
3704 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3706 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3708 device
->FmtType
= typelist
[i
].type
;
3709 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3713 if(i
== COUNTOF(typelist
))
3714 ERR("Unsupported sample-type: %s\n", fmt
);
3717 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3719 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3720 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3721 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3722 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3725 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3726 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3728 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3729 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3730 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3731 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3733 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
3734 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
3736 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3737 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
3739 ConfigValueInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3740 device
->NumAuxSends
= clampi(device
->NumAuxSends
, 0, MAX_SENDS
);
3742 device
->NumStereoSources
= 1;
3743 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
3745 // Find a playback device to open
3746 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3748 DELETE_OBJ(device
->Backend
);
3750 alcSetError(NULL
, err
);
3753 almtx_init(&device
->BackendLock
, almtx_plain
);
3755 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "ambi-format", &fmt
))
3757 if(strcasecmp(fmt
, "fuma") == 0)
3758 device
->AmbiFmt
= AmbiFormat_FuMa
;
3759 else if(strcasecmp(fmt
, "acn+sn3d") == 0)
3760 device
->AmbiFmt
= AmbiFormat_ACN_SN3D
;
3761 else if(strcasecmp(fmt
, "acn+n3d") == 0)
3762 device
->AmbiFmt
= AmbiFormat_ACN_N3D
;
3764 ERR("Unsupported ambi-format: %s\n", fmt
);
3767 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3769 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3770 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3772 device
->DefaultSlot
= NULL
;
3773 ERR("Failed to initialize the default effect slot\n");
3777 aluInitEffectPanning(device
->DefaultSlot
);
3778 if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3780 DeinitEffectSlot(device
->DefaultSlot
);
3781 device
->DefaultSlot
= NULL
;
3782 ERR("Failed to initialize the default effect\n");
3788 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
3790 device
->next
= head
;
3791 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice
*, &DeviceList
, &head
, device
));
3794 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3800 * Closes the given device.
3802 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3804 ALCdevice
*iter
, *origdev
;
3808 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
3812 } while((iter
=iter
->next
) != NULL
);
3813 if(!iter
|| iter
->Type
== Capture
)
3815 alcSetError(iter
, ALC_INVALID_DEVICE
);
3819 almtx_lock(&device
->BackendLock
);
3822 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice
*, &DeviceList
, &origdev
, device
->next
))
3824 ALCdevice
*volatile*list
= &origdev
->next
;
3829 *list
= (*list
)->next
;
3832 list
= &(*list
)->next
;
3837 ctx
= ATOMIC_LOAD_SEQ(&device
->ContextList
);
3840 ALCcontext
*next
= ctx
->next
;
3841 WARN("Releasing context %p\n", ctx
);
3842 ReleaseContext(ctx
, device
);
3845 if((device
->Flags
&DEVICE_RUNNING
))
3846 V0(device
->Backend
,stop
)();
3847 device
->Flags
&= ~DEVICE_RUNNING
;
3848 almtx_unlock(&device
->BackendLock
);
3850 ALCdevice_DecRef(device
);
3856 /************************************************
3857 * ALC capture functions
3858 ************************************************/
3859 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3861 ALCdevice
*device
= NULL
;
3866 if(!CaptureBackend
.name
)
3868 alcSetError(NULL
, ALC_INVALID_VALUE
);
3874 alcSetError(NULL
, ALC_INVALID_VALUE
);
3878 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3881 device
= al_calloc(16, sizeof(ALCdevice
));
3884 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3889 InitRef(&device
->ref
, 1);
3890 device
->Connected
= ALC_TRUE
;
3891 device
->Type
= Capture
;
3893 VECTOR_INIT(device
->Hrtf
.List
);
3894 AL_STRING_INIT(device
->Hrtf
.Name
);
3896 AL_STRING_INIT(device
->DeviceName
);
3897 device
->Dry
.Buffer
= NULL
;
3898 device
->Dry
.NumChannels
= 0;
3899 device
->FOAOut
.Buffer
= NULL
;
3900 device
->FOAOut
.NumChannels
= 0;
3901 device
->RealOut
.Buffer
= NULL
;
3902 device
->RealOut
.NumChannels
= 0;
3904 InitUIntMap(&device
->BufferMap
, ~0);
3905 InitUIntMap(&device
->EffectMap
, ~0);
3906 InitUIntMap(&device
->FilterMap
, ~0);
3908 if(!CaptureBackend
.getFactory
)
3909 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3910 ALCbackend_Capture
);
3913 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3914 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3916 if(!device
->Backend
)
3919 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3923 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3924 device
->Frequency
= frequency
;
3926 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3927 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3930 alcSetError(NULL
, ALC_INVALID_ENUM
);
3933 device
->IsHeadphones
= AL_FALSE
;
3934 device
->AmbiFmt
= AmbiFormat_Default
;
3936 device
->UpdateSize
= samples
;
3937 device
->NumUpdates
= 1;
3939 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3942 alcSetError(NULL
, err
);
3945 almtx_init(&device
->BackendLock
, almtx_plain
);
3948 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
3950 device
->next
= head
;
3951 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice
*, &DeviceList
, &head
, device
));
3954 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3958 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3960 ALCdevice
*iter
, *origdev
;
3963 iter
= ATOMIC_LOAD_SEQ(&DeviceList
);
3967 } while((iter
=iter
->next
) != NULL
);
3968 if(!iter
|| iter
->Type
!= Capture
)
3970 alcSetError(iter
, ALC_INVALID_DEVICE
);
3976 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice
*, &DeviceList
, &origdev
, device
->next
))
3978 ALCdevice
*volatile*list
= &origdev
->next
;
3983 *list
= (*list
)->next
;
3986 list
= &(*list
)->next
;
3991 ALCdevice_DecRef(device
);
3996 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3998 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3999 alcSetError(device
, ALC_INVALID_DEVICE
);
4002 almtx_lock(&device
->BackendLock
);
4003 if(!device
->Connected
)
4004 alcSetError(device
, ALC_INVALID_DEVICE
);
4005 else if(!(device
->Flags
&DEVICE_RUNNING
))
4007 if(V0(device
->Backend
,start
)())
4008 device
->Flags
|= DEVICE_RUNNING
;
4011 aluHandleDisconnect(device
);
4012 alcSetError(device
, ALC_INVALID_DEVICE
);
4015 almtx_unlock(&device
->BackendLock
);
4018 if(device
) ALCdevice_DecRef(device
);
4021 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
4023 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4024 alcSetError(device
, ALC_INVALID_DEVICE
);
4027 almtx_lock(&device
->BackendLock
);
4028 if((device
->Flags
&DEVICE_RUNNING
))
4029 V0(device
->Backend
,stop
)();
4030 device
->Flags
&= ~DEVICE_RUNNING
;
4031 almtx_unlock(&device
->BackendLock
);
4034 if(device
) ALCdevice_DecRef(device
);
4037 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4039 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
4040 alcSetError(device
, ALC_INVALID_DEVICE
);
4043 ALCenum err
= ALC_INVALID_VALUE
;
4045 almtx_lock(&device
->BackendLock
);
4046 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
4047 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
4048 almtx_unlock(&device
->BackendLock
);
4050 if(err
!= ALC_NO_ERROR
)
4051 alcSetError(device
, err
);
4053 if(device
) ALCdevice_DecRef(device
);
4057 /************************************************
4058 * ALC loopback functions
4059 ************************************************/
4061 /* alcLoopbackOpenDeviceSOFT
4063 * Open a loopback device, for manual rendering.
4065 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
4067 ALCbackendFactory
*factory
;
4072 /* Make sure the device name, if specified, is us. */
4073 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
4075 alcSetError(NULL
, ALC_INVALID_VALUE
);
4079 device
= al_calloc(16, sizeof(ALCdevice
));
4082 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4087 InitRef(&device
->ref
, 1);
4088 device
->Connected
= ALC_TRUE
;
4089 device
->Type
= Loopback
;
4090 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
4093 VECTOR_INIT(device
->Hrtf
.List
);
4094 AL_STRING_INIT(device
->Hrtf
.Name
);
4095 device
->Bs2b
= NULL
;
4096 device
->Uhj_Encoder
= NULL
;
4097 device
->Render_Mode
= NormalRender
;
4098 AL_STRING_INIT(device
->DeviceName
);
4099 device
->Dry
.Buffer
= NULL
;
4100 device
->Dry
.NumChannels
= 0;
4101 device
->FOAOut
.Buffer
= NULL
;
4102 device
->FOAOut
.NumChannels
= 0;
4103 device
->RealOut
.Buffer
= NULL
;
4104 device
->RealOut
.NumChannels
= 0;
4106 ATOMIC_INIT(&device
->ContextList
, NULL
);
4108 device
->ClockBase
= 0;
4109 device
->SamplesDone
= 0;
4111 device
->SourcesMax
= 256;
4112 device
->AuxiliaryEffectSlotMax
= 64;
4113 device
->NumAuxSends
= DEFAULT_SENDS
;
4115 InitUIntMap(&device
->BufferMap
, ~0);
4116 InitUIntMap(&device
->EffectMap
, ~0);
4117 InitUIntMap(&device
->FilterMap
, ~0);
4119 factory
= ALCloopbackFactory_getFactory();
4120 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
4121 if(!device
->Backend
)
4124 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
4127 almtx_init(&device
->BackendLock
, almtx_plain
);
4130 device
->NumUpdates
= 0;
4131 device
->UpdateSize
= 0;
4133 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
4134 device
->FmtChans
= DevFmtChannelsDefault
;
4135 device
->FmtType
= DevFmtTypeDefault
;
4136 device
->IsHeadphones
= AL_FALSE
;
4137 device
->AmbiFmt
= AmbiFormat_Default
;
4139 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
4140 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
4142 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
4143 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 64;
4145 ConfigValueInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
4146 device
->NumAuxSends
= clampi(device
->NumAuxSends
, 0, MAX_SENDS
);
4148 device
->NumStereoSources
= 1;
4149 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
4151 // Open the "backend"
4152 V(device
->Backend
,open
)("Loopback");
4155 ALCdevice
*head
= ATOMIC_LOAD_SEQ(&DeviceList
);
4157 device
->next
= head
;
4158 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice
*, &DeviceList
, &head
, device
));
4161 TRACE("Created device %p\n", device
);
4165 /* alcIsRenderFormatSupportedSOFT
4167 * Determines if the loopback device supports the given format for rendering.
4169 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
4171 ALCboolean ret
= ALC_FALSE
;
4173 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4174 alcSetError(device
, ALC_INVALID_DEVICE
);
4176 alcSetError(device
, ALC_INVALID_VALUE
);
4179 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
4180 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
4181 freq
>= MIN_OUTPUT_RATE
)
4184 if(device
) ALCdevice_DecRef(device
);
4189 /* alcRenderSamplesSOFT
4191 * Renders some samples into a buffer, using the format last set by the
4192 * attributes given to alcCreateContext.
4194 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
4196 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
4197 alcSetError(device
, ALC_INVALID_DEVICE
);
4198 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
4199 alcSetError(device
, ALC_INVALID_VALUE
);
4202 V0(device
->Backend
,lock
)();
4203 aluMixData(device
, buffer
, samples
);
4204 V0(device
->Backend
,unlock
)();
4206 if(device
) ALCdevice_DecRef(device
);
4210 /************************************************
4211 * ALC DSP pause/resume functions
4212 ************************************************/
4214 /* alcDevicePauseSOFT
4216 * Pause the DSP to stop audio processing.
4218 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
4220 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4221 alcSetError(device
, ALC_INVALID_DEVICE
);
4224 almtx_lock(&device
->BackendLock
);
4225 if((device
->Flags
&DEVICE_RUNNING
))
4226 V0(device
->Backend
,stop
)();
4227 device
->Flags
&= ~DEVICE_RUNNING
;
4228 device
->Flags
|= DEVICE_PAUSED
;
4229 almtx_unlock(&device
->BackendLock
);
4231 if(device
) ALCdevice_DecRef(device
);
4234 /* alcDeviceResumeSOFT
4236 * Resume the DSP to restart audio processing.
4238 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
4240 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
4241 alcSetError(device
, ALC_INVALID_DEVICE
);
4244 almtx_lock(&device
->BackendLock
);
4245 if((device
->Flags
&DEVICE_PAUSED
))
4247 device
->Flags
&= ~DEVICE_PAUSED
;
4248 if(ATOMIC_LOAD_SEQ(&device
->ContextList
) != NULL
)
4250 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4251 device
->Flags
|= DEVICE_RUNNING
;
4254 alcSetError(device
, ALC_INVALID_DEVICE
);
4255 V0(device
->Backend
,lock
)();
4256 aluHandleDisconnect(device
);
4257 V0(device
->Backend
,unlock
)();
4261 almtx_unlock(&device
->BackendLock
);
4263 if(device
) ALCdevice_DecRef(device
);
4267 /************************************************
4268 * ALC HRTF functions
4269 ************************************************/
4271 /* alcGetStringiSOFT
4273 * Gets a string parameter at the given index.
4275 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4277 const ALCchar
*str
= NULL
;
4279 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4280 alcSetError(device
, ALC_INVALID_DEVICE
);
4281 else switch(paramName
)
4283 case ALC_HRTF_SPECIFIER_SOFT
:
4284 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->Hrtf
.List
))
4285 str
= al_string_get_cstr(VECTOR_ELEM(device
->Hrtf
.List
, index
).name
);
4287 alcSetError(device
, ALC_INVALID_VALUE
);
4291 alcSetError(device
, ALC_INVALID_ENUM
);
4294 if(device
) ALCdevice_DecRef(device
);
4299 /* alcResetDeviceSOFT
4301 * Resets the given device output, using the specified attribute list.
4303 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4308 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4311 alcSetError(device
, ALC_INVALID_DEVICE
);
4312 if(device
) ALCdevice_DecRef(device
);
4315 almtx_lock(&device
->BackendLock
);
4318 err
= UpdateDeviceParams(device
, attribs
);
4319 almtx_unlock(&device
->BackendLock
);
4321 if(err
!= ALC_NO_ERROR
)
4323 alcSetError(device
, err
);
4324 if(err
== ALC_INVALID_DEVICE
)
4326 V0(device
->Backend
,lock
)();
4327 aluHandleDisconnect(device
);
4328 V0(device
->Backend
,unlock
)();
4330 ALCdevice_DecRef(device
);
4333 ALCdevice_DecRef(device
);