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
32 #include "alListener.h"
36 #include "alAuxEffectSlot.h"
39 #include "uhjfilter.h"
46 #include "backends/base.h"
49 /************************************************
51 ************************************************/
54 ALCbackendFactory
* (*getFactory
)(void);
55 ALCboolean (*Init
)(BackendFuncs
*);
57 void (*Probe
)(enum DevProbe
);
61 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
62 static struct BackendInfo BackendList
[] = {
64 { "jack", ALCjackBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
66 #ifdef HAVE_PULSEAUDIO
67 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
70 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
73 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
76 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
79 { "solaris", ALCsolarisBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
82 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
85 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
88 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
91 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
94 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
97 { "port", ALCportBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
100 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
103 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
105 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
108 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
112 static struct BackendInfo PlaybackBackend
;
113 static struct BackendInfo CaptureBackend
;
116 /************************************************
117 * Functions, enums, and errors
118 ************************************************/
119 typedef struct ALCfunction
{
120 const ALCchar
*funcName
;
124 typedef struct ALCenums
{
125 const ALCchar
*enumName
;
129 #define DECL(x) { #x, (ALCvoid*)(x) }
130 static const ALCfunction alcFunctions
[] = {
131 DECL(alcCreateContext
),
132 DECL(alcMakeContextCurrent
),
133 DECL(alcProcessContext
),
134 DECL(alcSuspendContext
),
135 DECL(alcDestroyContext
),
136 DECL(alcGetCurrentContext
),
137 DECL(alcGetContextsDevice
),
139 DECL(alcCloseDevice
),
141 DECL(alcIsExtensionPresent
),
142 DECL(alcGetProcAddress
),
143 DECL(alcGetEnumValue
),
145 DECL(alcGetIntegerv
),
146 DECL(alcCaptureOpenDevice
),
147 DECL(alcCaptureCloseDevice
),
148 DECL(alcCaptureStart
),
149 DECL(alcCaptureStop
),
150 DECL(alcCaptureSamples
),
152 DECL(alcSetThreadContext
),
153 DECL(alcGetThreadContext
),
155 DECL(alcLoopbackOpenDeviceSOFT
),
156 DECL(alcIsRenderFormatSupportedSOFT
),
157 DECL(alcRenderSamplesSOFT
),
159 DECL(alcDevicePauseSOFT
),
160 DECL(alcDeviceResumeSOFT
),
162 DECL(alcGetStringiSOFT
),
163 DECL(alcResetDeviceSOFT
),
165 DECL(alcGetInteger64vSOFT
),
180 DECL(alIsExtensionPresent
),
181 DECL(alGetProcAddress
),
182 DECL(alGetEnumValue
),
189 DECL(alGetListenerf
),
190 DECL(alGetListener3f
),
191 DECL(alGetListenerfv
),
192 DECL(alGetListeneri
),
193 DECL(alGetListener3i
),
194 DECL(alGetListeneriv
),
196 DECL(alDeleteSources
),
212 DECL(alSourceRewindv
),
213 DECL(alSourcePausev
),
216 DECL(alSourceRewind
),
218 DECL(alSourceQueueBuffers
),
219 DECL(alSourceUnqueueBuffers
),
221 DECL(alDeleteBuffers
),
236 DECL(alDopplerFactor
),
237 DECL(alDopplerVelocity
),
238 DECL(alSpeedOfSound
),
239 DECL(alDistanceModel
),
242 DECL(alDeleteFilters
),
253 DECL(alDeleteEffects
),
263 DECL(alGenAuxiliaryEffectSlots
),
264 DECL(alDeleteAuxiliaryEffectSlots
),
265 DECL(alIsAuxiliaryEffectSlot
),
266 DECL(alAuxiliaryEffectSloti
),
267 DECL(alAuxiliaryEffectSlotiv
),
268 DECL(alAuxiliaryEffectSlotf
),
269 DECL(alAuxiliaryEffectSlotfv
),
270 DECL(alGetAuxiliaryEffectSloti
),
271 DECL(alGetAuxiliaryEffectSlotiv
),
272 DECL(alGetAuxiliaryEffectSlotf
),
273 DECL(alGetAuxiliaryEffectSlotfv
),
275 DECL(alBufferSubDataSOFT
),
277 DECL(alBufferSamplesSOFT
),
278 DECL(alBufferSubSamplesSOFT
),
279 DECL(alGetBufferSamplesSOFT
),
280 DECL(alIsBufferFormatSupportedSOFT
),
282 DECL(alDeferUpdatesSOFT
),
283 DECL(alProcessUpdatesSOFT
),
286 DECL(alSource3dSOFT
),
287 DECL(alSourcedvSOFT
),
288 DECL(alGetSourcedSOFT
),
289 DECL(alGetSource3dSOFT
),
290 DECL(alGetSourcedvSOFT
),
291 DECL(alSourcei64SOFT
),
292 DECL(alSource3i64SOFT
),
293 DECL(alSourcei64vSOFT
),
294 DECL(alGetSourcei64SOFT
),
295 DECL(alGetSource3i64SOFT
),
296 DECL(alGetSourcei64vSOFT
),
302 #define DECL(x) { #x, (x) }
303 static const ALCenums enumeration
[] = {
308 DECL(ALC_MAJOR_VERSION
),
309 DECL(ALC_MINOR_VERSION
),
310 DECL(ALC_ATTRIBUTES_SIZE
),
311 DECL(ALC_ALL_ATTRIBUTES
),
312 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
313 DECL(ALC_DEVICE_SPECIFIER
),
314 DECL(ALC_ALL_DEVICES_SPECIFIER
),
315 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
316 DECL(ALC_EXTENSIONS
),
320 DECL(ALC_MONO_SOURCES
),
321 DECL(ALC_STEREO_SOURCES
),
322 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
323 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
324 DECL(ALC_CAPTURE_SAMPLES
),
327 DECL(ALC_EFX_MAJOR_VERSION
),
328 DECL(ALC_EFX_MINOR_VERSION
),
329 DECL(ALC_MAX_AUXILIARY_SENDS
),
331 DECL(ALC_FORMAT_CHANNELS_SOFT
),
332 DECL(ALC_FORMAT_TYPE_SOFT
),
335 DECL(ALC_STEREO_SOFT
),
337 DECL(ALC_5POINT1_SOFT
),
338 DECL(ALC_6POINT1_SOFT
),
339 DECL(ALC_7POINT1_SOFT
),
342 DECL(ALC_UNSIGNED_BYTE_SOFT
),
343 DECL(ALC_SHORT_SOFT
),
344 DECL(ALC_UNSIGNED_SHORT_SOFT
),
346 DECL(ALC_UNSIGNED_INT_SOFT
),
347 DECL(ALC_FLOAT_SOFT
),
350 DECL(ALC_DONT_CARE_SOFT
),
351 DECL(ALC_HRTF_STATUS_SOFT
),
352 DECL(ALC_HRTF_DISABLED_SOFT
),
353 DECL(ALC_HRTF_ENABLED_SOFT
),
354 DECL(ALC_HRTF_DENIED_SOFT
),
355 DECL(ALC_HRTF_REQUIRED_SOFT
),
356 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
357 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
358 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
359 DECL(ALC_HRTF_SPECIFIER_SOFT
),
360 DECL(ALC_HRTF_ID_SOFT
),
363 DECL(ALC_INVALID_DEVICE
),
364 DECL(ALC_INVALID_CONTEXT
),
365 DECL(ALC_INVALID_ENUM
),
366 DECL(ALC_INVALID_VALUE
),
367 DECL(ALC_OUT_OF_MEMORY
),
375 DECL(AL_SOURCE_RELATIVE
),
376 DECL(AL_CONE_INNER_ANGLE
),
377 DECL(AL_CONE_OUTER_ANGLE
),
387 DECL(AL_ORIENTATION
),
388 DECL(AL_REFERENCE_DISTANCE
),
389 DECL(AL_ROLLOFF_FACTOR
),
390 DECL(AL_CONE_OUTER_GAIN
),
391 DECL(AL_MAX_DISTANCE
),
393 DECL(AL_SAMPLE_OFFSET
),
394 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
395 DECL(AL_BYTE_OFFSET
),
396 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
397 DECL(AL_SOURCE_TYPE
),
400 DECL(AL_UNDETERMINED
),
401 DECL(AL_METERS_PER_UNIT
),
402 DECL(AL_LOOP_POINTS_SOFT
),
403 DECL(AL_DIRECT_CHANNELS_SOFT
),
405 DECL(AL_DIRECT_FILTER
),
406 DECL(AL_AUXILIARY_SEND_FILTER
),
407 DECL(AL_AIR_ABSORPTION_FACTOR
),
408 DECL(AL_ROOM_ROLLOFF_FACTOR
),
409 DECL(AL_CONE_OUTER_GAINHF
),
410 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
412 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
414 DECL(AL_SOURCE_STATE
),
420 DECL(AL_BUFFERS_QUEUED
),
421 DECL(AL_BUFFERS_PROCESSED
),
423 DECL(AL_FORMAT_MONO8
),
424 DECL(AL_FORMAT_MONO16
),
425 DECL(AL_FORMAT_MONO_FLOAT32
),
426 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
427 DECL(AL_FORMAT_STEREO8
),
428 DECL(AL_FORMAT_STEREO16
),
429 DECL(AL_FORMAT_STEREO_FLOAT32
),
430 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
431 DECL(AL_FORMAT_MONO_IMA4
),
432 DECL(AL_FORMAT_STEREO_IMA4
),
433 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
434 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
435 DECL(AL_FORMAT_QUAD8_LOKI
),
436 DECL(AL_FORMAT_QUAD16_LOKI
),
437 DECL(AL_FORMAT_QUAD8
),
438 DECL(AL_FORMAT_QUAD16
),
439 DECL(AL_FORMAT_QUAD32
),
440 DECL(AL_FORMAT_51CHN8
),
441 DECL(AL_FORMAT_51CHN16
),
442 DECL(AL_FORMAT_51CHN32
),
443 DECL(AL_FORMAT_61CHN8
),
444 DECL(AL_FORMAT_61CHN16
),
445 DECL(AL_FORMAT_61CHN32
),
446 DECL(AL_FORMAT_71CHN8
),
447 DECL(AL_FORMAT_71CHN16
),
448 DECL(AL_FORMAT_71CHN32
),
449 DECL(AL_FORMAT_REAR8
),
450 DECL(AL_FORMAT_REAR16
),
451 DECL(AL_FORMAT_REAR32
),
452 DECL(AL_FORMAT_MONO_MULAW
),
453 DECL(AL_FORMAT_MONO_MULAW_EXT
),
454 DECL(AL_FORMAT_STEREO_MULAW
),
455 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
456 DECL(AL_FORMAT_QUAD_MULAW
),
457 DECL(AL_FORMAT_51CHN_MULAW
),
458 DECL(AL_FORMAT_61CHN_MULAW
),
459 DECL(AL_FORMAT_71CHN_MULAW
),
460 DECL(AL_FORMAT_REAR_MULAW
),
461 DECL(AL_FORMAT_MONO_ALAW_EXT
),
462 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
465 DECL(AL_MONO16_SOFT
),
466 DECL(AL_MONO32F_SOFT
),
467 DECL(AL_STEREO8_SOFT
),
468 DECL(AL_STEREO16_SOFT
),
469 DECL(AL_STEREO32F_SOFT
),
471 DECL(AL_QUAD16_SOFT
),
472 DECL(AL_QUAD32F_SOFT
),
474 DECL(AL_REAR16_SOFT
),
475 DECL(AL_REAR32F_SOFT
),
476 DECL(AL_5POINT1_8_SOFT
),
477 DECL(AL_5POINT1_16_SOFT
),
478 DECL(AL_5POINT1_32F_SOFT
),
479 DECL(AL_6POINT1_8_SOFT
),
480 DECL(AL_6POINT1_16_SOFT
),
481 DECL(AL_6POINT1_32F_SOFT
),
482 DECL(AL_7POINT1_8_SOFT
),
483 DECL(AL_7POINT1_16_SOFT
),
484 DECL(AL_7POINT1_32F_SOFT
),
485 DECL(AL_FORMAT_BFORMAT2D_8
),
486 DECL(AL_FORMAT_BFORMAT2D_16
),
487 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
488 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
489 DECL(AL_FORMAT_BFORMAT3D_8
),
490 DECL(AL_FORMAT_BFORMAT3D_16
),
491 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
492 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
495 DECL(AL_STEREO_SOFT
),
498 DECL(AL_5POINT1_SOFT
),
499 DECL(AL_6POINT1_SOFT
),
500 DECL(AL_7POINT1_SOFT
),
503 DECL(AL_UNSIGNED_BYTE_SOFT
),
505 DECL(AL_UNSIGNED_SHORT_SOFT
),
507 DECL(AL_UNSIGNED_INT_SOFT
),
509 DECL(AL_DOUBLE_SOFT
),
511 DECL(AL_UNSIGNED_BYTE3_SOFT
),
517 DECL(AL_INTERNAL_FORMAT_SOFT
),
518 DECL(AL_BYTE_LENGTH_SOFT
),
519 DECL(AL_SAMPLE_LENGTH_SOFT
),
520 DECL(AL_SEC_LENGTH_SOFT
),
521 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
522 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
529 DECL(AL_INVALID_NAME
),
530 DECL(AL_INVALID_ENUM
),
531 DECL(AL_INVALID_VALUE
),
532 DECL(AL_INVALID_OPERATION
),
533 DECL(AL_OUT_OF_MEMORY
),
540 DECL(AL_DOPPLER_FACTOR
),
541 DECL(AL_DOPPLER_VELOCITY
),
542 DECL(AL_DISTANCE_MODEL
),
543 DECL(AL_SPEED_OF_SOUND
),
544 DECL(AL_SOURCE_DISTANCE_MODEL
),
545 DECL(AL_DEFERRED_UPDATES_SOFT
),
547 DECL(AL_INVERSE_DISTANCE
),
548 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
549 DECL(AL_LINEAR_DISTANCE
),
550 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
551 DECL(AL_EXPONENT_DISTANCE
),
552 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
554 DECL(AL_FILTER_TYPE
),
555 DECL(AL_FILTER_NULL
),
556 DECL(AL_FILTER_LOWPASS
),
557 DECL(AL_FILTER_HIGHPASS
),
558 DECL(AL_FILTER_BANDPASS
),
560 DECL(AL_LOWPASS_GAIN
),
561 DECL(AL_LOWPASS_GAINHF
),
563 DECL(AL_HIGHPASS_GAIN
),
564 DECL(AL_HIGHPASS_GAINLF
),
566 DECL(AL_BANDPASS_GAIN
),
567 DECL(AL_BANDPASS_GAINHF
),
568 DECL(AL_BANDPASS_GAINLF
),
570 DECL(AL_EFFECT_TYPE
),
571 DECL(AL_EFFECT_NULL
),
572 DECL(AL_EFFECT_REVERB
),
573 DECL(AL_EFFECT_EAXREVERB
),
574 DECL(AL_EFFECT_CHORUS
),
575 DECL(AL_EFFECT_DISTORTION
),
576 DECL(AL_EFFECT_ECHO
),
577 DECL(AL_EFFECT_FLANGER
),
579 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
580 DECL(AL_EFFECT_VOCAL_MORPHER
),
581 DECL(AL_EFFECT_PITCH_SHIFTER
),
583 DECL(AL_EFFECT_RING_MODULATOR
),
585 DECL(AL_EFFECT_AUTOWAH
),
587 DECL(AL_EFFECT_COMPRESSOR
),
588 DECL(AL_EFFECT_EQUALIZER
),
589 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
590 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
592 DECL(AL_EAXREVERB_DENSITY
),
593 DECL(AL_EAXREVERB_DIFFUSION
),
594 DECL(AL_EAXREVERB_GAIN
),
595 DECL(AL_EAXREVERB_GAINHF
),
596 DECL(AL_EAXREVERB_GAINLF
),
597 DECL(AL_EAXREVERB_DECAY_TIME
),
598 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
599 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
600 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
601 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
602 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
603 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
604 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
605 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
606 DECL(AL_EAXREVERB_ECHO_TIME
),
607 DECL(AL_EAXREVERB_ECHO_DEPTH
),
608 DECL(AL_EAXREVERB_MODULATION_TIME
),
609 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
610 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
611 DECL(AL_EAXREVERB_HFREFERENCE
),
612 DECL(AL_EAXREVERB_LFREFERENCE
),
613 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
614 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
616 DECL(AL_REVERB_DENSITY
),
617 DECL(AL_REVERB_DIFFUSION
),
618 DECL(AL_REVERB_GAIN
),
619 DECL(AL_REVERB_GAINHF
),
620 DECL(AL_REVERB_DECAY_TIME
),
621 DECL(AL_REVERB_DECAY_HFRATIO
),
622 DECL(AL_REVERB_REFLECTIONS_GAIN
),
623 DECL(AL_REVERB_REFLECTIONS_DELAY
),
624 DECL(AL_REVERB_LATE_REVERB_GAIN
),
625 DECL(AL_REVERB_LATE_REVERB_DELAY
),
626 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
627 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
628 DECL(AL_REVERB_DECAY_HFLIMIT
),
630 DECL(AL_CHORUS_WAVEFORM
),
631 DECL(AL_CHORUS_PHASE
),
632 DECL(AL_CHORUS_RATE
),
633 DECL(AL_CHORUS_DEPTH
),
634 DECL(AL_CHORUS_FEEDBACK
),
635 DECL(AL_CHORUS_DELAY
),
637 DECL(AL_DISTORTION_EDGE
),
638 DECL(AL_DISTORTION_GAIN
),
639 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
640 DECL(AL_DISTORTION_EQCENTER
),
641 DECL(AL_DISTORTION_EQBANDWIDTH
),
644 DECL(AL_ECHO_LRDELAY
),
645 DECL(AL_ECHO_DAMPING
),
646 DECL(AL_ECHO_FEEDBACK
),
647 DECL(AL_ECHO_SPREAD
),
649 DECL(AL_FLANGER_WAVEFORM
),
650 DECL(AL_FLANGER_PHASE
),
651 DECL(AL_FLANGER_RATE
),
652 DECL(AL_FLANGER_DEPTH
),
653 DECL(AL_FLANGER_FEEDBACK
),
654 DECL(AL_FLANGER_DELAY
),
656 DECL(AL_RING_MODULATOR_FREQUENCY
),
657 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
658 DECL(AL_RING_MODULATOR_WAVEFORM
),
661 DECL(AL_AUTOWAH_ATTACK_TIME
),
662 DECL(AL_AUTOWAH_PEAK_GAIN
),
663 DECL(AL_AUTOWAH_RELEASE_TIME
),
664 DECL(AL_AUTOWAH_RESONANCE
),
667 DECL(AL_COMPRESSOR_ONOFF
),
669 DECL(AL_EQUALIZER_LOW_GAIN
),
670 DECL(AL_EQUALIZER_LOW_CUTOFF
),
671 DECL(AL_EQUALIZER_MID1_GAIN
),
672 DECL(AL_EQUALIZER_MID1_CENTER
),
673 DECL(AL_EQUALIZER_MID1_WIDTH
),
674 DECL(AL_EQUALIZER_MID2_GAIN
),
675 DECL(AL_EQUALIZER_MID2_CENTER
),
676 DECL(AL_EQUALIZER_MID2_WIDTH
),
677 DECL(AL_EQUALIZER_HIGH_GAIN
),
678 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
680 DECL(AL_DEDICATED_GAIN
),
686 static const ALCchar alcNoError
[] = "No Error";
687 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
688 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
689 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
690 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
691 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
694 /************************************************
696 ************************************************/
698 /* Enumerated device names */
699 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
701 static al_string alcAllDevicesList
;
702 static al_string alcCaptureDeviceList
;
704 /* Default is always the first in the list */
705 static ALCchar
*alcDefaultAllDevicesSpecifier
;
706 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
708 /* Default context extensions */
709 static const ALchar alExtList
[] =
710 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
711 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
712 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
713 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
714 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
715 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
716 "AL_SOFT_source_latency AL_SOFT_source_length";
718 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
720 /* Thread-local current context */
721 static altss_t LocalContext
;
722 /* Process-wide current context */
723 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
725 /* Mixing thread piority level */
730 enum LogLevel LogLevel
= LogWarning
;
732 enum LogLevel LogLevel
= LogError
;
735 /* Flag to trap ALC device errors */
736 static ALCboolean TrapALCError
= ALC_FALSE
;
738 /* One-time configuration init control */
739 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
741 /* Default effect that applies to sources that don't have an effect on send 0 */
742 static ALeffect DefaultEffect
;
744 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
747 static ALCboolean SuspendDefers
= ALC_TRUE
;
750 /************************************************
752 ************************************************/
753 static const ALCchar alcNoDeviceExtList
[] =
754 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
755 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
756 static const ALCchar alcExtensionList
[] =
757 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
758 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
759 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
760 "ALC_SOFT_loopback ALC_SOFT_pause_device";
761 static const ALCint alcMajorVersion
= 1;
762 static const ALCint alcMinorVersion
= 1;
764 static const ALCint alcEFXMajorVersion
= 1;
765 static const ALCint alcEFXMinorVersion
= 0;
768 /************************************************
770 ************************************************/
771 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
773 static almtx_t ListLock
;
774 static inline void LockLists(void)
776 int lockret
= almtx_lock(&ListLock
);
777 assert(lockret
== althrd_success
);
779 static inline void UnlockLists(void)
781 int unlockret
= almtx_unlock(&ListLock
);
782 assert(unlockret
== althrd_success
);
785 /************************************************
786 * Library initialization
787 ************************************************/
789 static void alc_init(void);
790 static void alc_deinit(void);
791 static void alc_deinit_safe(void);
793 #ifndef AL_LIBTYPE_STATIC
794 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
798 case DLL_PROCESS_ATTACH
:
799 /* Pin the DLL so we won't get unloaded until the process terminates */
800 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
801 (WCHAR
*)hModule
, &hModule
);
805 case DLL_THREAD_DETACH
:
808 case DLL_PROCESS_DETACH
:
817 #elif defined(_MSC_VER)
818 #pragma section(".CRT$XCU",read)
819 static void alc_constructor(void);
820 static void alc_destructor(void);
821 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
823 static void alc_constructor(void)
825 atexit(alc_destructor
);
829 static void alc_destructor(void)
833 #elif defined(HAVE_GCC_DESTRUCTOR)
834 static void alc_init(void) __attribute__((constructor
));
835 static void alc_deinit(void) __attribute__((destructor
));
837 #error "No static initialization available on this platform!"
840 #elif defined(HAVE_GCC_DESTRUCTOR)
842 static void alc_init(void) __attribute__((constructor
));
843 static void alc_deinit(void) __attribute__((destructor
));
846 #error "No global initialization available on this platform!"
849 static void ReleaseThreadCtx(void *ptr
);
850 static void alc_init(void)
857 AL_STRING_INIT(alcAllDevicesList
);
858 AL_STRING_INIT(alcCaptureDeviceList
);
860 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
861 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
864 str
= getenv("__ALSOFT_REVERSE_Z");
865 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
868 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
869 assert(ret
== althrd_success
);
871 ret
= almtx_init(&ListLock
, almtx_recursive
);
872 assert(ret
== althrd_success
);
877 static void alc_initconfig(void)
879 const char *devs
, *str
;
884 str
= getenv("ALSOFT_LOGLEVEL");
887 long lvl
= strtol(str
, NULL
, 0);
888 if(lvl
>= NoLog
&& lvl
<= LogRef
)
892 str
= getenv("ALSOFT_LOGFILE");
895 FILE *logfile
= al_fopen(str
, "wt");
896 if(logfile
) LogFile
= logfile
;
897 else ERR("Failed to open log file '%s'\n", str
);
902 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
903 for(i
= 1;BackendList
[i
].name
;i
++)
904 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
905 TRACE("Supported backends: %s\n", buf
);
909 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
912 if(strcasecmp(str
, "ignore") == 0)
914 SuspendDefers
= ALC_FALSE
;
915 TRACE("Selected context suspend behavior, \"ignore\"\n");
918 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
922 #if defined(HAVE_SSE4_1)
923 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
924 #elif defined(HAVE_SSE3)
925 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
926 #elif defined(HAVE_SSE2)
927 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
928 #elif defined(HAVE_SSE)
929 capfilter
|= CPU_CAP_SSE
;
932 capfilter
|= CPU_CAP_NEON
;
934 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
936 if(strcasecmp(str
, "all") == 0)
941 const char *next
= str
;
945 while(isspace(str
[0]))
947 next
= strchr(str
, ',');
949 if(!str
[0] || str
[0] == ',')
952 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
953 while(len
> 0 && isspace(str
[len
-1]))
955 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
956 capfilter
&= ~CPU_CAP_SSE
;
957 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
958 capfilter
&= ~CPU_CAP_SSE2
;
959 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
960 capfilter
&= ~CPU_CAP_SSE3
;
961 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
962 capfilter
&= ~CPU_CAP_SSE4_1
;
963 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
964 capfilter
&= ~CPU_CAP_NEON
;
966 WARN("Invalid CPU extension \"%s\"\n", str
);
970 FillCPUCaps(capfilter
);
977 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
981 str
= getenv("ALSOFT_TRAP_ERROR");
982 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
984 TrapALError
= AL_TRUE
;
985 TrapALCError
= AL_TRUE
;
989 str
= getenv("ALSOFT_TRAP_AL_ERROR");
990 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
991 TrapALError
= AL_TRUE
;
992 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
994 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
995 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
996 TrapALCError
= ALC_TRUE
;
997 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1000 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1001 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1003 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1005 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1006 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1010 const char *next
= devs
;
1011 int endlist
, delitem
;
1016 while(isspace(devs
[0]))
1018 next
= strchr(devs
, ',');
1020 delitem
= (devs
[0] == '-');
1021 if(devs
[0] == '-') devs
++;
1023 if(!devs
[0] || devs
[0] == ',')
1030 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1031 while(len
> 0 && isspace(devs
[len
-1]))
1033 for(n
= i
;BackendList
[n
].name
;n
++)
1035 if(len
== strlen(BackendList
[n
].name
) &&
1036 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1041 BackendList
[n
] = BackendList
[n
+1];
1043 } while(BackendList
[n
].name
);
1047 struct BackendInfo Bkp
= BackendList
[n
];
1050 BackendList
[n
] = BackendList
[n
-1];
1053 BackendList
[n
] = Bkp
;
1064 BackendList
[i
].name
= NULL
;
1065 BackendList
[i
].getFactory
= NULL
;
1066 BackendList
[i
].Init
= NULL
;
1067 BackendList
[i
].Deinit
= NULL
;
1068 BackendList
[i
].Probe
= NULL
;
1072 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1074 if(BackendList
[i
].getFactory
)
1076 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1077 if(!V0(factory
,init
)())
1079 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1083 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1084 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1086 PlaybackBackend
= BackendList
[i
];
1087 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1089 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1091 CaptureBackend
= BackendList
[i
];
1092 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1098 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1100 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1104 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1105 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1107 PlaybackBackend
= BackendList
[i
];
1108 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1110 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1112 CaptureBackend
= BackendList
[i
];
1113 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1117 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1121 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1124 const char *next
= str
;
1128 next
= strchr(str
, ',');
1130 if(!str
[0] || next
== str
)
1133 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1134 for(n
= 0;EffectList
[n
].name
;n
++)
1136 if(len
== strlen(EffectList
[n
].name
) &&
1137 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1138 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1143 InitEffectFactoryMap();
1145 InitEffect(&DefaultEffect
);
1146 str
= getenv("ALSOFT_DEFAULT_REVERB");
1147 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1148 LoadReverbPreset(str
, &DefaultEffect
);
1150 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1153 /************************************************
1154 * Library deinitialization
1155 ************************************************/
1156 static void alc_cleanup(void)
1160 AL_STRING_DEINIT(alcAllDevicesList
);
1161 AL_STRING_DEINIT(alcCaptureDeviceList
);
1163 free(alcDefaultAllDevicesSpecifier
);
1164 alcDefaultAllDevicesSpecifier
= NULL
;
1165 free(alcCaptureDefaultDeviceSpecifier
);
1166 alcCaptureDefaultDeviceSpecifier
= NULL
;
1168 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1173 } while((dev
=dev
->next
) != NULL
);
1174 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1177 DeinitEffectFactoryMap();
1180 static void alc_deinit_safe(void)
1188 almtx_destroy(&ListLock
);
1189 altss_delete(LocalContext
);
1191 if(LogFile
!= stderr
)
1196 static void alc_deinit(void)
1202 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1203 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1205 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1207 if(!BackendList
[i
].getFactory
)
1208 BackendList
[i
].Deinit();
1211 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1212 V0(factory
,deinit
)();
1216 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1217 V0(factory
,deinit
)();
1224 /************************************************
1225 * Device enumeration
1226 ************************************************/
1227 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1232 al_string_clear(list
);
1234 if(!backendinfo
->getFactory
)
1235 backendinfo
->Probe(type
);
1238 ALCbackendFactory
*factory
= backendinfo
->getFactory();
1239 V(factory
,probe
)(type
);
1244 static void ProbeAllDevicesList(void)
1245 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1246 static void ProbeCaptureDeviceList(void)
1247 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1249 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1251 size_t len
= strlen(name
);
1253 al_string_append_range(devnames
, name
, name
+len
+1);
1255 void AppendAllDevicesList(const ALCchar
*name
)
1256 { AppendDevice(name
, &alcAllDevicesList
); }
1257 void AppendCaptureDeviceList(const ALCchar
*name
)
1258 { AppendDevice(name
, &alcCaptureDeviceList
); }
1261 /************************************************
1262 * Device format information
1263 ************************************************/
1264 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1268 case DevFmtByte
: return "Signed Byte";
1269 case DevFmtUByte
: return "Unsigned Byte";
1270 case DevFmtShort
: return "Signed Short";
1271 case DevFmtUShort
: return "Unsigned Short";
1272 case DevFmtInt
: return "Signed Int";
1273 case DevFmtUInt
: return "Unsigned Int";
1274 case DevFmtFloat
: return "Float";
1276 return "(unknown type)";
1278 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1282 case DevFmtMono
: return "Mono";
1283 case DevFmtStereo
: return "Stereo";
1284 case DevFmtQuad
: return "Quadraphonic";
1285 case DevFmtX51
: return "5.1 Surround";
1286 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1287 case DevFmtX61
: return "6.1 Surround";
1288 case DevFmtX71
: return "7.1 Surround";
1289 case DevFmtBFormat3D
: return "B-Format 3D";
1291 return "(unknown channels)";
1294 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1295 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1299 case DevFmtByte
: return sizeof(ALbyte
);
1300 case DevFmtUByte
: return sizeof(ALubyte
);
1301 case DevFmtShort
: return sizeof(ALshort
);
1302 case DevFmtUShort
: return sizeof(ALushort
);
1303 case DevFmtInt
: return sizeof(ALint
);
1304 case DevFmtUInt
: return sizeof(ALuint
);
1305 case DevFmtFloat
: return sizeof(ALfloat
);
1309 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1313 case DevFmtMono
: return 1;
1314 case DevFmtStereo
: return 2;
1315 case DevFmtQuad
: return 4;
1316 case DevFmtX51
: return 6;
1317 case DevFmtX51Rear
: return 6;
1318 case DevFmtX61
: return 7;
1319 case DevFmtX71
: return 8;
1320 case DevFmtBFormat3D
: return 4;
1325 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1326 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1328 static const struct {
1330 enum DevFmtChannels channels
;
1331 enum DevFmtType type
;
1333 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1334 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1335 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1337 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1338 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1339 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1341 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1342 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1343 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1345 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1346 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1347 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1349 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1350 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1351 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1353 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1354 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1355 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1359 for(i
= 0;i
< COUNTOF(list
);i
++)
1361 if(list
[i
].format
== format
)
1363 *chans
= list
[i
].channels
;
1364 *type
= list
[i
].type
;
1372 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1377 case ALC_UNSIGNED_BYTE_SOFT
:
1378 case ALC_SHORT_SOFT
:
1379 case ALC_UNSIGNED_SHORT_SOFT
:
1381 case ALC_UNSIGNED_INT_SOFT
:
1382 case ALC_FLOAT_SOFT
:
1388 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1393 case ALC_STEREO_SOFT
:
1395 case ALC_5POINT1_SOFT
:
1396 case ALC_6POINT1_SOFT
:
1397 case ALC_7POINT1_SOFT
:
1404 /************************************************
1405 * Miscellaneous ALC helpers
1406 ************************************************/
1407 enum HrtfRequestMode
{
1413 extern inline void LockContext(ALCcontext
*context
);
1414 extern inline void UnlockContext(ALCcontext
*context
);
1416 void ALCdevice_Lock(ALCdevice
*device
)
1418 V0(device
->Backend
,lock
)();
1421 void ALCdevice_Unlock(ALCdevice
*device
)
1423 V0(device
->Backend
,unlock
)();
1427 /* SetDefaultWFXChannelOrder
1429 * Sets the default channel order used by WaveFormatEx.
1431 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1435 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1436 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1438 switch(device
->FmtChans
)
1441 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1444 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1445 device
->RealOut
.ChannelName
[1] = FrontRight
;
1448 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1449 device
->RealOut
.ChannelName
[1] = FrontRight
;
1450 device
->RealOut
.ChannelName
[2] = BackLeft
;
1451 device
->RealOut
.ChannelName
[3] = BackRight
;
1454 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1455 device
->RealOut
.ChannelName
[1] = FrontRight
;
1456 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1457 device
->RealOut
.ChannelName
[3] = LFE
;
1458 device
->RealOut
.ChannelName
[4] = SideLeft
;
1459 device
->RealOut
.ChannelName
[5] = SideRight
;
1462 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1463 device
->RealOut
.ChannelName
[1] = FrontRight
;
1464 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1465 device
->RealOut
.ChannelName
[3] = LFE
;
1466 device
->RealOut
.ChannelName
[4] = BackLeft
;
1467 device
->RealOut
.ChannelName
[5] = BackRight
;
1470 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1471 device
->RealOut
.ChannelName
[1] = FrontRight
;
1472 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1473 device
->RealOut
.ChannelName
[3] = LFE
;
1474 device
->RealOut
.ChannelName
[4] = BackCenter
;
1475 device
->RealOut
.ChannelName
[5] = SideLeft
;
1476 device
->RealOut
.ChannelName
[6] = SideRight
;
1479 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1480 device
->RealOut
.ChannelName
[1] = FrontRight
;
1481 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1482 device
->RealOut
.ChannelName
[3] = LFE
;
1483 device
->RealOut
.ChannelName
[4] = BackLeft
;
1484 device
->RealOut
.ChannelName
[5] = BackRight
;
1485 device
->RealOut
.ChannelName
[6] = SideLeft
;
1486 device
->RealOut
.ChannelName
[7] = SideRight
;
1488 case DevFmtBFormat3D
:
1489 device
->RealOut
.ChannelName
[0] = BFormatW
;
1490 device
->RealOut
.ChannelName
[1] = BFormatX
;
1491 device
->RealOut
.ChannelName
[2] = BFormatY
;
1492 device
->RealOut
.ChannelName
[3] = BFormatZ
;
1497 /* SetDefaultChannelOrder
1499 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1501 void SetDefaultChannelOrder(ALCdevice
*device
)
1505 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1506 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1508 switch(device
->FmtChans
)
1511 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1512 device
->RealOut
.ChannelName
[1] = FrontRight
;
1513 device
->RealOut
.ChannelName
[2] = BackLeft
;
1514 device
->RealOut
.ChannelName
[3] = BackRight
;
1515 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1516 device
->RealOut
.ChannelName
[5] = LFE
;
1519 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1520 device
->RealOut
.ChannelName
[1] = FrontRight
;
1521 device
->RealOut
.ChannelName
[2] = BackLeft
;
1522 device
->RealOut
.ChannelName
[3] = BackRight
;
1523 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1524 device
->RealOut
.ChannelName
[5] = LFE
;
1525 device
->RealOut
.ChannelName
[6] = SideLeft
;
1526 device
->RealOut
.ChannelName
[7] = SideRight
;
1529 /* Same as WFX order */
1535 case DevFmtBFormat3D
:
1536 SetDefaultWFXChannelOrder(device
);
1541 extern inline ALint
GetChannelIdxByName(const ALCdevice
*device
, enum Channel chan
);
1544 /* ALCcontext_DeferUpdates
1546 * Defers/suspends updates for the given context's listener and sources. This
1547 * does *NOT* stop mixing, but rather prevents certain property changes from
1550 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1552 ALCdevice
*device
= context
->Device
;
1555 SetMixerFPUMode(&oldMode
);
1557 V0(device
->Backend
,lock
)();
1558 if(!context
->DeferUpdates
)
1560 context
->DeferUpdates
= AL_TRUE
;
1562 /* Make sure all pending updates are performed */
1563 UpdateContextSources(context
);
1564 #define UPDATE_SLOT(iter) do { \
1565 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1566 V((*iter)->EffectState,update)(device, *iter); \
1568 VECTOR_FOR_EACH(ALeffectslot
*, context
->ActiveAuxSlots
, UPDATE_SLOT
);
1571 V0(device
->Backend
,unlock
)();
1573 RestoreFPUMode(&oldMode
);
1576 /* ALCcontext_ProcessUpdates
1578 * Resumes update processing after being deferred.
1580 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1582 ALCdevice
*device
= context
->Device
;
1584 V0(device
->Backend
,lock
)();
1585 if(context
->DeferUpdates
)
1589 context
->DeferUpdates
= AL_FALSE
;
1591 LockUIntMapRead(&context
->SourceMap
);
1592 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1594 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1597 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1598 Source
->Offset
>= 0.0)
1600 WriteLock(&Source
->queue_lock
);
1601 ApplyOffset(Source
);
1602 WriteUnlock(&Source
->queue_lock
);
1605 new_state
= Source
->new_state
;
1606 Source
->new_state
= AL_NONE
;
1608 SetSourceState(Source
, context
, new_state
);
1610 UnlockUIntMapRead(&context
->SourceMap
);
1612 V0(device
->Backend
,unlock
)();
1618 * Stores the latest ALC device error
1620 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1625 /* DebugBreak() will cause an exception if there is no debugger */
1626 if(IsDebuggerPresent())
1628 #elif defined(SIGTRAP)
1634 ATOMIC_STORE(&device
->LastError
, errorCode
);
1636 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1642 * Updates the device's base clock time with however many samples have been
1643 * done. This is used so frequency changes on the device don't cause the time
1644 * to jump forward or back.
1646 static inline void UpdateClockBase(ALCdevice
*device
)
1648 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1649 device
->SamplesDone
= 0;
1652 /* UpdateDeviceParams
1654 * Updates device parameters according to the attribute list (caller is
1655 * responsible for holding the list lock).
1657 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1659 ALCcontext
*context
;
1660 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1661 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1662 enum DevFmtChannels oldChans
;
1663 enum DevFmtType oldType
;
1666 ALCsizei hrtf_id
= -1;
1669 // Check for attributes
1670 if(device
->Type
== Loopback
)
1676 GotAll
= GotFreq
|GotChans
|GotType
1678 ALCuint freq
, numMono
, numStereo
, numSends
;
1679 enum DevFmtChannels schans
;
1680 enum DevFmtType stype
;
1681 ALCuint attrIdx
= 0;
1686 WARN("Missing attributes for loopback device\n");
1687 return ALC_INVALID_VALUE
;
1690 numMono
= device
->NumMonoSources
;
1691 numStereo
= device
->NumStereoSources
;
1692 numSends
= device
->NumAuxSends
;
1693 schans
= device
->FmtChans
;
1694 stype
= device
->FmtType
;
1695 freq
= device
->Frequency
;
1697 while(attrList
[attrIdx
])
1699 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1701 ALCint val
= attrList
[attrIdx
+ 1];
1702 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1703 return ALC_INVALID_VALUE
;
1708 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1710 ALCint val
= attrList
[attrIdx
+ 1];
1711 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1712 return ALC_INVALID_VALUE
;
1717 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1719 freq
= attrList
[attrIdx
+ 1];
1720 if(freq
< MIN_OUTPUT_RATE
)
1721 return ALC_INVALID_VALUE
;
1725 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1727 numStereo
= attrList
[attrIdx
+ 1];
1728 if(numStereo
> device
->MaxNoOfSources
)
1729 numStereo
= device
->MaxNoOfSources
;
1731 numMono
= device
->MaxNoOfSources
- numStereo
;
1734 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1735 numSends
= attrList
[attrIdx
+ 1];
1737 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1739 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1740 hrtf_appreq
= Hrtf_Disable
;
1741 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1742 hrtf_appreq
= Hrtf_Enable
;
1744 hrtf_appreq
= Hrtf_Default
;
1747 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1748 hrtf_id
= attrList
[attrIdx
+ 1];
1753 if(gotFmt
!= GotAll
)
1755 WARN("Missing format for loopback device\n");
1756 return ALC_INVALID_VALUE
;
1759 ConfigValueUInt(NULL
, NULL
, "sends", &numSends
);
1760 numSends
= minu(MAX_SENDS
, numSends
);
1762 if((device
->Flags
&DEVICE_RUNNING
))
1763 V0(device
->Backend
,stop
)();
1764 device
->Flags
&= ~DEVICE_RUNNING
;
1766 UpdateClockBase(device
);
1768 device
->Frequency
= freq
;
1769 device
->FmtChans
= schans
;
1770 device
->FmtType
= stype
;
1771 device
->NumMonoSources
= numMono
;
1772 device
->NumStereoSources
= numStereo
;
1773 device
->NumAuxSends
= numSends
;
1775 else if(attrList
&& attrList
[0])
1777 ALCuint freq
, numMono
, numStereo
, numSends
;
1778 ALCuint attrIdx
= 0;
1780 /* If a context is already running on the device, stop playback so the
1781 * device attributes can be updated. */
1782 if((device
->Flags
&DEVICE_RUNNING
))
1783 V0(device
->Backend
,stop
)();
1784 device
->Flags
&= ~DEVICE_RUNNING
;
1786 freq
= device
->Frequency
;
1787 numMono
= device
->NumMonoSources
;
1788 numStereo
= device
->NumStereoSources
;
1789 numSends
= device
->NumAuxSends
;
1791 while(attrList
[attrIdx
])
1793 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1795 freq
= attrList
[attrIdx
+ 1];
1796 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1799 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1801 numStereo
= attrList
[attrIdx
+ 1];
1802 if(numStereo
> device
->MaxNoOfSources
)
1803 numStereo
= device
->MaxNoOfSources
;
1805 numMono
= device
->MaxNoOfSources
- numStereo
;
1808 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1809 numSends
= attrList
[attrIdx
+ 1];
1811 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1813 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1814 hrtf_appreq
= Hrtf_Disable
;
1815 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1816 hrtf_appreq
= Hrtf_Enable
;
1818 hrtf_appreq
= Hrtf_Default
;
1821 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1822 hrtf_id
= attrList
[attrIdx
+ 1];
1827 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1828 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1830 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1831 numSends
= minu(MAX_SENDS
, numSends
);
1833 UpdateClockBase(device
);
1835 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1837 /* SSE and Neon do best with the update size being a multiple of 4 */
1838 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1839 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1841 device
->Frequency
= freq
;
1842 device
->NumMonoSources
= numMono
;
1843 device
->NumStereoSources
= numStereo
;
1844 device
->NumAuxSends
= numSends
;
1847 if((device
->Flags
&DEVICE_RUNNING
))
1848 return ALC_NO_ERROR
;
1850 al_free(device
->Uhj_Encoder
);
1851 device
->Uhj_Encoder
= NULL
;
1853 al_free(device
->Bs2b
);
1854 device
->Bs2b
= NULL
;
1856 al_free(device
->Dry
.Buffer
);
1857 device
->Dry
.Buffer
= NULL
;
1858 device
->Dry
.NumChannels
= 0;
1859 device
->VirtOut
.Buffer
= NULL
;
1860 device
->VirtOut
.NumChannels
= 0;
1861 device
->RealOut
.Buffer
= NULL
;
1862 device
->RealOut
.NumChannels
= 0;
1864 UpdateClockBase(device
);
1866 device
->Hrtf_Status
= ALC_HRTF_DISABLED_SOFT
;
1867 if(device
->Type
!= Loopback
)
1870 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
1872 if(strcasecmp(hrtf
, "true") == 0)
1873 hrtf_userreq
= Hrtf_Enable
;
1874 else if(strcasecmp(hrtf
, "false") == 0)
1875 hrtf_userreq
= Hrtf_Disable
;
1876 else if(strcasecmp(hrtf
, "auto") != 0)
1877 ERR("Unexpected hrtf value: %s\n", hrtf
);
1880 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
1882 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1884 VECTOR_DEINIT(device
->Hrtf_List
);
1885 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1887 if(VECTOR_SIZE(device
->Hrtf_List
) > 0)
1889 device
->FmtChans
= DevFmtStereo
;
1890 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
1891 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
).hrtf
);
1893 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, 0).hrtf
);
1894 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
1898 hrtf_userreq
= hrtf_appreq
= Hrtf_Default
;
1899 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1903 else if(hrtf_appreq
== Hrtf_Enable
)
1906 /* Loopback device. We don't need to match to a specific HRTF entry
1907 * here. If the requested ID matches, we'll pick that later, if not,
1908 * we'll try to auto-select one anyway. */
1909 if(device
->FmtChans
!= DevFmtStereo
)
1910 i
= VECTOR_SIZE(device
->Hrtf_List
);
1913 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1915 VECTOR_DEINIT(device
->Hrtf_List
);
1916 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1918 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
1920 const struct Hrtf
*hrtf
= VECTOR_ELEM(device
->Hrtf_List
, i
).hrtf
;
1921 if(GetHrtfSampleRate(hrtf
) == device
->Frequency
)
1925 if(i
== VECTOR_SIZE(device
->Hrtf_List
))
1927 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1928 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1929 hrtf_appreq
= Hrtf_Default
;
1930 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1934 oldFreq
= device
->Frequency
;
1935 oldChans
= device
->FmtChans
;
1936 oldType
= device
->FmtType
;
1938 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1939 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1940 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1941 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1942 device
->UpdateSize
, device
->NumUpdates
1945 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1946 return ALC_INVALID_DEVICE
;
1948 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1950 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1951 DevFmtChannelsString(device
->FmtChans
));
1952 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1954 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1956 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1957 DevFmtTypeString(device
->FmtType
));
1958 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1960 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1962 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1963 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1966 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1967 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1968 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1971 if((device
->UpdateSize
&3) != 0)
1973 if((CPUCapFlags
&CPU_CAP_SSE
))
1974 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1975 if((CPUCapFlags
&CPU_CAP_NEON
))
1976 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1979 device
->Hrtf
= NULL
;
1980 al_string_clear(&device
->Hrtf_Name
);
1981 device
->Render_Mode
= NormalRender
;
1982 if(device
->FmtChans
!= DevFmtStereo
)
1984 if(hrtf_appreq
== Hrtf_Enable
)
1985 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1989 bool headphones
= device
->IsHeadphones
;
1990 enum RenderMode render_mode
= HrtfRender
;
1991 ALCenum hrtf_status
= device
->Hrtf_Status
;
1996 if(device
->Type
!= Loopback
)
1998 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "stereo-mode", &mode
))
2000 if(strcasecmp(mode
, "headphones") == 0)
2002 else if(strcasecmp(mode
, "speakers") == 0)
2004 else if(strcasecmp(mode
, "auto") != 0)
2005 ERR("Unexpected stereo-mode: %s\n", mode
);
2008 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf-mode", &mode
))
2010 if(strcasecmp(mode
, "full") == 0)
2011 render_mode
= HrtfRender
;
2012 else if(strcasecmp(mode
, "basic") == 0)
2013 render_mode
= NormalRender
;
2015 ERR("Unexpected hrtf-mode: %s\n", mode
);
2020 if(hrtf_userreq
== Hrtf_Default
)
2022 usehrtf
= (headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2023 (hrtf_appreq
== Hrtf_Enable
);
2024 if(headphones
&& hrtf_appreq
!= Hrtf_Disable
)
2025 hrtf_status
= ALC_HRTF_HEADPHONES_DETECTED_SOFT
;
2027 hrtf_status
= ALC_HRTF_ENABLED_SOFT
;
2031 usehrtf
= (hrtf_userreq
== Hrtf_Enable
);
2033 hrtf_status
= ALC_HRTF_DENIED_SOFT
;
2035 hrtf_status
= ALC_HRTF_REQUIRED_SOFT
;
2039 device
->Hrtf_Status
= hrtf_status
;
2044 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2045 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
2047 VECTOR_DEINIT(device
->Hrtf_List
);
2048 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2051 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
2053 const HrtfEntry
*entry
= &VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
);
2054 if(GetHrtfSampleRate(entry
->hrtf
) == device
->Frequency
)
2056 device
->Hrtf
= entry
->hrtf
;
2057 al_string_copy(&device
->Hrtf_Name
, entry
->name
);
2062 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
2064 const HrtfEntry
*entry
= &VECTOR_ELEM(device
->Hrtf_List
, i
);
2065 if(GetHrtfSampleRate(entry
->hrtf
) == device
->Frequency
)
2067 device
->Hrtf
= entry
->hrtf
;
2068 al_string_copy(&device
->Hrtf_Name
, entry
->name
);
2076 device
->Hrtf_Status
= hrtf_status
;
2077 device
->Render_Mode
= render_mode
;
2078 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device
->Hrtf_Name
));
2082 TRACE("HRTF disabled\n");
2084 bs2blevel
= ((headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2085 (hrtf_appreq
== Hrtf_Enable
)) ? 5 : 0;
2086 if(device
->Type
!= Loopback
)
2087 ConfigValueInt(al_string_get_cstr(device
->DeviceName
), NULL
, "cf_level", &bs2blevel
);
2088 if(bs2blevel
> 0 && bs2blevel
<= 6)
2090 device
->Bs2b
= al_calloc(16, sizeof(*device
->Bs2b
));
2091 bs2b_set_params(device
->Bs2b
, bs2blevel
, device
->Frequency
);
2092 device
->Render_Mode
= StereoPair
;
2093 TRACE("BS2B enabled\n");
2097 TRACE("BS2B disabled\n");
2099 render_mode
= NormalRender
;
2100 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "stereo-panning", &mode
))
2102 if(strcasecmp(mode
, "paired") == 0)
2103 render_mode
= StereoPair
;
2104 else if(strcasecmp(mode
, "uhj") != 0)
2105 ERR("Unexpected stereo-panning: %s\n", mode
);
2107 device
->Render_Mode
= render_mode
;
2108 if(render_mode
== NormalRender
)
2110 device
->Uhj_Encoder
= al_calloc(16, sizeof(Uhj2Encoder
));
2111 TRACE("UHJ enabled\n");
2114 TRACE("UHJ disabled\n");
2119 aluInitPanning(device
);
2121 /* With HRTF, allocate two extra channels for the post-filter output. */
2122 size
= device
->Dry
.NumChannels
* sizeof(device
->Dry
.Buffer
[0]);
2123 if(device
->Hrtf
|| device
->Uhj_Encoder
)
2124 size
+= 2 * sizeof(device
->Dry
.Buffer
[0]);
2125 device
->Dry
.Buffer
= al_calloc(16, size
);
2126 if(!device
->Dry
.Buffer
)
2128 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2129 return ALC_INVALID_DEVICE
;
2132 if(device
->Hrtf
|| device
->Uhj_Encoder
)
2134 device
->VirtOut
.Buffer
= device
->Dry
.Buffer
;
2135 device
->VirtOut
.NumChannels
= device
->Dry
.NumChannels
;
2136 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2137 device
->RealOut
.NumChannels
= 2;
2141 device
->VirtOut
.Buffer
= NULL
;
2142 device
->VirtOut
.NumChannels
= 0;
2143 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2144 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2147 SetMixerFPUMode(&oldMode
);
2148 V0(device
->Backend
,lock
)();
2149 context
= ATOMIC_LOAD(&device
->ContextList
);
2154 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2155 LockUIntMapRead(&context
->EffectSlotMap
);
2156 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2158 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2160 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2162 UnlockUIntMapRead(&context
->EffectSlotMap
);
2163 V0(device
->Backend
,unlock
)();
2164 RestoreFPUMode(&oldMode
);
2165 return ALC_INVALID_DEVICE
;
2167 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2168 V(slot
->EffectState
,update
)(device
, slot
);
2170 UnlockUIntMapRead(&context
->EffectSlotMap
);
2172 LockUIntMapRead(&context
->SourceMap
);
2173 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2175 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2176 ALuint s
= device
->NumAuxSends
;
2177 while(s
< MAX_SENDS
)
2179 if(source
->Send
[s
].Slot
)
2180 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2181 source
->Send
[s
].Slot
= NULL
;
2182 source
->Send
[s
].Gain
= 1.0f
;
2183 source
->Send
[s
].GainHF
= 1.0f
;
2186 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2188 UnlockUIntMapRead(&context
->SourceMap
);
2190 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2192 ALvoice
*voice
= &context
->Voices
[pos
];
2193 ALsource
*source
= voice
->Source
;
2197 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2198 voice
->Update(voice
, source
, context
);
2202 context
= context
->next
;
2204 if(device
->DefaultSlot
)
2206 ALeffectslot
*slot
= device
->DefaultSlot
;
2208 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2210 V0(device
->Backend
,unlock
)();
2211 RestoreFPUMode(&oldMode
);
2212 return ALC_INVALID_DEVICE
;
2214 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2215 V(slot
->EffectState
,update
)(device
, slot
);
2217 V0(device
->Backend
,unlock
)();
2218 RestoreFPUMode(&oldMode
);
2220 if(!(device
->Flags
&DEVICE_PAUSED
))
2222 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2223 return ALC_INVALID_DEVICE
;
2224 device
->Flags
|= DEVICE_RUNNING
;
2227 return ALC_NO_ERROR
;
2232 * Frees the device structure, and destroys any objects the app failed to
2233 * delete. Called once there's no more references on the device.
2235 static ALCvoid
FreeDevice(ALCdevice
*device
)
2237 TRACE("%p\n", device
);
2239 V0(device
->Backend
,close
)();
2240 DELETE_OBJ(device
->Backend
);
2241 device
->Backend
= NULL
;
2243 if(device
->DefaultSlot
)
2245 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2246 device
->DefaultSlot
= NULL
;
2250 if(device
->BufferMap
.size
> 0)
2252 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2253 ReleaseALBuffers(device
);
2255 ResetUIntMap(&device
->BufferMap
);
2257 if(device
->EffectMap
.size
> 0)
2259 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2260 ReleaseALEffects(device
);
2262 ResetUIntMap(&device
->EffectMap
);
2264 if(device
->FilterMap
.size
> 0)
2266 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2267 ReleaseALFilters(device
);
2269 ResetUIntMap(&device
->FilterMap
);
2271 AL_STRING_DEINIT(device
->Hrtf_Name
);
2272 FreeHrtfList(&device
->Hrtf_List
);
2274 al_free(device
->Bs2b
);
2275 device
->Bs2b
= NULL
;
2277 al_free(device
->Uhj_Encoder
);
2278 device
->Uhj_Encoder
= NULL
;
2280 AL_STRING_DEINIT(device
->DeviceName
);
2282 al_free(device
->Dry
.Buffer
);
2283 device
->Dry
.Buffer
= NULL
;
2284 device
->Dry
.NumChannels
= 0;
2285 device
->VirtOut
.Buffer
= NULL
;
2286 device
->VirtOut
.NumChannels
= 0;
2287 device
->RealOut
.Buffer
= NULL
;
2288 device
->RealOut
.NumChannels
= 0;
2294 void ALCdevice_IncRef(ALCdevice
*device
)
2297 ref
= IncrementRef(&device
->ref
);
2298 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2301 void ALCdevice_DecRef(ALCdevice
*device
)
2304 ref
= DecrementRef(&device
->ref
);
2305 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2306 if(ref
== 0) FreeDevice(device
);
2311 * Checks if the device handle is valid, and increments its ref count if so.
2313 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2315 ALCdevice
*tmpDevice
;
2318 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2321 if(tmpDevice
== *device
)
2323 ALCdevice_IncRef(tmpDevice
);
2327 tmpDevice
= tmpDevice
->next
;
2338 * Initializes context fields
2340 static ALvoid
InitContext(ALCcontext
*Context
)
2342 ALlistener
*listener
= Context
->Listener
;
2343 //Initialise listener
2344 listener
->Gain
= 1.0f
;
2345 listener
->MetersPerUnit
= 1.0f
;
2346 aluVectorSet(&listener
->Position
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
2347 aluVectorSet(&listener
->Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2348 listener
->Forward
[0] = 0.0f
;
2349 listener
->Forward
[1] = 0.0f
;
2350 listener
->Forward
[2] = -1.0f
;
2351 listener
->Up
[0] = 0.0f
;
2352 listener
->Up
[1] = 1.0f
;
2353 listener
->Up
[2] = 0.0f
;
2354 aluMatrixdSet(&listener
->Params
.Matrix
,
2360 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2363 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2364 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2365 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2366 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2369 Context
->DistanceModel
= DefaultDistanceModel
;
2370 Context
->SourceDistanceModel
= AL_FALSE
;
2371 Context
->DopplerFactor
= 1.0f
;
2372 Context
->DopplerVelocity
= 1.0f
;
2373 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2374 Context
->DeferUpdates
= AL_FALSE
;
2376 Context
->ExtensionList
= alExtList
;
2382 * Cleans up the context, and destroys any remaining objects the app failed to
2383 * delete. Called once there's no more references on the context.
2385 static void FreeContext(ALCcontext
*context
)
2387 TRACE("%p\n", context
);
2389 if(context
->SourceMap
.size
> 0)
2391 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2392 ReleaseALSources(context
);
2394 ResetUIntMap(&context
->SourceMap
);
2396 if(context
->EffectSlotMap
.size
> 0)
2398 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2399 ReleaseALAuxiliaryEffectSlots(context
);
2401 ResetUIntMap(&context
->EffectSlotMap
);
2403 al_free(context
->Voices
);
2404 context
->Voices
= NULL
;
2405 context
->VoiceCount
= 0;
2406 context
->MaxVoices
= 0;
2408 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2410 ALCdevice_DecRef(context
->Device
);
2411 context
->Device
= NULL
;
2413 //Invalidate context
2414 memset(context
, 0, sizeof(ALCcontext
));
2420 * Removes the context reference from the given device and removes it from
2421 * being current on the running thread or globally.
2423 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2425 ALCcontext
*nextctx
;
2426 ALCcontext
*origctx
;
2428 if(altss_get(LocalContext
) == context
)
2430 WARN("%p released while current on thread\n", context
);
2431 altss_set(LocalContext
, NULL
);
2432 ALCcontext_DecRef(context
);
2436 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2437 ALCcontext_DecRef(context
);
2439 ALCdevice_Lock(device
);
2441 nextctx
= context
->next
;
2442 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2448 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2450 ALCdevice_Unlock(device
);
2452 ALCcontext_DecRef(context
);
2455 void ALCcontext_IncRef(ALCcontext
*context
)
2458 ref
= IncrementRef(&context
->ref
);
2459 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2462 void ALCcontext_DecRef(ALCcontext
*context
)
2465 ref
= DecrementRef(&context
->ref
);
2466 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2467 if(ref
== 0) FreeContext(context
);
2470 static void ReleaseThreadCtx(void *ptr
)
2472 WARN("%p current for thread being destroyed\n", ptr
);
2473 ALCcontext_DecRef(ptr
);
2478 * Checks that the given context is valid, and increments its reference count.
2480 static ALCboolean
VerifyContext(ALCcontext
**context
)
2485 dev
= ATOMIC_LOAD(&DeviceList
);
2488 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2493 ALCcontext_IncRef(ctx
);
2510 * Returns the currently active context for this thread, and adds a reference
2511 * without locking it.
2513 ALCcontext
*GetContextRef(void)
2515 ALCcontext
*context
;
2517 context
= altss_get(LocalContext
);
2519 ALCcontext_IncRef(context
);
2523 context
= ATOMIC_LOAD(&GlobalContext
);
2525 ALCcontext_IncRef(context
);
2533 /************************************************
2534 * Standard ALC functions
2535 ************************************************/
2539 * Return last ALC generated error code for the given device
2541 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2545 if(VerifyDevice(&device
))
2547 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2548 ALCdevice_DecRef(device
);
2551 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2557 /* alcSuspendContext
2559 * Suspends updates for the given context
2561 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2566 if(!VerifyContext(&context
))
2567 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2570 ALCcontext_DeferUpdates(context
);
2571 ALCcontext_DecRef(context
);
2575 /* alcProcessContext
2577 * Resumes processing updates for the given context
2579 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2584 if(!VerifyContext(&context
))
2585 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2588 ALCcontext_ProcessUpdates(context
);
2589 ALCcontext_DecRef(context
);
2596 * Returns information about the device, and error strings
2598 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2600 const ALCchar
*value
= NULL
;
2608 case ALC_INVALID_ENUM
:
2609 value
= alcErrInvalidEnum
;
2612 case ALC_INVALID_VALUE
:
2613 value
= alcErrInvalidValue
;
2616 case ALC_INVALID_DEVICE
:
2617 value
= alcErrInvalidDevice
;
2620 case ALC_INVALID_CONTEXT
:
2621 value
= alcErrInvalidContext
;
2624 case ALC_OUT_OF_MEMORY
:
2625 value
= alcErrOutOfMemory
;
2628 case ALC_DEVICE_SPECIFIER
:
2629 value
= alcDefaultName
;
2632 case ALC_ALL_DEVICES_SPECIFIER
:
2633 if(VerifyDevice(&Device
))
2635 value
= al_string_get_cstr(Device
->DeviceName
);
2636 ALCdevice_DecRef(Device
);
2640 ProbeAllDevicesList();
2641 value
= al_string_get_cstr(alcAllDevicesList
);
2645 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2646 if(VerifyDevice(&Device
))
2648 value
= al_string_get_cstr(Device
->DeviceName
);
2649 ALCdevice_DecRef(Device
);
2653 ProbeCaptureDeviceList();
2654 value
= al_string_get_cstr(alcCaptureDeviceList
);
2658 /* Default devices are always first in the list */
2659 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2660 value
= alcDefaultName
;
2663 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2664 if(al_string_empty(alcAllDevicesList
))
2665 ProbeAllDevicesList();
2667 VerifyDevice(&Device
);
2669 free(alcDefaultAllDevicesSpecifier
);
2670 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2671 if(!alcDefaultAllDevicesSpecifier
)
2672 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2674 value
= alcDefaultAllDevicesSpecifier
;
2675 if(Device
) ALCdevice_DecRef(Device
);
2678 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2679 if(al_string_empty(alcCaptureDeviceList
))
2680 ProbeCaptureDeviceList();
2682 VerifyDevice(&Device
);
2684 free(alcCaptureDefaultDeviceSpecifier
);
2685 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2686 if(!alcCaptureDefaultDeviceSpecifier
)
2687 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2689 value
= alcCaptureDefaultDeviceSpecifier
;
2690 if(Device
) ALCdevice_DecRef(Device
);
2693 case ALC_EXTENSIONS
:
2694 if(!VerifyDevice(&Device
))
2695 value
= alcNoDeviceExtList
;
2698 value
= alcExtensionList
;
2699 ALCdevice_DecRef(Device
);
2703 case ALC_HRTF_SPECIFIER_SOFT
:
2704 if(!VerifyDevice(&Device
))
2705 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2709 value
= (Device
->Hrtf
? al_string_get_cstr(Device
->Hrtf_Name
) : "");
2711 ALCdevice_DecRef(Device
);
2716 VerifyDevice(&Device
);
2717 alcSetError(Device
, ALC_INVALID_ENUM
);
2718 if(Device
) ALCdevice_DecRef(Device
);
2726 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2730 if(size
<= 0 || values
== NULL
)
2732 alcSetError(device
, ALC_INVALID_VALUE
);
2740 case ALC_MAJOR_VERSION
:
2741 values
[0] = alcMajorVersion
;
2743 case ALC_MINOR_VERSION
:
2744 values
[0] = alcMinorVersion
;
2747 case ALC_ATTRIBUTES_SIZE
:
2748 case ALC_ALL_ATTRIBUTES
:
2752 case ALC_MONO_SOURCES
:
2753 case ALC_STEREO_SOURCES
:
2754 case ALC_CAPTURE_SAMPLES
:
2755 case ALC_FORMAT_CHANNELS_SOFT
:
2756 case ALC_FORMAT_TYPE_SOFT
:
2757 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2761 alcSetError(NULL
, ALC_INVALID_ENUM
);
2767 if(device
->Type
== Capture
)
2771 case ALC_CAPTURE_SAMPLES
:
2772 V0(device
->Backend
,lock
)();
2773 values
[0] = V0(device
->Backend
,availableSamples
)();
2774 V0(device
->Backend
,unlock
)();
2778 values
[0] = device
->Connected
;
2782 alcSetError(device
, ALC_INVALID_ENUM
);
2791 case ALC_MAJOR_VERSION
:
2792 values
[0] = alcMajorVersion
;
2795 case ALC_MINOR_VERSION
:
2796 values
[0] = alcMinorVersion
;
2799 case ALC_EFX_MAJOR_VERSION
:
2800 values
[0] = alcEFXMajorVersion
;
2803 case ALC_EFX_MINOR_VERSION
:
2804 values
[0] = alcEFXMinorVersion
;
2807 case ALC_ATTRIBUTES_SIZE
:
2811 case ALC_ALL_ATTRIBUTES
:
2814 alcSetError(device
, ALC_INVALID_VALUE
);
2819 values
[i
++] = ALC_FREQUENCY
;
2820 values
[i
++] = device
->Frequency
;
2822 if(device
->Type
!= Loopback
)
2824 values
[i
++] = ALC_REFRESH
;
2825 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2827 values
[i
++] = ALC_SYNC
;
2828 values
[i
++] = ALC_FALSE
;
2832 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2833 values
[i
++] = device
->FmtChans
;
2835 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2836 values
[i
++] = device
->FmtType
;
2839 values
[i
++] = ALC_MONO_SOURCES
;
2840 values
[i
++] = device
->NumMonoSources
;
2842 values
[i
++] = ALC_STEREO_SOURCES
;
2843 values
[i
++] = device
->NumStereoSources
;
2845 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2846 values
[i
++] = device
->NumAuxSends
;
2848 values
[i
++] = ALC_HRTF_SOFT
;
2849 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2851 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2852 values
[i
++] = device
->Hrtf_Status
;
2858 values
[0] = device
->Frequency
;
2862 if(device
->Type
== Loopback
)
2864 alcSetError(device
, ALC_INVALID_DEVICE
);
2867 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2871 if(device
->Type
== Loopback
)
2873 alcSetError(device
, ALC_INVALID_DEVICE
);
2876 values
[0] = ALC_FALSE
;
2879 case ALC_FORMAT_CHANNELS_SOFT
:
2880 if(device
->Type
!= Loopback
)
2882 alcSetError(device
, ALC_INVALID_DEVICE
);
2885 values
[0] = device
->FmtChans
;
2888 case ALC_FORMAT_TYPE_SOFT
:
2889 if(device
->Type
!= Loopback
)
2891 alcSetError(device
, ALC_INVALID_DEVICE
);
2894 values
[0] = device
->FmtType
;
2897 case ALC_MONO_SOURCES
:
2898 values
[0] = device
->NumMonoSources
;
2901 case ALC_STEREO_SOURCES
:
2902 values
[0] = device
->NumStereoSources
;
2905 case ALC_MAX_AUXILIARY_SENDS
:
2906 values
[0] = device
->NumAuxSends
;
2910 values
[0] = device
->Connected
;
2914 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2917 case ALC_HRTF_STATUS_SOFT
:
2918 values
[0] = device
->Hrtf_Status
;
2921 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
2922 FreeHrtfList(&device
->Hrtf_List
);
2923 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2924 values
[0] = (ALCint
)VECTOR_SIZE(device
->Hrtf_List
);
2928 alcSetError(device
, ALC_INVALID_ENUM
);
2936 * Returns information about the device and the version of OpenAL
2938 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2940 VerifyDevice(&device
);
2941 if(size
<= 0 || values
== NULL
)
2942 alcSetError(device
, ALC_INVALID_VALUE
);
2944 GetIntegerv(device
, param
, size
, values
);
2945 if(device
) ALCdevice_DecRef(device
);
2948 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2953 VerifyDevice(&device
);
2954 if(size
<= 0 || values
== NULL
)
2955 alcSetError(device
, ALC_INVALID_VALUE
);
2956 else if(!device
|| device
->Type
== Capture
)
2958 ivals
= malloc(size
* sizeof(ALCint
));
2959 size
= GetIntegerv(device
, pname
, size
, ivals
);
2960 for(i
= 0;i
< size
;i
++)
2961 values
[i
] = ivals
[i
];
2964 else /* render device */
2968 case ALC_ATTRIBUTES_SIZE
:
2972 case ALC_ALL_ATTRIBUTES
:
2974 alcSetError(device
, ALC_INVALID_VALUE
);
2979 V0(device
->Backend
,lock
)();
2980 values
[i
++] = ALC_FREQUENCY
;
2981 values
[i
++] = device
->Frequency
;
2983 if(device
->Type
!= Loopback
)
2985 values
[i
++] = ALC_REFRESH
;
2986 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2988 values
[i
++] = ALC_SYNC
;
2989 values
[i
++] = ALC_FALSE
;
2993 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2994 values
[i
++] = device
->FmtChans
;
2996 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2997 values
[i
++] = device
->FmtType
;
3000 values
[i
++] = ALC_MONO_SOURCES
;
3001 values
[i
++] = device
->NumMonoSources
;
3003 values
[i
++] = ALC_STEREO_SOURCES
;
3004 values
[i
++] = device
->NumStereoSources
;
3006 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3007 values
[i
++] = device
->NumAuxSends
;
3009 values
[i
++] = ALC_HRTF_SOFT
;
3010 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
3012 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3013 values
[i
++] = device
->Hrtf_Status
;
3015 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3016 values
[i
++] = device
->ClockBase
+
3017 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
3020 V0(device
->Backend
,unlock
)();
3024 case ALC_DEVICE_CLOCK_SOFT
:
3025 V0(device
->Backend
,lock
)();
3026 *values
= device
->ClockBase
+
3027 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
3028 V0(device
->Backend
,unlock
)();
3032 ivals
= malloc(size
* sizeof(ALCint
));
3033 size
= GetIntegerv(device
, pname
, size
, ivals
);
3034 for(i
= 0;i
< size
;i
++)
3035 values
[i
] = ivals
[i
];
3041 ALCdevice_DecRef(device
);
3045 /* alcIsExtensionPresent
3047 * Determines if there is support for a particular extension
3049 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3051 ALCboolean bResult
= ALC_FALSE
;
3053 VerifyDevice(&device
);
3056 alcSetError(device
, ALC_INVALID_VALUE
);
3059 size_t len
= strlen(extName
);
3060 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3063 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3064 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3069 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3073 } while(isspace(*ptr
));
3078 ALCdevice_DecRef(device
);
3083 /* alcGetProcAddress
3085 * Retrieves the function address for a particular extension function
3087 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3089 ALCvoid
*ptr
= NULL
;
3093 VerifyDevice(&device
);
3094 alcSetError(device
, ALC_INVALID_VALUE
);
3095 if(device
) ALCdevice_DecRef(device
);
3100 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3102 ptr
= alcFunctions
[i
].address
;
3111 * Get the value for a particular ALC enumeration name
3113 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3119 VerifyDevice(&device
);
3120 alcSetError(device
, ALC_INVALID_VALUE
);
3121 if(device
) ALCdevice_DecRef(device
);
3126 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3128 val
= enumeration
[i
].value
;
3137 * Create and attach a context to the given device.
3139 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3141 ALCcontext
*ALContext
;
3145 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3148 alcSetError(device
, ALC_INVALID_DEVICE
);
3149 if(device
) ALCdevice_DecRef(device
);
3153 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3155 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3158 alcSetError(device
, err
);
3159 if(err
== ALC_INVALID_DEVICE
)
3161 V0(device
->Backend
,lock
)();
3162 aluHandleDisconnect(device
);
3163 V0(device
->Backend
,unlock
)();
3165 ALCdevice_DecRef(device
);
3169 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3172 InitRef(&ALContext
->ref
, 1);
3173 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3175 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3177 ALContext
->VoiceCount
= 0;
3178 ALContext
->MaxVoices
= 256;
3179 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3181 if(!ALContext
|| !ALContext
->Voices
)
3183 if(!ATOMIC_LOAD(&device
->ContextList
))
3185 V0(device
->Backend
,stop
)();
3186 device
->Flags
&= ~DEVICE_RUNNING
;
3192 al_free(ALContext
->Voices
);
3193 ALContext
->Voices
= NULL
;
3195 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3201 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3202 ALCdevice_DecRef(device
);
3206 ALContext
->Device
= device
;
3207 ALCdevice_IncRef(device
);
3208 InitContext(ALContext
);
3211 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3213 ALContext
->next
= head
;
3214 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3218 ALCdevice_DecRef(device
);
3220 TRACE("Created context %p\n", ALContext
);
3224 /* alcDestroyContext
3226 * Remove a context from its device
3228 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3233 /* alcGetContextsDevice sets an error for invalid contexts */
3234 Device
= alcGetContextsDevice(context
);
3237 ReleaseContext(context
, Device
);
3238 if(!ATOMIC_LOAD(&Device
->ContextList
))
3240 V0(Device
->Backend
,stop
)();
3241 Device
->Flags
&= ~DEVICE_RUNNING
;
3248 /* alcGetCurrentContext
3250 * Returns the currently active context on the calling thread
3252 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3254 ALCcontext
*Context
= altss_get(LocalContext
);
3255 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3259 /* alcGetThreadContext
3261 * Returns the currently active thread-local context
3263 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3265 return altss_get(LocalContext
);
3269 /* alcMakeContextCurrent
3271 * Makes the given context the active process-wide context, and removes the
3272 * thread-local context for the calling thread.
3274 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3276 /* context must be valid or NULL */
3277 if(context
&& !VerifyContext(&context
))
3279 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3282 /* context's reference count is already incremented */
3283 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3284 if(context
) ALCcontext_DecRef(context
);
3286 if((context
=altss_get(LocalContext
)) != NULL
)
3288 altss_set(LocalContext
, NULL
);
3289 ALCcontext_DecRef(context
);
3295 /* alcSetThreadContext
3297 * Makes the given context the active context for the current thread
3299 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3303 /* context must be valid or NULL */
3304 if(context
&& !VerifyContext(&context
))
3306 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3309 /* context's reference count is already incremented */
3310 old
= altss_get(LocalContext
);
3311 altss_set(LocalContext
, context
);
3312 if(old
) ALCcontext_DecRef(old
);
3318 /* alcGetContextsDevice
3320 * Returns the device that a particular context is attached to
3322 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3326 if(!VerifyContext(&Context
))
3328 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3331 Device
= Context
->Device
;
3332 ALCcontext_DecRef(Context
);
3340 * Opens the named device.
3342 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3350 if(!PlaybackBackend
.name
)
3352 alcSetError(NULL
, ALC_INVALID_VALUE
);
3356 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3358 /* Some old Windows apps hardcode these expecting OpenAL to use a
3359 * specific audio API, even when they're not enumerated. Creative's
3360 * router effectively ignores them too.
3362 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3363 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3368 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3371 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3376 InitRef(&device
->ref
, 1);
3377 device
->Connected
= ALC_TRUE
;
3378 device
->Type
= Playback
;
3379 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3382 device
->Bs2b
= NULL
;
3383 device
->Uhj_Encoder
= NULL
;
3384 VECTOR_INIT(device
->Hrtf_List
);
3385 AL_STRING_INIT(device
->Hrtf_Name
);
3386 device
->Render_Mode
= NormalRender
;
3387 AL_STRING_INIT(device
->DeviceName
);
3388 device
->Dry
.Buffer
= NULL
;
3389 device
->Dry
.NumChannels
= 0;
3390 device
->VirtOut
.Buffer
= NULL
;
3391 device
->VirtOut
.NumChannels
= 0;
3392 device
->RealOut
.Buffer
= NULL
;
3393 device
->RealOut
.NumChannels
= 0;
3395 ATOMIC_INIT(&device
->ContextList
, NULL
);
3397 device
->ClockBase
= 0;
3398 device
->SamplesDone
= 0;
3400 device
->MaxNoOfSources
= 256;
3401 device
->AuxiliaryEffectSlotMax
= 4;
3402 device
->NumAuxSends
= MAX_SENDS
;
3404 InitUIntMap(&device
->BufferMap
, ~0);
3405 InitUIntMap(&device
->EffectMap
, ~0);
3406 InitUIntMap(&device
->FilterMap
, ~0);
3409 device
->FmtChans
= DevFmtChannelsDefault
;
3410 device
->FmtType
= DevFmtTypeDefault
;
3411 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3412 device
->IsHeadphones
= AL_FALSE
;
3413 device
->NumUpdates
= 4;
3414 device
->UpdateSize
= 1024;
3416 if(!PlaybackBackend
.getFactory
)
3417 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3418 ALCbackend_Playback
);
3421 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3422 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3424 if(!device
->Backend
)
3427 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3432 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3434 static const struct {
3435 const char name
[16];
3436 enum DevFmtChannels chans
;
3438 { "mono", DevFmtMono
},
3439 { "stereo", DevFmtStereo
},
3440 { "quad", DevFmtQuad
},
3441 { "surround51", DevFmtX51
},
3442 { "surround61", DevFmtX61
},
3443 { "surround71", DevFmtX71
},
3444 { "surround51rear", DevFmtX51Rear
},
3448 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3450 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3452 device
->FmtChans
= chanlist
[i
].chans
;
3453 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3457 if(i
== COUNTOF(chanlist
))
3458 ERR("Unsupported channels: %s\n", fmt
);
3460 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3462 static const struct {
3463 const char name
[16];
3464 enum DevFmtType type
;
3466 { "int8", DevFmtByte
},
3467 { "uint8", DevFmtUByte
},
3468 { "int16", DevFmtShort
},
3469 { "uint16", DevFmtUShort
},
3470 { "int32", DevFmtInt
},
3471 { "uint32", DevFmtUInt
},
3472 { "float32", DevFmtFloat
},
3476 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3478 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3480 device
->FmtType
= typelist
[i
].type
;
3481 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3485 if(i
== COUNTOF(typelist
))
3486 ERR("Unsupported sample-type: %s\n", fmt
);
3489 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3491 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3492 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3493 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3494 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3497 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3498 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3500 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3501 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3502 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3503 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3505 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->MaxNoOfSources
);
3506 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3508 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3509 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3511 ConfigValueUInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3512 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3514 device
->NumStereoSources
= 1;
3515 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3517 // Find a playback device to open
3518 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3520 DELETE_OBJ(device
->Backend
);
3522 alcSetError(NULL
, err
);
3526 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3528 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3529 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3531 device
->DefaultSlot
= NULL
;
3532 ERR("Failed to initialize the default effect slot\n");
3534 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3536 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3537 device
->DefaultSlot
= NULL
;
3539 ERR("Failed to initialize the default effect\n");
3542 aluInitEffectPanning(device
->DefaultSlot
);
3546 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3548 device
->next
= head
;
3549 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3552 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3558 * Closes the given device.
3560 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3562 ALCdevice
*list
, *origdev
, *nextdev
;
3566 list
= ATOMIC_LOAD(&DeviceList
);
3570 } while((list
=list
->next
) != NULL
);
3571 if(!list
|| list
->Type
== Capture
)
3573 alcSetError(list
, ALC_INVALID_DEVICE
);
3579 nextdev
= device
->next
;
3580 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3585 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3589 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3592 ALCcontext
*next
= ctx
->next
;
3593 WARN("Releasing context %p\n", ctx
);
3594 ReleaseContext(ctx
, device
);
3597 if((device
->Flags
&DEVICE_RUNNING
))
3598 V0(device
->Backend
,stop
)();
3599 device
->Flags
&= ~DEVICE_RUNNING
;
3601 ALCdevice_DecRef(device
);
3607 /************************************************
3608 * ALC capture functions
3609 ************************************************/
3610 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3612 ALCdevice
*device
= NULL
;
3617 if(!CaptureBackend
.name
)
3619 alcSetError(NULL
, ALC_INVALID_VALUE
);
3625 alcSetError(NULL
, ALC_INVALID_VALUE
);
3629 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3632 device
= al_calloc(16, sizeof(ALCdevice
));
3635 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3640 InitRef(&device
->ref
, 1);
3641 device
->Connected
= ALC_TRUE
;
3642 device
->Type
= Capture
;
3644 VECTOR_INIT(device
->Hrtf_List
);
3645 AL_STRING_INIT(device
->Hrtf_Name
);
3647 AL_STRING_INIT(device
->DeviceName
);
3648 device
->Dry
.Buffer
= NULL
;
3649 device
->Dry
.NumChannels
= 0;
3650 device
->VirtOut
.Buffer
= NULL
;
3651 device
->VirtOut
.NumChannels
= 0;
3652 device
->RealOut
.Buffer
= NULL
;
3653 device
->RealOut
.NumChannels
= 0;
3655 InitUIntMap(&device
->BufferMap
, ~0);
3656 InitUIntMap(&device
->EffectMap
, ~0);
3657 InitUIntMap(&device
->FilterMap
, ~0);
3659 if(!CaptureBackend
.getFactory
)
3660 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3661 ALCbackend_Capture
);
3664 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3665 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3667 if(!device
->Backend
)
3670 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3674 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3675 device
->Frequency
= frequency
;
3677 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3678 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3681 alcSetError(NULL
, ALC_INVALID_ENUM
);
3684 device
->IsHeadphones
= AL_FALSE
;
3686 device
->UpdateSize
= samples
;
3687 device
->NumUpdates
= 1;
3689 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3692 alcSetError(NULL
, err
);
3697 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3699 device
->next
= head
;
3700 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3703 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3707 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3709 ALCdevice
*list
, *next
, *nextdev
;
3712 list
= ATOMIC_LOAD(&DeviceList
);
3716 } while((list
=list
->next
) != NULL
);
3717 if(!list
|| list
->Type
!= Capture
)
3719 alcSetError(list
, ALC_INVALID_DEVICE
);
3725 nextdev
= device
->next
;
3726 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3731 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3735 ALCdevice_DecRef(device
);
3740 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3742 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3743 alcSetError(device
, ALC_INVALID_DEVICE
);
3746 V0(device
->Backend
,lock
)();
3747 if(!device
->Connected
)
3748 alcSetError(device
, ALC_INVALID_DEVICE
);
3749 else if(!(device
->Flags
&DEVICE_RUNNING
))
3751 if(V0(device
->Backend
,start
)())
3752 device
->Flags
|= DEVICE_RUNNING
;
3755 aluHandleDisconnect(device
);
3756 alcSetError(device
, ALC_INVALID_DEVICE
);
3759 V0(device
->Backend
,unlock
)();
3762 if(device
) ALCdevice_DecRef(device
);
3765 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3767 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3768 alcSetError(device
, ALC_INVALID_DEVICE
);
3771 V0(device
->Backend
,lock
)();
3772 if((device
->Flags
&DEVICE_RUNNING
))
3773 V0(device
->Backend
,stop
)();
3774 device
->Flags
&= ~DEVICE_RUNNING
;
3775 V0(device
->Backend
,unlock
)();
3778 if(device
) ALCdevice_DecRef(device
);
3781 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3783 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3784 alcSetError(device
, ALC_INVALID_DEVICE
);
3787 ALCenum err
= ALC_INVALID_VALUE
;
3789 V0(device
->Backend
,lock
)();
3790 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3791 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3792 V0(device
->Backend
,unlock
)();
3794 if(err
!= ALC_NO_ERROR
)
3795 alcSetError(device
, err
);
3797 if(device
) ALCdevice_DecRef(device
);
3801 /************************************************
3802 * ALC loopback functions
3803 ************************************************/
3805 /* alcLoopbackOpenDeviceSOFT
3807 * Open a loopback device, for manual rendering.
3809 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3811 ALCbackendFactory
*factory
;
3816 /* Make sure the device name, if specified, is us. */
3817 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3819 alcSetError(NULL
, ALC_INVALID_VALUE
);
3823 device
= al_calloc(16, sizeof(ALCdevice
));
3826 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3831 InitRef(&device
->ref
, 1);
3832 device
->Connected
= ALC_TRUE
;
3833 device
->Type
= Loopback
;
3834 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3837 VECTOR_INIT(device
->Hrtf_List
);
3838 AL_STRING_INIT(device
->Hrtf_Name
);
3839 device
->Bs2b
= NULL
;
3840 device
->Uhj_Encoder
= NULL
;
3841 device
->Render_Mode
= NormalRender
;
3842 AL_STRING_INIT(device
->DeviceName
);
3843 device
->Dry
.Buffer
= NULL
;
3844 device
->Dry
.NumChannels
= 0;
3845 device
->VirtOut
.Buffer
= NULL
;
3846 device
->VirtOut
.NumChannels
= 0;
3847 device
->RealOut
.Buffer
= NULL
;
3848 device
->RealOut
.NumChannels
= 0;
3850 ATOMIC_INIT(&device
->ContextList
, NULL
);
3852 device
->ClockBase
= 0;
3853 device
->SamplesDone
= 0;
3855 device
->MaxNoOfSources
= 256;
3856 device
->AuxiliaryEffectSlotMax
= 4;
3857 device
->NumAuxSends
= MAX_SENDS
;
3859 InitUIntMap(&device
->BufferMap
, ~0);
3860 InitUIntMap(&device
->EffectMap
, ~0);
3861 InitUIntMap(&device
->FilterMap
, ~0);
3863 factory
= ALCloopbackFactory_getFactory();
3864 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3865 if(!device
->Backend
)
3868 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3873 device
->NumUpdates
= 0;
3874 device
->UpdateSize
= 0;
3876 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3877 device
->FmtChans
= DevFmtChannelsDefault
;
3878 device
->FmtType
= DevFmtTypeDefault
;
3879 device
->IsHeadphones
= AL_FALSE
;
3881 ConfigValueUInt(NULL
, NULL
, "sources", &device
->MaxNoOfSources
);
3882 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3884 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3885 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3887 ConfigValueUInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
3888 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3890 device
->NumStereoSources
= 1;
3891 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3893 // Open the "backend"
3894 V(device
->Backend
,open
)("Loopback");
3897 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3899 device
->next
= head
;
3900 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3903 TRACE("Created device %p\n", device
);
3907 /* alcIsRenderFormatSupportedSOFT
3909 * Determines if the loopback device supports the given format for rendering.
3911 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3913 ALCboolean ret
= ALC_FALSE
;
3915 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3916 alcSetError(device
, ALC_INVALID_DEVICE
);
3918 alcSetError(device
, ALC_INVALID_VALUE
);
3921 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3922 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3923 freq
>= MIN_OUTPUT_RATE
)
3926 if(device
) ALCdevice_DecRef(device
);
3931 /* alcRenderSamplesSOFT
3933 * Renders some samples into a buffer, using the format last set by the
3934 * attributes given to alcCreateContext.
3936 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3938 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3939 alcSetError(device
, ALC_INVALID_DEVICE
);
3940 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3941 alcSetError(device
, ALC_INVALID_VALUE
);
3943 aluMixData(device
, buffer
, samples
);
3944 if(device
) ALCdevice_DecRef(device
);
3948 /************************************************
3949 * ALC DSP pause/resume functions
3950 ************************************************/
3952 /* alcDevicePauseSOFT
3954 * Pause the DSP to stop audio processing.
3956 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3958 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3959 alcSetError(device
, ALC_INVALID_DEVICE
);
3963 if((device
->Flags
&DEVICE_RUNNING
))
3964 V0(device
->Backend
,stop
)();
3965 device
->Flags
&= ~DEVICE_RUNNING
;
3966 device
->Flags
|= DEVICE_PAUSED
;
3969 if(device
) ALCdevice_DecRef(device
);
3972 /* alcDeviceResumeSOFT
3974 * Resume the DSP to restart audio processing.
3976 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3978 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3979 alcSetError(device
, ALC_INVALID_DEVICE
);
3983 if((device
->Flags
&DEVICE_PAUSED
))
3985 device
->Flags
&= ~DEVICE_PAUSED
;
3986 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3988 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3989 device
->Flags
|= DEVICE_RUNNING
;
3992 alcSetError(device
, ALC_INVALID_DEVICE
);
3993 V0(device
->Backend
,lock
)();
3994 aluHandleDisconnect(device
);
3995 V0(device
->Backend
,unlock
)();
4001 if(device
) ALCdevice_DecRef(device
);
4005 /************************************************
4006 * ALC HRTF functions
4007 ************************************************/
4009 /* alcGetStringiSOFT
4011 * Gets a string parameter at the given index.
4013 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4015 const ALCchar
*str
= NULL
;
4017 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4018 alcSetError(device
, ALC_INVALID_DEVICE
);
4019 else switch(paramName
)
4021 case ALC_HRTF_SPECIFIER_SOFT
:
4022 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->Hrtf_List
))
4023 str
= al_string_get_cstr(VECTOR_ELEM(device
->Hrtf_List
, index
).name
);
4025 alcSetError(device
, ALC_INVALID_VALUE
);
4029 alcSetError(device
, ALC_INVALID_ENUM
);
4032 if(device
) ALCdevice_DecRef(device
);
4037 /* alcResetDeviceSOFT
4039 * Resets the given device output, using the specified attribute list.
4041 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4046 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4049 alcSetError(device
, ALC_INVALID_DEVICE
);
4050 if(device
) ALCdevice_DecRef(device
);
4054 if((err
=UpdateDeviceParams(device
, attribs
)) != ALC_NO_ERROR
)
4057 alcSetError(device
, err
);
4058 if(err
== ALC_INVALID_DEVICE
)
4060 V0(device
->Backend
,lock
)();
4061 aluHandleDisconnect(device
);
4062 V0(device
->Backend
,unlock
)();
4064 ALCdevice_DecRef(device
);
4068 ALCdevice_DecRef(device
);