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"
40 #include "bformatdec.h"
48 #include "backends/base.h"
51 /************************************************
53 ************************************************/
56 ALCbackendFactory
* (*getFactory
)(void);
57 ALCboolean (*Init
)(BackendFuncs
*);
59 void (*Probe
)(enum DevProbe
);
63 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
64 static struct BackendInfo BackendList
[] = {
66 { "jack", ALCjackBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
68 #ifdef HAVE_PULSEAUDIO
69 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
72 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
75 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
78 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
81 { "solaris", ALCsolarisBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
84 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
87 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
90 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
93 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
96 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
99 { "port", ALCportBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
102 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
105 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
107 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
110 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
114 static struct BackendInfo PlaybackBackend
;
115 static struct BackendInfo CaptureBackend
;
118 /************************************************
119 * Functions, enums, and errors
120 ************************************************/
121 typedef struct ALCfunction
{
122 const ALCchar
*funcName
;
126 typedef struct ALCenums
{
127 const ALCchar
*enumName
;
131 #define DECL(x) { #x, (ALCvoid*)(x) }
132 static const ALCfunction alcFunctions
[] = {
133 DECL(alcCreateContext
),
134 DECL(alcMakeContextCurrent
),
135 DECL(alcProcessContext
),
136 DECL(alcSuspendContext
),
137 DECL(alcDestroyContext
),
138 DECL(alcGetCurrentContext
),
139 DECL(alcGetContextsDevice
),
141 DECL(alcCloseDevice
),
143 DECL(alcIsExtensionPresent
),
144 DECL(alcGetProcAddress
),
145 DECL(alcGetEnumValue
),
147 DECL(alcGetIntegerv
),
148 DECL(alcCaptureOpenDevice
),
149 DECL(alcCaptureCloseDevice
),
150 DECL(alcCaptureStart
),
151 DECL(alcCaptureStop
),
152 DECL(alcCaptureSamples
),
154 DECL(alcSetThreadContext
),
155 DECL(alcGetThreadContext
),
157 DECL(alcLoopbackOpenDeviceSOFT
),
158 DECL(alcIsRenderFormatSupportedSOFT
),
159 DECL(alcRenderSamplesSOFT
),
161 DECL(alcDevicePauseSOFT
),
162 DECL(alcDeviceResumeSOFT
),
164 DECL(alcGetStringiSOFT
),
165 DECL(alcResetDeviceSOFT
),
167 DECL(alcGetInteger64vSOFT
),
182 DECL(alIsExtensionPresent
),
183 DECL(alGetProcAddress
),
184 DECL(alGetEnumValue
),
191 DECL(alGetListenerf
),
192 DECL(alGetListener3f
),
193 DECL(alGetListenerfv
),
194 DECL(alGetListeneri
),
195 DECL(alGetListener3i
),
196 DECL(alGetListeneriv
),
198 DECL(alDeleteSources
),
214 DECL(alSourceRewindv
),
215 DECL(alSourcePausev
),
218 DECL(alSourceRewind
),
220 DECL(alSourceQueueBuffers
),
221 DECL(alSourceUnqueueBuffers
),
223 DECL(alDeleteBuffers
),
238 DECL(alDopplerFactor
),
239 DECL(alDopplerVelocity
),
240 DECL(alSpeedOfSound
),
241 DECL(alDistanceModel
),
244 DECL(alDeleteFilters
),
255 DECL(alDeleteEffects
),
265 DECL(alGenAuxiliaryEffectSlots
),
266 DECL(alDeleteAuxiliaryEffectSlots
),
267 DECL(alIsAuxiliaryEffectSlot
),
268 DECL(alAuxiliaryEffectSloti
),
269 DECL(alAuxiliaryEffectSlotiv
),
270 DECL(alAuxiliaryEffectSlotf
),
271 DECL(alAuxiliaryEffectSlotfv
),
272 DECL(alGetAuxiliaryEffectSloti
),
273 DECL(alGetAuxiliaryEffectSlotiv
),
274 DECL(alGetAuxiliaryEffectSlotf
),
275 DECL(alGetAuxiliaryEffectSlotfv
),
277 DECL(alBufferSubDataSOFT
),
279 DECL(alBufferSamplesSOFT
),
280 DECL(alBufferSubSamplesSOFT
),
281 DECL(alGetBufferSamplesSOFT
),
282 DECL(alIsBufferFormatSupportedSOFT
),
284 DECL(alDeferUpdatesSOFT
),
285 DECL(alProcessUpdatesSOFT
),
288 DECL(alSource3dSOFT
),
289 DECL(alSourcedvSOFT
),
290 DECL(alGetSourcedSOFT
),
291 DECL(alGetSource3dSOFT
),
292 DECL(alGetSourcedvSOFT
),
293 DECL(alSourcei64SOFT
),
294 DECL(alSource3i64SOFT
),
295 DECL(alSourcei64vSOFT
),
296 DECL(alGetSourcei64SOFT
),
297 DECL(alGetSource3i64SOFT
),
298 DECL(alGetSourcei64vSOFT
),
304 #define DECL(x) { #x, (x) }
305 static const ALCenums enumeration
[] = {
310 DECL(ALC_MAJOR_VERSION
),
311 DECL(ALC_MINOR_VERSION
),
312 DECL(ALC_ATTRIBUTES_SIZE
),
313 DECL(ALC_ALL_ATTRIBUTES
),
314 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
315 DECL(ALC_DEVICE_SPECIFIER
),
316 DECL(ALC_ALL_DEVICES_SPECIFIER
),
317 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
318 DECL(ALC_EXTENSIONS
),
322 DECL(ALC_MONO_SOURCES
),
323 DECL(ALC_STEREO_SOURCES
),
324 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
325 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
326 DECL(ALC_CAPTURE_SAMPLES
),
329 DECL(ALC_EFX_MAJOR_VERSION
),
330 DECL(ALC_EFX_MINOR_VERSION
),
331 DECL(ALC_MAX_AUXILIARY_SENDS
),
333 DECL(ALC_FORMAT_CHANNELS_SOFT
),
334 DECL(ALC_FORMAT_TYPE_SOFT
),
337 DECL(ALC_STEREO_SOFT
),
339 DECL(ALC_5POINT1_SOFT
),
340 DECL(ALC_6POINT1_SOFT
),
341 DECL(ALC_7POINT1_SOFT
),
344 DECL(ALC_UNSIGNED_BYTE_SOFT
),
345 DECL(ALC_SHORT_SOFT
),
346 DECL(ALC_UNSIGNED_SHORT_SOFT
),
348 DECL(ALC_UNSIGNED_INT_SOFT
),
349 DECL(ALC_FLOAT_SOFT
),
352 DECL(ALC_DONT_CARE_SOFT
),
353 DECL(ALC_HRTF_STATUS_SOFT
),
354 DECL(ALC_HRTF_DISABLED_SOFT
),
355 DECL(ALC_HRTF_ENABLED_SOFT
),
356 DECL(ALC_HRTF_DENIED_SOFT
),
357 DECL(ALC_HRTF_REQUIRED_SOFT
),
358 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
359 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
360 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
361 DECL(ALC_HRTF_SPECIFIER_SOFT
),
362 DECL(ALC_HRTF_ID_SOFT
),
365 DECL(ALC_INVALID_DEVICE
),
366 DECL(ALC_INVALID_CONTEXT
),
367 DECL(ALC_INVALID_ENUM
),
368 DECL(ALC_INVALID_VALUE
),
369 DECL(ALC_OUT_OF_MEMORY
),
377 DECL(AL_SOURCE_RELATIVE
),
378 DECL(AL_CONE_INNER_ANGLE
),
379 DECL(AL_CONE_OUTER_ANGLE
),
389 DECL(AL_ORIENTATION
),
390 DECL(AL_REFERENCE_DISTANCE
),
391 DECL(AL_ROLLOFF_FACTOR
),
392 DECL(AL_CONE_OUTER_GAIN
),
393 DECL(AL_MAX_DISTANCE
),
395 DECL(AL_SAMPLE_OFFSET
),
396 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
397 DECL(AL_BYTE_OFFSET
),
398 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
399 DECL(AL_SOURCE_TYPE
),
402 DECL(AL_UNDETERMINED
),
403 DECL(AL_METERS_PER_UNIT
),
404 DECL(AL_LOOP_POINTS_SOFT
),
405 DECL(AL_DIRECT_CHANNELS_SOFT
),
407 DECL(AL_DIRECT_FILTER
),
408 DECL(AL_AUXILIARY_SEND_FILTER
),
409 DECL(AL_AIR_ABSORPTION_FACTOR
),
410 DECL(AL_ROOM_ROLLOFF_FACTOR
),
411 DECL(AL_CONE_OUTER_GAINHF
),
412 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
413 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
414 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
416 DECL(AL_SOURCE_STATE
),
422 DECL(AL_BUFFERS_QUEUED
),
423 DECL(AL_BUFFERS_PROCESSED
),
425 DECL(AL_FORMAT_MONO8
),
426 DECL(AL_FORMAT_MONO16
),
427 DECL(AL_FORMAT_MONO_FLOAT32
),
428 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
429 DECL(AL_FORMAT_STEREO8
),
430 DECL(AL_FORMAT_STEREO16
),
431 DECL(AL_FORMAT_STEREO_FLOAT32
),
432 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
433 DECL(AL_FORMAT_MONO_IMA4
),
434 DECL(AL_FORMAT_STEREO_IMA4
),
435 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
436 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
437 DECL(AL_FORMAT_QUAD8_LOKI
),
438 DECL(AL_FORMAT_QUAD16_LOKI
),
439 DECL(AL_FORMAT_QUAD8
),
440 DECL(AL_FORMAT_QUAD16
),
441 DECL(AL_FORMAT_QUAD32
),
442 DECL(AL_FORMAT_51CHN8
),
443 DECL(AL_FORMAT_51CHN16
),
444 DECL(AL_FORMAT_51CHN32
),
445 DECL(AL_FORMAT_61CHN8
),
446 DECL(AL_FORMAT_61CHN16
),
447 DECL(AL_FORMAT_61CHN32
),
448 DECL(AL_FORMAT_71CHN8
),
449 DECL(AL_FORMAT_71CHN16
),
450 DECL(AL_FORMAT_71CHN32
),
451 DECL(AL_FORMAT_REAR8
),
452 DECL(AL_FORMAT_REAR16
),
453 DECL(AL_FORMAT_REAR32
),
454 DECL(AL_FORMAT_MONO_MULAW
),
455 DECL(AL_FORMAT_MONO_MULAW_EXT
),
456 DECL(AL_FORMAT_STEREO_MULAW
),
457 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
458 DECL(AL_FORMAT_QUAD_MULAW
),
459 DECL(AL_FORMAT_51CHN_MULAW
),
460 DECL(AL_FORMAT_61CHN_MULAW
),
461 DECL(AL_FORMAT_71CHN_MULAW
),
462 DECL(AL_FORMAT_REAR_MULAW
),
463 DECL(AL_FORMAT_MONO_ALAW_EXT
),
464 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
467 DECL(AL_MONO16_SOFT
),
468 DECL(AL_MONO32F_SOFT
),
469 DECL(AL_STEREO8_SOFT
),
470 DECL(AL_STEREO16_SOFT
),
471 DECL(AL_STEREO32F_SOFT
),
473 DECL(AL_QUAD16_SOFT
),
474 DECL(AL_QUAD32F_SOFT
),
476 DECL(AL_REAR16_SOFT
),
477 DECL(AL_REAR32F_SOFT
),
478 DECL(AL_5POINT1_8_SOFT
),
479 DECL(AL_5POINT1_16_SOFT
),
480 DECL(AL_5POINT1_32F_SOFT
),
481 DECL(AL_6POINT1_8_SOFT
),
482 DECL(AL_6POINT1_16_SOFT
),
483 DECL(AL_6POINT1_32F_SOFT
),
484 DECL(AL_7POINT1_8_SOFT
),
485 DECL(AL_7POINT1_16_SOFT
),
486 DECL(AL_7POINT1_32F_SOFT
),
487 DECL(AL_FORMAT_BFORMAT2D_8
),
488 DECL(AL_FORMAT_BFORMAT2D_16
),
489 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
490 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
491 DECL(AL_FORMAT_BFORMAT3D_8
),
492 DECL(AL_FORMAT_BFORMAT3D_16
),
493 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
494 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
497 DECL(AL_STEREO_SOFT
),
500 DECL(AL_5POINT1_SOFT
),
501 DECL(AL_6POINT1_SOFT
),
502 DECL(AL_7POINT1_SOFT
),
505 DECL(AL_UNSIGNED_BYTE_SOFT
),
507 DECL(AL_UNSIGNED_SHORT_SOFT
),
509 DECL(AL_UNSIGNED_INT_SOFT
),
511 DECL(AL_DOUBLE_SOFT
),
513 DECL(AL_UNSIGNED_BYTE3_SOFT
),
519 DECL(AL_INTERNAL_FORMAT_SOFT
),
520 DECL(AL_BYTE_LENGTH_SOFT
),
521 DECL(AL_SAMPLE_LENGTH_SOFT
),
522 DECL(AL_SEC_LENGTH_SOFT
),
523 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
524 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
531 DECL(AL_INVALID_NAME
),
532 DECL(AL_INVALID_ENUM
),
533 DECL(AL_INVALID_VALUE
),
534 DECL(AL_INVALID_OPERATION
),
535 DECL(AL_OUT_OF_MEMORY
),
542 DECL(AL_DOPPLER_FACTOR
),
543 DECL(AL_DOPPLER_VELOCITY
),
544 DECL(AL_DISTANCE_MODEL
),
545 DECL(AL_SPEED_OF_SOUND
),
546 DECL(AL_SOURCE_DISTANCE_MODEL
),
547 DECL(AL_DEFERRED_UPDATES_SOFT
),
549 DECL(AL_INVERSE_DISTANCE
),
550 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
551 DECL(AL_LINEAR_DISTANCE
),
552 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
553 DECL(AL_EXPONENT_DISTANCE
),
554 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
556 DECL(AL_FILTER_TYPE
),
557 DECL(AL_FILTER_NULL
),
558 DECL(AL_FILTER_LOWPASS
),
559 DECL(AL_FILTER_HIGHPASS
),
560 DECL(AL_FILTER_BANDPASS
),
562 DECL(AL_LOWPASS_GAIN
),
563 DECL(AL_LOWPASS_GAINHF
),
565 DECL(AL_HIGHPASS_GAIN
),
566 DECL(AL_HIGHPASS_GAINLF
),
568 DECL(AL_BANDPASS_GAIN
),
569 DECL(AL_BANDPASS_GAINHF
),
570 DECL(AL_BANDPASS_GAINLF
),
572 DECL(AL_EFFECT_TYPE
),
573 DECL(AL_EFFECT_NULL
),
574 DECL(AL_EFFECT_REVERB
),
575 DECL(AL_EFFECT_EAXREVERB
),
576 DECL(AL_EFFECT_CHORUS
),
577 DECL(AL_EFFECT_DISTORTION
),
578 DECL(AL_EFFECT_ECHO
),
579 DECL(AL_EFFECT_FLANGER
),
581 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
582 DECL(AL_EFFECT_VOCAL_MORPHER
),
583 DECL(AL_EFFECT_PITCH_SHIFTER
),
585 DECL(AL_EFFECT_RING_MODULATOR
),
587 DECL(AL_EFFECT_AUTOWAH
),
589 DECL(AL_EFFECT_COMPRESSOR
),
590 DECL(AL_EFFECT_EQUALIZER
),
591 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
592 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
594 DECL(AL_EAXREVERB_DENSITY
),
595 DECL(AL_EAXREVERB_DIFFUSION
),
596 DECL(AL_EAXREVERB_GAIN
),
597 DECL(AL_EAXREVERB_GAINHF
),
598 DECL(AL_EAXREVERB_GAINLF
),
599 DECL(AL_EAXREVERB_DECAY_TIME
),
600 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
601 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
602 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
603 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
604 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
605 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
606 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
607 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
608 DECL(AL_EAXREVERB_ECHO_TIME
),
609 DECL(AL_EAXREVERB_ECHO_DEPTH
),
610 DECL(AL_EAXREVERB_MODULATION_TIME
),
611 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
612 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
613 DECL(AL_EAXREVERB_HFREFERENCE
),
614 DECL(AL_EAXREVERB_LFREFERENCE
),
615 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
616 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
618 DECL(AL_REVERB_DENSITY
),
619 DECL(AL_REVERB_DIFFUSION
),
620 DECL(AL_REVERB_GAIN
),
621 DECL(AL_REVERB_GAINHF
),
622 DECL(AL_REVERB_DECAY_TIME
),
623 DECL(AL_REVERB_DECAY_HFRATIO
),
624 DECL(AL_REVERB_REFLECTIONS_GAIN
),
625 DECL(AL_REVERB_REFLECTIONS_DELAY
),
626 DECL(AL_REVERB_LATE_REVERB_GAIN
),
627 DECL(AL_REVERB_LATE_REVERB_DELAY
),
628 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
629 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
630 DECL(AL_REVERB_DECAY_HFLIMIT
),
632 DECL(AL_CHORUS_WAVEFORM
),
633 DECL(AL_CHORUS_PHASE
),
634 DECL(AL_CHORUS_RATE
),
635 DECL(AL_CHORUS_DEPTH
),
636 DECL(AL_CHORUS_FEEDBACK
),
637 DECL(AL_CHORUS_DELAY
),
639 DECL(AL_DISTORTION_EDGE
),
640 DECL(AL_DISTORTION_GAIN
),
641 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
642 DECL(AL_DISTORTION_EQCENTER
),
643 DECL(AL_DISTORTION_EQBANDWIDTH
),
646 DECL(AL_ECHO_LRDELAY
),
647 DECL(AL_ECHO_DAMPING
),
648 DECL(AL_ECHO_FEEDBACK
),
649 DECL(AL_ECHO_SPREAD
),
651 DECL(AL_FLANGER_WAVEFORM
),
652 DECL(AL_FLANGER_PHASE
),
653 DECL(AL_FLANGER_RATE
),
654 DECL(AL_FLANGER_DEPTH
),
655 DECL(AL_FLANGER_FEEDBACK
),
656 DECL(AL_FLANGER_DELAY
),
658 DECL(AL_RING_MODULATOR_FREQUENCY
),
659 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
660 DECL(AL_RING_MODULATOR_WAVEFORM
),
663 DECL(AL_AUTOWAH_ATTACK_TIME
),
664 DECL(AL_AUTOWAH_PEAK_GAIN
),
665 DECL(AL_AUTOWAH_RELEASE_TIME
),
666 DECL(AL_AUTOWAH_RESONANCE
),
669 DECL(AL_COMPRESSOR_ONOFF
),
671 DECL(AL_EQUALIZER_LOW_GAIN
),
672 DECL(AL_EQUALIZER_LOW_CUTOFF
),
673 DECL(AL_EQUALIZER_MID1_GAIN
),
674 DECL(AL_EQUALIZER_MID1_CENTER
),
675 DECL(AL_EQUALIZER_MID1_WIDTH
),
676 DECL(AL_EQUALIZER_MID2_GAIN
),
677 DECL(AL_EQUALIZER_MID2_CENTER
),
678 DECL(AL_EQUALIZER_MID2_WIDTH
),
679 DECL(AL_EQUALIZER_HIGH_GAIN
),
680 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
682 DECL(AL_DEDICATED_GAIN
),
688 static const ALCchar alcNoError
[] = "No Error";
689 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
690 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
691 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
692 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
693 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
696 /************************************************
698 ************************************************/
700 /* Enumerated device names */
701 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
703 static al_string alcAllDevicesList
;
704 static al_string alcCaptureDeviceList
;
706 /* Default is always the first in the list */
707 static ALCchar
*alcDefaultAllDevicesSpecifier
;
708 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
710 /* Default context extensions */
711 static const ALchar alExtList
[] =
712 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
713 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
714 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
715 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
716 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
717 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
718 "AL_SOFT_source_latency AL_SOFT_source_length";
720 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
722 /* Thread-local current context */
723 static altss_t LocalContext
;
724 /* Process-wide current context */
725 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
727 /* Mixing thread piority level */
732 enum LogLevel LogLevel
= LogWarning
;
734 enum LogLevel LogLevel
= LogError
;
737 /* Flag to trap ALC device errors */
738 static ALCboolean TrapALCError
= ALC_FALSE
;
740 /* One-time configuration init control */
741 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
743 /* Default effect that applies to sources that don't have an effect on send 0 */
744 static ALeffect DefaultEffect
;
746 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
749 static ALCboolean SuspendDefers
= ALC_TRUE
;
752 /************************************************
754 ************************************************/
755 static const ALCchar alcNoDeviceExtList
[] =
756 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
757 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
758 static const ALCchar alcExtensionList
[] =
759 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
760 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
761 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
762 "ALC_SOFT_loopback ALC_SOFT_pause_device";
763 static const ALCint alcMajorVersion
= 1;
764 static const ALCint alcMinorVersion
= 1;
766 static const ALCint alcEFXMajorVersion
= 1;
767 static const ALCint alcEFXMinorVersion
= 0;
770 /************************************************
772 ************************************************/
773 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
775 static almtx_t ListLock
;
776 static inline void LockLists(void)
778 int lockret
= almtx_lock(&ListLock
);
779 assert(lockret
== althrd_success
);
781 static inline void UnlockLists(void)
783 int unlockret
= almtx_unlock(&ListLock
);
784 assert(unlockret
== althrd_success
);
787 /************************************************
788 * Library initialization
789 ************************************************/
791 static void alc_init(void);
792 static void alc_deinit(void);
793 static void alc_deinit_safe(void);
795 #ifndef AL_LIBTYPE_STATIC
796 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
800 case DLL_PROCESS_ATTACH
:
801 /* Pin the DLL so we won't get unloaded until the process terminates */
802 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
803 (WCHAR
*)hModule
, &hModule
);
807 case DLL_THREAD_DETACH
:
810 case DLL_PROCESS_DETACH
:
819 #elif defined(_MSC_VER)
820 #pragma section(".CRT$XCU",read)
821 static void alc_constructor(void);
822 static void alc_destructor(void);
823 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
825 static void alc_constructor(void)
827 atexit(alc_destructor
);
831 static void alc_destructor(void)
835 #elif defined(HAVE_GCC_DESTRUCTOR)
836 static void alc_init(void) __attribute__((constructor
));
837 static void alc_deinit(void) __attribute__((destructor
));
839 #error "No static initialization available on this platform!"
842 #elif defined(HAVE_GCC_DESTRUCTOR)
844 static void alc_init(void) __attribute__((constructor
));
845 static void alc_deinit(void) __attribute__((destructor
));
848 #error "No global initialization available on this platform!"
851 static void ReleaseThreadCtx(void *ptr
);
852 static void alc_init(void)
859 AL_STRING_INIT(alcAllDevicesList
);
860 AL_STRING_INIT(alcCaptureDeviceList
);
862 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
863 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
866 str
= getenv("__ALSOFT_REVERSE_Z");
867 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
870 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
871 assert(ret
== althrd_success
);
873 ret
= almtx_init(&ListLock
, almtx_recursive
);
874 assert(ret
== althrd_success
);
879 static void alc_initconfig(void)
881 const char *devs
, *str
;
886 str
= getenv("ALSOFT_LOGLEVEL");
889 long lvl
= strtol(str
, NULL
, 0);
890 if(lvl
>= NoLog
&& lvl
<= LogRef
)
894 str
= getenv("ALSOFT_LOGFILE");
897 FILE *logfile
= al_fopen(str
, "wt");
898 if(logfile
) LogFile
= logfile
;
899 else ERR("Failed to open log file '%s'\n", str
);
904 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
905 for(i
= 1;BackendList
[i
].name
;i
++)
906 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
907 TRACE("Supported backends: %s\n", buf
);
911 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
914 if(strcasecmp(str
, "ignore") == 0)
916 SuspendDefers
= ALC_FALSE
;
917 TRACE("Selected context suspend behavior, \"ignore\"\n");
920 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
924 #if defined(HAVE_SSE4_1)
925 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
926 #elif defined(HAVE_SSE3)
927 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
928 #elif defined(HAVE_SSE2)
929 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
930 #elif defined(HAVE_SSE)
931 capfilter
|= CPU_CAP_SSE
;
934 capfilter
|= CPU_CAP_NEON
;
936 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
938 if(strcasecmp(str
, "all") == 0)
943 const char *next
= str
;
947 while(isspace(str
[0]))
949 next
= strchr(str
, ',');
951 if(!str
[0] || str
[0] == ',')
954 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
955 while(len
> 0 && isspace(str
[len
-1]))
957 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
958 capfilter
&= ~CPU_CAP_SSE
;
959 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
960 capfilter
&= ~CPU_CAP_SSE2
;
961 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
962 capfilter
&= ~CPU_CAP_SSE3
;
963 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
964 capfilter
&= ~CPU_CAP_SSE4_1
;
965 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
966 capfilter
&= ~CPU_CAP_NEON
;
968 WARN("Invalid CPU extension \"%s\"\n", str
);
972 FillCPUCaps(capfilter
);
979 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
983 str
= getenv("ALSOFT_TRAP_ERROR");
984 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
986 TrapALError
= AL_TRUE
;
987 TrapALCError
= AL_TRUE
;
991 str
= getenv("ALSOFT_TRAP_AL_ERROR");
992 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
993 TrapALError
= AL_TRUE
;
994 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
996 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
997 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
998 TrapALCError
= ALC_TRUE
;
999 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1002 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1003 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1005 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1007 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1008 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1012 const char *next
= devs
;
1013 int endlist
, delitem
;
1018 while(isspace(devs
[0]))
1020 next
= strchr(devs
, ',');
1022 delitem
= (devs
[0] == '-');
1023 if(devs
[0] == '-') devs
++;
1025 if(!devs
[0] || devs
[0] == ',')
1032 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1033 while(len
> 0 && isspace(devs
[len
-1]))
1035 for(n
= i
;BackendList
[n
].name
;n
++)
1037 if(len
== strlen(BackendList
[n
].name
) &&
1038 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1043 BackendList
[n
] = BackendList
[n
+1];
1045 } while(BackendList
[n
].name
);
1049 struct BackendInfo Bkp
= BackendList
[n
];
1052 BackendList
[n
] = BackendList
[n
-1];
1055 BackendList
[n
] = Bkp
;
1066 BackendList
[i
].name
= NULL
;
1067 BackendList
[i
].getFactory
= NULL
;
1068 BackendList
[i
].Init
= NULL
;
1069 BackendList
[i
].Deinit
= NULL
;
1070 BackendList
[i
].Probe
= NULL
;
1074 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1076 if(BackendList
[i
].getFactory
)
1078 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1079 if(!V0(factory
,init
)())
1081 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1085 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1086 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1088 PlaybackBackend
= BackendList
[i
];
1089 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1091 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1093 CaptureBackend
= BackendList
[i
];
1094 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1100 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1102 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1106 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1107 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1109 PlaybackBackend
= BackendList
[i
];
1110 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1112 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1114 CaptureBackend
= BackendList
[i
];
1115 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1119 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1123 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1126 const char *next
= str
;
1130 next
= strchr(str
, ',');
1132 if(!str
[0] || next
== str
)
1135 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1136 for(n
= 0;EffectList
[n
].name
;n
++)
1138 if(len
== strlen(EffectList
[n
].name
) &&
1139 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1140 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1145 InitEffectFactoryMap();
1147 InitEffect(&DefaultEffect
);
1148 str
= getenv("ALSOFT_DEFAULT_REVERB");
1149 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1150 LoadReverbPreset(str
, &DefaultEffect
);
1152 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1155 /************************************************
1156 * Library deinitialization
1157 ************************************************/
1158 static void alc_cleanup(void)
1162 AL_STRING_DEINIT(alcAllDevicesList
);
1163 AL_STRING_DEINIT(alcCaptureDeviceList
);
1165 free(alcDefaultAllDevicesSpecifier
);
1166 alcDefaultAllDevicesSpecifier
= NULL
;
1167 free(alcCaptureDefaultDeviceSpecifier
);
1168 alcCaptureDefaultDeviceSpecifier
= NULL
;
1170 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1175 } while((dev
=dev
->next
) != NULL
);
1176 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1179 DeinitEffectFactoryMap();
1182 static void alc_deinit_safe(void)
1190 almtx_destroy(&ListLock
);
1191 altss_delete(LocalContext
);
1193 if(LogFile
!= stderr
)
1198 static void alc_deinit(void)
1204 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1205 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1207 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1209 if(!BackendList
[i
].getFactory
)
1210 BackendList
[i
].Deinit();
1213 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1214 V0(factory
,deinit
)();
1218 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1219 V0(factory
,deinit
)();
1226 /************************************************
1227 * Device enumeration
1228 ************************************************/
1229 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1234 al_string_clear(list
);
1236 if(!backendinfo
->getFactory
)
1237 backendinfo
->Probe(type
);
1240 ALCbackendFactory
*factory
= backendinfo
->getFactory();
1241 V(factory
,probe
)(type
);
1246 static void ProbeAllDevicesList(void)
1247 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1248 static void ProbeCaptureDeviceList(void)
1249 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1251 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1253 size_t len
= strlen(name
);
1255 al_string_append_range(devnames
, name
, name
+len
+1);
1257 void AppendAllDevicesList(const ALCchar
*name
)
1258 { AppendDevice(name
, &alcAllDevicesList
); }
1259 void AppendCaptureDeviceList(const ALCchar
*name
)
1260 { AppendDevice(name
, &alcCaptureDeviceList
); }
1263 /************************************************
1264 * Device format information
1265 ************************************************/
1266 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1270 case DevFmtByte
: return "Signed Byte";
1271 case DevFmtUByte
: return "Unsigned Byte";
1272 case DevFmtShort
: return "Signed Short";
1273 case DevFmtUShort
: return "Unsigned Short";
1274 case DevFmtInt
: return "Signed Int";
1275 case DevFmtUInt
: return "Unsigned Int";
1276 case DevFmtFloat
: return "Float";
1278 return "(unknown type)";
1280 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1284 case DevFmtMono
: return "Mono";
1285 case DevFmtStereo
: return "Stereo";
1286 case DevFmtQuad
: return "Quadraphonic";
1287 case DevFmtX51
: return "5.1 Surround";
1288 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1289 case DevFmtX61
: return "6.1 Surround";
1290 case DevFmtX71
: return "7.1 Surround";
1291 case DevFmtBFormat3D
: return "B-Format 3D";
1293 return "(unknown channels)";
1296 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1297 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1301 case DevFmtByte
: return sizeof(ALbyte
);
1302 case DevFmtUByte
: return sizeof(ALubyte
);
1303 case DevFmtShort
: return sizeof(ALshort
);
1304 case DevFmtUShort
: return sizeof(ALushort
);
1305 case DevFmtInt
: return sizeof(ALint
);
1306 case DevFmtUInt
: return sizeof(ALuint
);
1307 case DevFmtFloat
: return sizeof(ALfloat
);
1311 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1315 case DevFmtMono
: return 1;
1316 case DevFmtStereo
: return 2;
1317 case DevFmtQuad
: return 4;
1318 case DevFmtX51
: return 6;
1319 case DevFmtX51Rear
: return 6;
1320 case DevFmtX61
: return 7;
1321 case DevFmtX71
: return 8;
1322 case DevFmtBFormat3D
: return 4;
1327 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1328 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1330 static const struct {
1332 enum DevFmtChannels channels
;
1333 enum DevFmtType type
;
1335 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1336 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1337 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1339 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1340 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1341 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1343 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1344 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1345 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1347 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1348 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1349 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1351 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1352 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1353 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1355 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1356 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1357 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1361 for(i
= 0;i
< COUNTOF(list
);i
++)
1363 if(list
[i
].format
== format
)
1365 *chans
= list
[i
].channels
;
1366 *type
= list
[i
].type
;
1374 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1379 case ALC_UNSIGNED_BYTE_SOFT
:
1380 case ALC_SHORT_SOFT
:
1381 case ALC_UNSIGNED_SHORT_SOFT
:
1383 case ALC_UNSIGNED_INT_SOFT
:
1384 case ALC_FLOAT_SOFT
:
1390 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1395 case ALC_STEREO_SOFT
:
1397 case ALC_5POINT1_SOFT
:
1398 case ALC_6POINT1_SOFT
:
1399 case ALC_7POINT1_SOFT
:
1406 /************************************************
1407 * Miscellaneous ALC helpers
1408 ************************************************/
1409 enum HrtfRequestMode
{
1415 extern inline void LockContext(ALCcontext
*context
);
1416 extern inline void UnlockContext(ALCcontext
*context
);
1418 void ALCdevice_Lock(ALCdevice
*device
)
1420 V0(device
->Backend
,lock
)();
1423 void ALCdevice_Unlock(ALCdevice
*device
)
1425 V0(device
->Backend
,unlock
)();
1429 /* SetDefaultWFXChannelOrder
1431 * Sets the default channel order used by WaveFormatEx.
1433 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1437 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1438 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1440 switch(device
->FmtChans
)
1443 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1446 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1447 device
->RealOut
.ChannelName
[1] = FrontRight
;
1450 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1451 device
->RealOut
.ChannelName
[1] = FrontRight
;
1452 device
->RealOut
.ChannelName
[2] = BackLeft
;
1453 device
->RealOut
.ChannelName
[3] = BackRight
;
1456 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1457 device
->RealOut
.ChannelName
[1] = FrontRight
;
1458 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1459 device
->RealOut
.ChannelName
[3] = LFE
;
1460 device
->RealOut
.ChannelName
[4] = SideLeft
;
1461 device
->RealOut
.ChannelName
[5] = SideRight
;
1464 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1465 device
->RealOut
.ChannelName
[1] = FrontRight
;
1466 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1467 device
->RealOut
.ChannelName
[3] = LFE
;
1468 device
->RealOut
.ChannelName
[4] = BackLeft
;
1469 device
->RealOut
.ChannelName
[5] = BackRight
;
1472 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1473 device
->RealOut
.ChannelName
[1] = FrontRight
;
1474 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1475 device
->RealOut
.ChannelName
[3] = LFE
;
1476 device
->RealOut
.ChannelName
[4] = BackCenter
;
1477 device
->RealOut
.ChannelName
[5] = SideLeft
;
1478 device
->RealOut
.ChannelName
[6] = SideRight
;
1481 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1482 device
->RealOut
.ChannelName
[1] = FrontRight
;
1483 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1484 device
->RealOut
.ChannelName
[3] = LFE
;
1485 device
->RealOut
.ChannelName
[4] = BackLeft
;
1486 device
->RealOut
.ChannelName
[5] = BackRight
;
1487 device
->RealOut
.ChannelName
[6] = SideLeft
;
1488 device
->RealOut
.ChannelName
[7] = SideRight
;
1490 case DevFmtBFormat3D
:
1491 device
->RealOut
.ChannelName
[0] = BFormatW
;
1492 device
->RealOut
.ChannelName
[1] = BFormatX
;
1493 device
->RealOut
.ChannelName
[2] = BFormatY
;
1494 device
->RealOut
.ChannelName
[3] = BFormatZ
;
1499 /* SetDefaultChannelOrder
1501 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1503 void SetDefaultChannelOrder(ALCdevice
*device
)
1507 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1508 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1510 switch(device
->FmtChans
)
1513 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1514 device
->RealOut
.ChannelName
[1] = FrontRight
;
1515 device
->RealOut
.ChannelName
[2] = BackLeft
;
1516 device
->RealOut
.ChannelName
[3] = BackRight
;
1517 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1518 device
->RealOut
.ChannelName
[5] = LFE
;
1521 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1522 device
->RealOut
.ChannelName
[1] = FrontRight
;
1523 device
->RealOut
.ChannelName
[2] = BackLeft
;
1524 device
->RealOut
.ChannelName
[3] = BackRight
;
1525 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1526 device
->RealOut
.ChannelName
[5] = LFE
;
1527 device
->RealOut
.ChannelName
[6] = SideLeft
;
1528 device
->RealOut
.ChannelName
[7] = SideRight
;
1531 /* Same as WFX order */
1537 case DevFmtBFormat3D
:
1538 SetDefaultWFXChannelOrder(device
);
1543 extern inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
);
1546 /* ALCcontext_DeferUpdates
1548 * Defers/suspends updates for the given context's listener and sources. This
1549 * does *NOT* stop mixing, but rather prevents certain property changes from
1552 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1554 ALCdevice
*device
= context
->Device
;
1557 SetMixerFPUMode(&oldMode
);
1559 V0(device
->Backend
,lock
)();
1560 if(!context
->DeferUpdates
)
1562 context
->DeferUpdates
= AL_TRUE
;
1564 /* Make sure all pending updates are performed */
1565 UpdateContextSources(context
);
1566 #define UPDATE_SLOT(iter) do { \
1567 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1568 V((*iter)->EffectState,update)(device, *iter); \
1570 VECTOR_FOR_EACH(ALeffectslot
*, context
->ActiveAuxSlots
, UPDATE_SLOT
);
1573 V0(device
->Backend
,unlock
)();
1575 RestoreFPUMode(&oldMode
);
1578 /* ALCcontext_ProcessUpdates
1580 * Resumes update processing after being deferred.
1582 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1584 ALCdevice
*device
= context
->Device
;
1586 V0(device
->Backend
,lock
)();
1587 if(context
->DeferUpdates
)
1591 context
->DeferUpdates
= AL_FALSE
;
1593 LockUIntMapRead(&context
->SourceMap
);
1594 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1596 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1599 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1600 Source
->Offset
>= 0.0)
1602 WriteLock(&Source
->queue_lock
);
1603 ApplyOffset(Source
);
1604 WriteUnlock(&Source
->queue_lock
);
1607 new_state
= Source
->new_state
;
1608 Source
->new_state
= AL_NONE
;
1610 SetSourceState(Source
, context
, new_state
);
1612 UnlockUIntMapRead(&context
->SourceMap
);
1614 V0(device
->Backend
,unlock
)();
1620 * Stores the latest ALC device error
1622 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1627 /* DebugBreak() will cause an exception if there is no debugger */
1628 if(IsDebuggerPresent())
1630 #elif defined(SIGTRAP)
1636 ATOMIC_STORE(&device
->LastError
, errorCode
);
1638 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1644 * Updates the device's base clock time with however many samples have been
1645 * done. This is used so frequency changes on the device don't cause the time
1646 * to jump forward or back.
1648 static inline void UpdateClockBase(ALCdevice
*device
)
1650 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1651 device
->SamplesDone
= 0;
1654 /* UpdateDeviceParams
1656 * Updates device parameters according to the attribute list (caller is
1657 * responsible for holding the list lock).
1659 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1661 ALCcontext
*context
;
1662 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1663 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1664 enum DevFmtChannels oldChans
;
1665 enum DevFmtType oldType
;
1668 ALCsizei hrtf_id
= -1;
1671 // Check for attributes
1672 if(device
->Type
== Loopback
)
1678 GotAll
= GotFreq
|GotChans
|GotType
1680 ALCuint freq
, numMono
, numStereo
, numSends
;
1681 enum DevFmtChannels schans
;
1682 enum DevFmtType stype
;
1683 ALCuint attrIdx
= 0;
1688 WARN("Missing attributes for loopback device\n");
1689 return ALC_INVALID_VALUE
;
1692 numMono
= device
->NumMonoSources
;
1693 numStereo
= device
->NumStereoSources
;
1694 numSends
= device
->NumAuxSends
;
1695 schans
= device
->FmtChans
;
1696 stype
= device
->FmtType
;
1697 freq
= device
->Frequency
;
1699 while(attrList
[attrIdx
])
1701 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1703 ALCint val
= attrList
[attrIdx
+ 1];
1704 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1705 return ALC_INVALID_VALUE
;
1710 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1712 ALCint val
= attrList
[attrIdx
+ 1];
1713 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1714 return ALC_INVALID_VALUE
;
1719 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1721 freq
= attrList
[attrIdx
+ 1];
1722 if(freq
< MIN_OUTPUT_RATE
)
1723 return ALC_INVALID_VALUE
;
1727 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1729 numStereo
= attrList
[attrIdx
+ 1];
1730 if(numStereo
> device
->MaxNoOfSources
)
1731 numStereo
= device
->MaxNoOfSources
;
1733 numMono
= device
->MaxNoOfSources
- numStereo
;
1736 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1737 numSends
= attrList
[attrIdx
+ 1];
1739 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1741 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1742 hrtf_appreq
= Hrtf_Disable
;
1743 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1744 hrtf_appreq
= Hrtf_Enable
;
1746 hrtf_appreq
= Hrtf_Default
;
1749 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1750 hrtf_id
= attrList
[attrIdx
+ 1];
1755 if(gotFmt
!= GotAll
)
1757 WARN("Missing format for loopback device\n");
1758 return ALC_INVALID_VALUE
;
1761 ConfigValueUInt(NULL
, NULL
, "sends", &numSends
);
1762 numSends
= minu(MAX_SENDS
, numSends
);
1764 if((device
->Flags
&DEVICE_RUNNING
))
1765 V0(device
->Backend
,stop
)();
1766 device
->Flags
&= ~DEVICE_RUNNING
;
1768 UpdateClockBase(device
);
1770 device
->Frequency
= freq
;
1771 device
->FmtChans
= schans
;
1772 device
->FmtType
= stype
;
1773 device
->NumMonoSources
= numMono
;
1774 device
->NumStereoSources
= numStereo
;
1775 device
->NumAuxSends
= numSends
;
1777 else if(attrList
&& attrList
[0])
1779 ALCuint freq
, numMono
, numStereo
, numSends
;
1780 ALCuint attrIdx
= 0;
1782 /* If a context is already running on the device, stop playback so the
1783 * device attributes can be updated. */
1784 if((device
->Flags
&DEVICE_RUNNING
))
1785 V0(device
->Backend
,stop
)();
1786 device
->Flags
&= ~DEVICE_RUNNING
;
1788 freq
= device
->Frequency
;
1789 numMono
= device
->NumMonoSources
;
1790 numStereo
= device
->NumStereoSources
;
1791 numSends
= device
->NumAuxSends
;
1793 while(attrList
[attrIdx
])
1795 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1797 freq
= attrList
[attrIdx
+ 1];
1798 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1801 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1803 numStereo
= attrList
[attrIdx
+ 1];
1804 if(numStereo
> device
->MaxNoOfSources
)
1805 numStereo
= device
->MaxNoOfSources
;
1807 numMono
= device
->MaxNoOfSources
- numStereo
;
1810 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1811 numSends
= attrList
[attrIdx
+ 1];
1813 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1815 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1816 hrtf_appreq
= Hrtf_Disable
;
1817 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1818 hrtf_appreq
= Hrtf_Enable
;
1820 hrtf_appreq
= Hrtf_Default
;
1823 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1824 hrtf_id
= attrList
[attrIdx
+ 1];
1829 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1830 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1832 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1833 numSends
= minu(MAX_SENDS
, numSends
);
1835 UpdateClockBase(device
);
1837 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1839 /* SSE and Neon do best with the update size being a multiple of 4 */
1840 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1841 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1843 device
->Frequency
= freq
;
1844 device
->NumMonoSources
= numMono
;
1845 device
->NumStereoSources
= numStereo
;
1846 device
->NumAuxSends
= numSends
;
1849 if((device
->Flags
&DEVICE_RUNNING
))
1850 return ALC_NO_ERROR
;
1852 al_free(device
->Uhj_Encoder
);
1853 device
->Uhj_Encoder
= NULL
;
1855 al_free(device
->Bs2b
);
1856 device
->Bs2b
= NULL
;
1858 al_free(device
->Dry
.Buffer
);
1859 device
->Dry
.Buffer
= NULL
;
1860 device
->Dry
.NumChannels
= 0;
1861 device
->VirtOut
.Buffer
= NULL
;
1862 device
->VirtOut
.NumChannels
= 0;
1863 device
->RealOut
.Buffer
= NULL
;
1864 device
->RealOut
.NumChannels
= 0;
1866 UpdateClockBase(device
);
1868 device
->Hrtf_Status
= ALC_HRTF_DISABLED_SOFT
;
1869 if(device
->Type
!= Loopback
)
1872 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
1874 if(strcasecmp(hrtf
, "true") == 0)
1875 hrtf_userreq
= Hrtf_Enable
;
1876 else if(strcasecmp(hrtf
, "false") == 0)
1877 hrtf_userreq
= Hrtf_Disable
;
1878 else if(strcasecmp(hrtf
, "auto") != 0)
1879 ERR("Unexpected hrtf value: %s\n", hrtf
);
1882 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
1884 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1886 VECTOR_DEINIT(device
->Hrtf_List
);
1887 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1889 if(VECTOR_SIZE(device
->Hrtf_List
) > 0)
1891 device
->FmtChans
= DevFmtStereo
;
1892 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
1893 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
).hrtf
);
1895 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, 0).hrtf
);
1896 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
1900 hrtf_userreq
= hrtf_appreq
= Hrtf_Default
;
1901 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1905 else if(hrtf_appreq
== Hrtf_Enable
)
1908 /* Loopback device. We don't need to match to a specific HRTF entry
1909 * here. If the requested ID matches, we'll pick that later, if not,
1910 * we'll try to auto-select one anyway. */
1911 if(device
->FmtChans
!= DevFmtStereo
)
1912 i
= VECTOR_SIZE(device
->Hrtf_List
);
1915 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1917 VECTOR_DEINIT(device
->Hrtf_List
);
1918 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1920 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
1922 const struct Hrtf
*hrtf
= VECTOR_ELEM(device
->Hrtf_List
, i
).hrtf
;
1923 if(GetHrtfSampleRate(hrtf
) == device
->Frequency
)
1927 if(i
== VECTOR_SIZE(device
->Hrtf_List
))
1929 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1930 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1931 hrtf_appreq
= Hrtf_Default
;
1932 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1936 oldFreq
= device
->Frequency
;
1937 oldChans
= device
->FmtChans
;
1938 oldType
= device
->FmtType
;
1940 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1941 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1942 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1943 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1944 device
->UpdateSize
, device
->NumUpdates
1947 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1948 return ALC_INVALID_DEVICE
;
1950 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1952 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1953 DevFmtChannelsString(device
->FmtChans
));
1954 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1956 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1958 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1959 DevFmtTypeString(device
->FmtType
));
1960 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1962 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1964 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1965 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1968 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1969 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1970 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1973 if((device
->UpdateSize
&3) != 0)
1975 if((CPUCapFlags
&CPU_CAP_SSE
))
1976 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1977 if((CPUCapFlags
&CPU_CAP_NEON
))
1978 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1981 device
->Hrtf
= NULL
;
1982 al_string_clear(&device
->Hrtf_Name
);
1983 device
->Render_Mode
= NormalRender
;
1984 if(device
->FmtChans
!= DevFmtStereo
)
1986 if(hrtf_appreq
== Hrtf_Enable
)
1987 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1991 bool headphones
= device
->IsHeadphones
;
1992 enum RenderMode render_mode
= HrtfRender
;
1993 ALCenum hrtf_status
= device
->Hrtf_Status
;
1998 if(device
->Type
!= Loopback
)
2000 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "stereo-mode", &mode
))
2002 if(strcasecmp(mode
, "headphones") == 0)
2004 else if(strcasecmp(mode
, "speakers") == 0)
2006 else if(strcasecmp(mode
, "auto") != 0)
2007 ERR("Unexpected stereo-mode: %s\n", mode
);
2010 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf-mode", &mode
))
2012 if(strcasecmp(mode
, "full") == 0)
2013 render_mode
= HrtfRender
;
2014 else if(strcasecmp(mode
, "basic") == 0)
2015 render_mode
= NormalRender
;
2017 ERR("Unexpected hrtf-mode: %s\n", mode
);
2022 if(hrtf_userreq
== Hrtf_Default
)
2024 usehrtf
= (headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2025 (hrtf_appreq
== Hrtf_Enable
);
2026 if(headphones
&& hrtf_appreq
!= Hrtf_Disable
)
2027 hrtf_status
= ALC_HRTF_HEADPHONES_DETECTED_SOFT
;
2029 hrtf_status
= ALC_HRTF_ENABLED_SOFT
;
2033 usehrtf
= (hrtf_userreq
== Hrtf_Enable
);
2035 hrtf_status
= ALC_HRTF_DENIED_SOFT
;
2037 hrtf_status
= ALC_HRTF_REQUIRED_SOFT
;
2041 device
->Hrtf_Status
= hrtf_status
;
2046 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2047 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
2049 VECTOR_DEINIT(device
->Hrtf_List
);
2050 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2053 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
2055 const HrtfEntry
*entry
= &VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
);
2056 if(GetHrtfSampleRate(entry
->hrtf
) == device
->Frequency
)
2058 device
->Hrtf
= entry
->hrtf
;
2059 al_string_copy(&device
->Hrtf_Name
, entry
->name
);
2064 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
2066 const HrtfEntry
*entry
= &VECTOR_ELEM(device
->Hrtf_List
, i
);
2067 if(GetHrtfSampleRate(entry
->hrtf
) == device
->Frequency
)
2069 device
->Hrtf
= entry
->hrtf
;
2070 al_string_copy(&device
->Hrtf_Name
, entry
->name
);
2078 device
->Hrtf_Status
= hrtf_status
;
2079 device
->Render_Mode
= render_mode
;
2080 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device
->Hrtf_Name
));
2084 TRACE("HRTF disabled\n");
2086 bs2blevel
= ((headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2087 (hrtf_appreq
== Hrtf_Enable
)) ? 5 : 0;
2088 if(device
->Type
!= Loopback
)
2089 ConfigValueInt(al_string_get_cstr(device
->DeviceName
), NULL
, "cf_level", &bs2blevel
);
2090 if(bs2blevel
> 0 && bs2blevel
<= 6)
2092 device
->Bs2b
= al_calloc(16, sizeof(*device
->Bs2b
));
2093 bs2b_set_params(device
->Bs2b
, bs2blevel
, device
->Frequency
);
2094 device
->Render_Mode
= StereoPair
;
2095 TRACE("BS2B enabled\n");
2099 TRACE("BS2B disabled\n");
2101 render_mode
= NormalRender
;
2102 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "stereo-panning", &mode
))
2104 if(strcasecmp(mode
, "paired") == 0)
2105 render_mode
= StereoPair
;
2106 else if(strcasecmp(mode
, "uhj") != 0)
2107 ERR("Unexpected stereo-panning: %s\n", mode
);
2109 device
->Render_Mode
= render_mode
;
2110 if(render_mode
== NormalRender
)
2112 device
->Uhj_Encoder
= al_calloc(16, sizeof(Uhj2Encoder
));
2113 TRACE("UHJ enabled\n");
2116 TRACE("UHJ disabled\n");
2121 if(!device
->Hrtf
&& !device
->Uhj_Encoder
&&
2122 GetConfigValueBool(al_string_get_cstr(device
->DeviceName
), "ambisonics", "hq-mode", 1))
2124 if(!device
->AmbiDecoder
)
2125 device
->AmbiDecoder
= bformatdec_alloc();
2129 bformatdec_free(device
->AmbiDecoder
);
2130 device
->AmbiDecoder
= NULL
;
2132 aluInitPanning(device
);
2134 /* Allocate extra channels for any post-filter output. */
2135 size
= device
->Dry
.NumChannels
* sizeof(device
->Dry
.Buffer
[0]);
2136 if(device
->Hrtf
|| device
->Uhj_Encoder
|| device
->AmbiDecoder
)
2137 size
+= ChannelsFromDevFmt(device
->FmtChans
) * sizeof(device
->Dry
.Buffer
[0]);
2138 device
->Dry
.Buffer
= al_calloc(16, size
);
2139 if(!device
->Dry
.Buffer
)
2141 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2142 return ALC_INVALID_DEVICE
;
2145 if(device
->Hrtf
|| device
->Uhj_Encoder
|| device
->AmbiDecoder
)
2147 device
->VirtOut
.Buffer
= device
->Dry
.Buffer
;
2148 device
->VirtOut
.NumChannels
= device
->Dry
.NumChannels
;
2149 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2150 device
->RealOut
.NumChannels
= ChannelsFromDevFmt(device
->FmtChans
);
2154 device
->VirtOut
.Buffer
= NULL
;
2155 device
->VirtOut
.NumChannels
= 0;
2156 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2157 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2160 SetMixerFPUMode(&oldMode
);
2161 V0(device
->Backend
,lock
)();
2162 context
= ATOMIC_LOAD(&device
->ContextList
);
2167 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2168 LockUIntMapRead(&context
->EffectSlotMap
);
2169 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2171 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2173 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2175 UnlockUIntMapRead(&context
->EffectSlotMap
);
2176 V0(device
->Backend
,unlock
)();
2177 RestoreFPUMode(&oldMode
);
2178 return ALC_INVALID_DEVICE
;
2180 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2181 V(slot
->EffectState
,update
)(device
, slot
);
2183 UnlockUIntMapRead(&context
->EffectSlotMap
);
2185 LockUIntMapRead(&context
->SourceMap
);
2186 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2188 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2189 ALuint s
= device
->NumAuxSends
;
2190 while(s
< MAX_SENDS
)
2192 if(source
->Send
[s
].Slot
)
2193 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2194 source
->Send
[s
].Slot
= NULL
;
2195 source
->Send
[s
].Gain
= 1.0f
;
2196 source
->Send
[s
].GainHF
= 1.0f
;
2199 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2201 UnlockUIntMapRead(&context
->SourceMap
);
2203 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2205 ALvoice
*voice
= &context
->Voices
[pos
];
2206 ALsource
*source
= voice
->Source
;
2210 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2211 voice
->Update(voice
, source
, context
);
2215 context
= context
->next
;
2217 if(device
->DefaultSlot
)
2219 ALeffectslot
*slot
= device
->DefaultSlot
;
2221 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2223 V0(device
->Backend
,unlock
)();
2224 RestoreFPUMode(&oldMode
);
2225 return ALC_INVALID_DEVICE
;
2227 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2228 V(slot
->EffectState
,update
)(device
, slot
);
2230 V0(device
->Backend
,unlock
)();
2231 RestoreFPUMode(&oldMode
);
2233 if(!(device
->Flags
&DEVICE_PAUSED
))
2235 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2236 return ALC_INVALID_DEVICE
;
2237 device
->Flags
|= DEVICE_RUNNING
;
2240 return ALC_NO_ERROR
;
2245 * Frees the device structure, and destroys any objects the app failed to
2246 * delete. Called once there's no more references on the device.
2248 static ALCvoid
FreeDevice(ALCdevice
*device
)
2250 TRACE("%p\n", device
);
2252 V0(device
->Backend
,close
)();
2253 DELETE_OBJ(device
->Backend
);
2254 device
->Backend
= NULL
;
2256 if(device
->DefaultSlot
)
2258 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2259 device
->DefaultSlot
= NULL
;
2263 if(device
->BufferMap
.size
> 0)
2265 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2266 ReleaseALBuffers(device
);
2268 ResetUIntMap(&device
->BufferMap
);
2270 if(device
->EffectMap
.size
> 0)
2272 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2273 ReleaseALEffects(device
);
2275 ResetUIntMap(&device
->EffectMap
);
2277 if(device
->FilterMap
.size
> 0)
2279 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2280 ReleaseALFilters(device
);
2282 ResetUIntMap(&device
->FilterMap
);
2284 AL_STRING_DEINIT(device
->Hrtf_Name
);
2285 FreeHrtfList(&device
->Hrtf_List
);
2287 al_free(device
->Bs2b
);
2288 device
->Bs2b
= NULL
;
2290 al_free(device
->Uhj_Encoder
);
2291 device
->Uhj_Encoder
= NULL
;
2293 bformatdec_free(device
->AmbiDecoder
);
2294 device
->AmbiDecoder
= NULL
;
2296 AL_STRING_DEINIT(device
->DeviceName
);
2298 al_free(device
->Dry
.Buffer
);
2299 device
->Dry
.Buffer
= NULL
;
2300 device
->Dry
.NumChannels
= 0;
2301 device
->VirtOut
.Buffer
= NULL
;
2302 device
->VirtOut
.NumChannels
= 0;
2303 device
->RealOut
.Buffer
= NULL
;
2304 device
->RealOut
.NumChannels
= 0;
2310 void ALCdevice_IncRef(ALCdevice
*device
)
2313 ref
= IncrementRef(&device
->ref
);
2314 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2317 void ALCdevice_DecRef(ALCdevice
*device
)
2320 ref
= DecrementRef(&device
->ref
);
2321 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2322 if(ref
== 0) FreeDevice(device
);
2327 * Checks if the device handle is valid, and increments its ref count if so.
2329 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2331 ALCdevice
*tmpDevice
;
2334 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2337 if(tmpDevice
== *device
)
2339 ALCdevice_IncRef(tmpDevice
);
2343 tmpDevice
= tmpDevice
->next
;
2354 * Initializes context fields
2356 static ALvoid
InitContext(ALCcontext
*Context
)
2358 ALlistener
*listener
= Context
->Listener
;
2359 //Initialise listener
2360 listener
->Gain
= 1.0f
;
2361 listener
->MetersPerUnit
= 1.0f
;
2362 aluVectorSet(&listener
->Position
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
2363 aluVectorSet(&listener
->Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2364 listener
->Forward
[0] = 0.0f
;
2365 listener
->Forward
[1] = 0.0f
;
2366 listener
->Forward
[2] = -1.0f
;
2367 listener
->Up
[0] = 0.0f
;
2368 listener
->Up
[1] = 1.0f
;
2369 listener
->Up
[2] = 0.0f
;
2370 aluMatrixdSet(&listener
->Params
.Matrix
,
2376 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2379 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2380 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2381 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2382 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2385 Context
->DistanceModel
= DefaultDistanceModel
;
2386 Context
->SourceDistanceModel
= AL_FALSE
;
2387 Context
->DopplerFactor
= 1.0f
;
2388 Context
->DopplerVelocity
= 1.0f
;
2389 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2390 Context
->DeferUpdates
= AL_FALSE
;
2392 Context
->ExtensionList
= alExtList
;
2398 * Cleans up the context, and destroys any remaining objects the app failed to
2399 * delete. Called once there's no more references on the context.
2401 static void FreeContext(ALCcontext
*context
)
2403 TRACE("%p\n", context
);
2405 if(context
->SourceMap
.size
> 0)
2407 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2408 ReleaseALSources(context
);
2410 ResetUIntMap(&context
->SourceMap
);
2412 if(context
->EffectSlotMap
.size
> 0)
2414 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2415 ReleaseALAuxiliaryEffectSlots(context
);
2417 ResetUIntMap(&context
->EffectSlotMap
);
2419 al_free(context
->Voices
);
2420 context
->Voices
= NULL
;
2421 context
->VoiceCount
= 0;
2422 context
->MaxVoices
= 0;
2424 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2426 ALCdevice_DecRef(context
->Device
);
2427 context
->Device
= NULL
;
2429 //Invalidate context
2430 memset(context
, 0, sizeof(ALCcontext
));
2436 * Removes the context reference from the given device and removes it from
2437 * being current on the running thread or globally.
2439 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2441 ALCcontext
*nextctx
;
2442 ALCcontext
*origctx
;
2444 if(altss_get(LocalContext
) == context
)
2446 WARN("%p released while current on thread\n", context
);
2447 altss_set(LocalContext
, NULL
);
2448 ALCcontext_DecRef(context
);
2452 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2453 ALCcontext_DecRef(context
);
2455 ALCdevice_Lock(device
);
2457 nextctx
= context
->next
;
2458 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2464 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2466 ALCdevice_Unlock(device
);
2468 ALCcontext_DecRef(context
);
2471 void ALCcontext_IncRef(ALCcontext
*context
)
2474 ref
= IncrementRef(&context
->ref
);
2475 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2478 void ALCcontext_DecRef(ALCcontext
*context
)
2481 ref
= DecrementRef(&context
->ref
);
2482 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2483 if(ref
== 0) FreeContext(context
);
2486 static void ReleaseThreadCtx(void *ptr
)
2488 WARN("%p current for thread being destroyed\n", ptr
);
2489 ALCcontext_DecRef(ptr
);
2494 * Checks that the given context is valid, and increments its reference count.
2496 static ALCboolean
VerifyContext(ALCcontext
**context
)
2501 dev
= ATOMIC_LOAD(&DeviceList
);
2504 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2509 ALCcontext_IncRef(ctx
);
2526 * Returns the currently active context for this thread, and adds a reference
2527 * without locking it.
2529 ALCcontext
*GetContextRef(void)
2531 ALCcontext
*context
;
2533 context
= altss_get(LocalContext
);
2535 ALCcontext_IncRef(context
);
2539 context
= ATOMIC_LOAD(&GlobalContext
);
2541 ALCcontext_IncRef(context
);
2549 /************************************************
2550 * Standard ALC functions
2551 ************************************************/
2555 * Return last ALC generated error code for the given device
2557 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2561 if(VerifyDevice(&device
))
2563 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2564 ALCdevice_DecRef(device
);
2567 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2573 /* alcSuspendContext
2575 * Suspends updates for the given context
2577 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2582 if(!VerifyContext(&context
))
2583 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2586 ALCcontext_DeferUpdates(context
);
2587 ALCcontext_DecRef(context
);
2591 /* alcProcessContext
2593 * Resumes processing updates for the given context
2595 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2600 if(!VerifyContext(&context
))
2601 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2604 ALCcontext_ProcessUpdates(context
);
2605 ALCcontext_DecRef(context
);
2612 * Returns information about the device, and error strings
2614 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2616 const ALCchar
*value
= NULL
;
2624 case ALC_INVALID_ENUM
:
2625 value
= alcErrInvalidEnum
;
2628 case ALC_INVALID_VALUE
:
2629 value
= alcErrInvalidValue
;
2632 case ALC_INVALID_DEVICE
:
2633 value
= alcErrInvalidDevice
;
2636 case ALC_INVALID_CONTEXT
:
2637 value
= alcErrInvalidContext
;
2640 case ALC_OUT_OF_MEMORY
:
2641 value
= alcErrOutOfMemory
;
2644 case ALC_DEVICE_SPECIFIER
:
2645 value
= alcDefaultName
;
2648 case ALC_ALL_DEVICES_SPECIFIER
:
2649 if(VerifyDevice(&Device
))
2651 value
= al_string_get_cstr(Device
->DeviceName
);
2652 ALCdevice_DecRef(Device
);
2656 ProbeAllDevicesList();
2657 value
= al_string_get_cstr(alcAllDevicesList
);
2661 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2662 if(VerifyDevice(&Device
))
2664 value
= al_string_get_cstr(Device
->DeviceName
);
2665 ALCdevice_DecRef(Device
);
2669 ProbeCaptureDeviceList();
2670 value
= al_string_get_cstr(alcCaptureDeviceList
);
2674 /* Default devices are always first in the list */
2675 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2676 value
= alcDefaultName
;
2679 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2680 if(al_string_empty(alcAllDevicesList
))
2681 ProbeAllDevicesList();
2683 VerifyDevice(&Device
);
2685 free(alcDefaultAllDevicesSpecifier
);
2686 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2687 if(!alcDefaultAllDevicesSpecifier
)
2688 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2690 value
= alcDefaultAllDevicesSpecifier
;
2691 if(Device
) ALCdevice_DecRef(Device
);
2694 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2695 if(al_string_empty(alcCaptureDeviceList
))
2696 ProbeCaptureDeviceList();
2698 VerifyDevice(&Device
);
2700 free(alcCaptureDefaultDeviceSpecifier
);
2701 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2702 if(!alcCaptureDefaultDeviceSpecifier
)
2703 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2705 value
= alcCaptureDefaultDeviceSpecifier
;
2706 if(Device
) ALCdevice_DecRef(Device
);
2709 case ALC_EXTENSIONS
:
2710 if(!VerifyDevice(&Device
))
2711 value
= alcNoDeviceExtList
;
2714 value
= alcExtensionList
;
2715 ALCdevice_DecRef(Device
);
2719 case ALC_HRTF_SPECIFIER_SOFT
:
2720 if(!VerifyDevice(&Device
))
2721 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2725 value
= (Device
->Hrtf
? al_string_get_cstr(Device
->Hrtf_Name
) : "");
2727 ALCdevice_DecRef(Device
);
2732 VerifyDevice(&Device
);
2733 alcSetError(Device
, ALC_INVALID_ENUM
);
2734 if(Device
) ALCdevice_DecRef(Device
);
2742 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2746 if(size
<= 0 || values
== NULL
)
2748 alcSetError(device
, ALC_INVALID_VALUE
);
2756 case ALC_MAJOR_VERSION
:
2757 values
[0] = alcMajorVersion
;
2759 case ALC_MINOR_VERSION
:
2760 values
[0] = alcMinorVersion
;
2763 case ALC_ATTRIBUTES_SIZE
:
2764 case ALC_ALL_ATTRIBUTES
:
2768 case ALC_MONO_SOURCES
:
2769 case ALC_STEREO_SOURCES
:
2770 case ALC_CAPTURE_SAMPLES
:
2771 case ALC_FORMAT_CHANNELS_SOFT
:
2772 case ALC_FORMAT_TYPE_SOFT
:
2773 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2777 alcSetError(NULL
, ALC_INVALID_ENUM
);
2783 if(device
->Type
== Capture
)
2787 case ALC_CAPTURE_SAMPLES
:
2788 V0(device
->Backend
,lock
)();
2789 values
[0] = V0(device
->Backend
,availableSamples
)();
2790 V0(device
->Backend
,unlock
)();
2794 values
[0] = device
->Connected
;
2798 alcSetError(device
, ALC_INVALID_ENUM
);
2807 case ALC_MAJOR_VERSION
:
2808 values
[0] = alcMajorVersion
;
2811 case ALC_MINOR_VERSION
:
2812 values
[0] = alcMinorVersion
;
2815 case ALC_EFX_MAJOR_VERSION
:
2816 values
[0] = alcEFXMajorVersion
;
2819 case ALC_EFX_MINOR_VERSION
:
2820 values
[0] = alcEFXMinorVersion
;
2823 case ALC_ATTRIBUTES_SIZE
:
2827 case ALC_ALL_ATTRIBUTES
:
2830 alcSetError(device
, ALC_INVALID_VALUE
);
2835 values
[i
++] = ALC_FREQUENCY
;
2836 values
[i
++] = device
->Frequency
;
2838 if(device
->Type
!= Loopback
)
2840 values
[i
++] = ALC_REFRESH
;
2841 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2843 values
[i
++] = ALC_SYNC
;
2844 values
[i
++] = ALC_FALSE
;
2848 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2849 values
[i
++] = device
->FmtChans
;
2851 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2852 values
[i
++] = device
->FmtType
;
2855 values
[i
++] = ALC_MONO_SOURCES
;
2856 values
[i
++] = device
->NumMonoSources
;
2858 values
[i
++] = ALC_STEREO_SOURCES
;
2859 values
[i
++] = device
->NumStereoSources
;
2861 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2862 values
[i
++] = device
->NumAuxSends
;
2864 values
[i
++] = ALC_HRTF_SOFT
;
2865 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2867 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2868 values
[i
++] = device
->Hrtf_Status
;
2874 values
[0] = device
->Frequency
;
2878 if(device
->Type
== Loopback
)
2880 alcSetError(device
, ALC_INVALID_DEVICE
);
2883 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2887 if(device
->Type
== Loopback
)
2889 alcSetError(device
, ALC_INVALID_DEVICE
);
2892 values
[0] = ALC_FALSE
;
2895 case ALC_FORMAT_CHANNELS_SOFT
:
2896 if(device
->Type
!= Loopback
)
2898 alcSetError(device
, ALC_INVALID_DEVICE
);
2901 values
[0] = device
->FmtChans
;
2904 case ALC_FORMAT_TYPE_SOFT
:
2905 if(device
->Type
!= Loopback
)
2907 alcSetError(device
, ALC_INVALID_DEVICE
);
2910 values
[0] = device
->FmtType
;
2913 case ALC_MONO_SOURCES
:
2914 values
[0] = device
->NumMonoSources
;
2917 case ALC_STEREO_SOURCES
:
2918 values
[0] = device
->NumStereoSources
;
2921 case ALC_MAX_AUXILIARY_SENDS
:
2922 values
[0] = device
->NumAuxSends
;
2926 values
[0] = device
->Connected
;
2930 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2933 case ALC_HRTF_STATUS_SOFT
:
2934 values
[0] = device
->Hrtf_Status
;
2937 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
2938 FreeHrtfList(&device
->Hrtf_List
);
2939 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2940 values
[0] = (ALCint
)VECTOR_SIZE(device
->Hrtf_List
);
2944 alcSetError(device
, ALC_INVALID_ENUM
);
2952 * Returns information about the device and the version of OpenAL
2954 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2956 VerifyDevice(&device
);
2957 if(size
<= 0 || values
== NULL
)
2958 alcSetError(device
, ALC_INVALID_VALUE
);
2960 GetIntegerv(device
, param
, size
, values
);
2961 if(device
) ALCdevice_DecRef(device
);
2964 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2969 VerifyDevice(&device
);
2970 if(size
<= 0 || values
== NULL
)
2971 alcSetError(device
, ALC_INVALID_VALUE
);
2972 else if(!device
|| device
->Type
== Capture
)
2974 ivals
= malloc(size
* sizeof(ALCint
));
2975 size
= GetIntegerv(device
, pname
, size
, ivals
);
2976 for(i
= 0;i
< size
;i
++)
2977 values
[i
] = ivals
[i
];
2980 else /* render device */
2984 case ALC_ATTRIBUTES_SIZE
:
2988 case ALC_ALL_ATTRIBUTES
:
2990 alcSetError(device
, ALC_INVALID_VALUE
);
2995 V0(device
->Backend
,lock
)();
2996 values
[i
++] = ALC_FREQUENCY
;
2997 values
[i
++] = device
->Frequency
;
2999 if(device
->Type
!= Loopback
)
3001 values
[i
++] = ALC_REFRESH
;
3002 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
3004 values
[i
++] = ALC_SYNC
;
3005 values
[i
++] = ALC_FALSE
;
3009 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
3010 values
[i
++] = device
->FmtChans
;
3012 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
3013 values
[i
++] = device
->FmtType
;
3016 values
[i
++] = ALC_MONO_SOURCES
;
3017 values
[i
++] = device
->NumMonoSources
;
3019 values
[i
++] = ALC_STEREO_SOURCES
;
3020 values
[i
++] = device
->NumStereoSources
;
3022 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
3023 values
[i
++] = device
->NumAuxSends
;
3025 values
[i
++] = ALC_HRTF_SOFT
;
3026 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
3028 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
3029 values
[i
++] = device
->Hrtf_Status
;
3031 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
3032 values
[i
++] = device
->ClockBase
+
3033 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
3036 V0(device
->Backend
,unlock
)();
3040 case ALC_DEVICE_CLOCK_SOFT
:
3041 V0(device
->Backend
,lock
)();
3042 *values
= device
->ClockBase
+
3043 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
3044 V0(device
->Backend
,unlock
)();
3048 ivals
= malloc(size
* sizeof(ALCint
));
3049 size
= GetIntegerv(device
, pname
, size
, ivals
);
3050 for(i
= 0;i
< size
;i
++)
3051 values
[i
] = ivals
[i
];
3057 ALCdevice_DecRef(device
);
3061 /* alcIsExtensionPresent
3063 * Determines if there is support for a particular extension
3065 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3067 ALCboolean bResult
= ALC_FALSE
;
3069 VerifyDevice(&device
);
3072 alcSetError(device
, ALC_INVALID_VALUE
);
3075 size_t len
= strlen(extName
);
3076 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3079 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3080 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3085 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3089 } while(isspace(*ptr
));
3094 ALCdevice_DecRef(device
);
3099 /* alcGetProcAddress
3101 * Retrieves the function address for a particular extension function
3103 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3105 ALCvoid
*ptr
= NULL
;
3109 VerifyDevice(&device
);
3110 alcSetError(device
, ALC_INVALID_VALUE
);
3111 if(device
) ALCdevice_DecRef(device
);
3116 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3118 ptr
= alcFunctions
[i
].address
;
3127 * Get the value for a particular ALC enumeration name
3129 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3135 VerifyDevice(&device
);
3136 alcSetError(device
, ALC_INVALID_VALUE
);
3137 if(device
) ALCdevice_DecRef(device
);
3142 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3144 val
= enumeration
[i
].value
;
3153 * Create and attach a context to the given device.
3155 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3157 ALCcontext
*ALContext
;
3161 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3164 alcSetError(device
, ALC_INVALID_DEVICE
);
3165 if(device
) ALCdevice_DecRef(device
);
3169 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3171 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3174 alcSetError(device
, err
);
3175 if(err
== ALC_INVALID_DEVICE
)
3177 V0(device
->Backend
,lock
)();
3178 aluHandleDisconnect(device
);
3179 V0(device
->Backend
,unlock
)();
3181 ALCdevice_DecRef(device
);
3185 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3188 InitRef(&ALContext
->ref
, 1);
3189 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3191 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3193 ALContext
->VoiceCount
= 0;
3194 ALContext
->MaxVoices
= 256;
3195 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3197 if(!ALContext
|| !ALContext
->Voices
)
3199 if(!ATOMIC_LOAD(&device
->ContextList
))
3201 V0(device
->Backend
,stop
)();
3202 device
->Flags
&= ~DEVICE_RUNNING
;
3208 al_free(ALContext
->Voices
);
3209 ALContext
->Voices
= NULL
;
3211 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3217 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3218 ALCdevice_DecRef(device
);
3222 ALContext
->Device
= device
;
3223 ALCdevice_IncRef(device
);
3224 InitContext(ALContext
);
3227 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3229 ALContext
->next
= head
;
3230 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3234 ALCdevice_DecRef(device
);
3236 TRACE("Created context %p\n", ALContext
);
3240 /* alcDestroyContext
3242 * Remove a context from its device
3244 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3249 /* alcGetContextsDevice sets an error for invalid contexts */
3250 Device
= alcGetContextsDevice(context
);
3253 ReleaseContext(context
, Device
);
3254 if(!ATOMIC_LOAD(&Device
->ContextList
))
3256 V0(Device
->Backend
,stop
)();
3257 Device
->Flags
&= ~DEVICE_RUNNING
;
3264 /* alcGetCurrentContext
3266 * Returns the currently active context on the calling thread
3268 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3270 ALCcontext
*Context
= altss_get(LocalContext
);
3271 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3275 /* alcGetThreadContext
3277 * Returns the currently active thread-local context
3279 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3281 return altss_get(LocalContext
);
3285 /* alcMakeContextCurrent
3287 * Makes the given context the active process-wide context, and removes the
3288 * thread-local context for the calling thread.
3290 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3292 /* context must be valid or NULL */
3293 if(context
&& !VerifyContext(&context
))
3295 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3298 /* context's reference count is already incremented */
3299 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3300 if(context
) ALCcontext_DecRef(context
);
3302 if((context
=altss_get(LocalContext
)) != NULL
)
3304 altss_set(LocalContext
, NULL
);
3305 ALCcontext_DecRef(context
);
3311 /* alcSetThreadContext
3313 * Makes the given context the active context for the current thread
3315 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3319 /* context must be valid or NULL */
3320 if(context
&& !VerifyContext(&context
))
3322 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3325 /* context's reference count is already incremented */
3326 old
= altss_get(LocalContext
);
3327 altss_set(LocalContext
, context
);
3328 if(old
) ALCcontext_DecRef(old
);
3334 /* alcGetContextsDevice
3336 * Returns the device that a particular context is attached to
3338 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3342 if(!VerifyContext(&Context
))
3344 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3347 Device
= Context
->Device
;
3348 ALCcontext_DecRef(Context
);
3356 * Opens the named device.
3358 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3366 if(!PlaybackBackend
.name
)
3368 alcSetError(NULL
, ALC_INVALID_VALUE
);
3372 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3374 /* Some old Windows apps hardcode these expecting OpenAL to use a
3375 * specific audio API, even when they're not enumerated. Creative's
3376 * router effectively ignores them too.
3378 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3379 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3384 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3387 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3392 InitRef(&device
->ref
, 1);
3393 device
->Connected
= ALC_TRUE
;
3394 device
->Type
= Playback
;
3395 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3398 device
->Bs2b
= NULL
;
3399 device
->Uhj_Encoder
= NULL
;
3400 VECTOR_INIT(device
->Hrtf_List
);
3401 AL_STRING_INIT(device
->Hrtf_Name
);
3402 device
->Render_Mode
= NormalRender
;
3403 AL_STRING_INIT(device
->DeviceName
);
3404 device
->Dry
.Buffer
= NULL
;
3405 device
->Dry
.NumChannels
= 0;
3406 device
->VirtOut
.Buffer
= NULL
;
3407 device
->VirtOut
.NumChannels
= 0;
3408 device
->RealOut
.Buffer
= NULL
;
3409 device
->RealOut
.NumChannels
= 0;
3411 ATOMIC_INIT(&device
->ContextList
, NULL
);
3413 device
->ClockBase
= 0;
3414 device
->SamplesDone
= 0;
3416 device
->MaxNoOfSources
= 256;
3417 device
->AuxiliaryEffectSlotMax
= 4;
3418 device
->NumAuxSends
= MAX_SENDS
;
3420 InitUIntMap(&device
->BufferMap
, ~0);
3421 InitUIntMap(&device
->EffectMap
, ~0);
3422 InitUIntMap(&device
->FilterMap
, ~0);
3425 device
->FmtChans
= DevFmtChannelsDefault
;
3426 device
->FmtType
= DevFmtTypeDefault
;
3427 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3428 device
->IsHeadphones
= AL_FALSE
;
3429 device
->NumUpdates
= 4;
3430 device
->UpdateSize
= 1024;
3432 if(!PlaybackBackend
.getFactory
)
3433 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3434 ALCbackend_Playback
);
3437 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3438 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3440 if(!device
->Backend
)
3443 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3448 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3450 static const struct {
3451 const char name
[16];
3452 enum DevFmtChannels chans
;
3454 { "mono", DevFmtMono
},
3455 { "stereo", DevFmtStereo
},
3456 { "quad", DevFmtQuad
},
3457 { "surround51", DevFmtX51
},
3458 { "surround61", DevFmtX61
},
3459 { "surround71", DevFmtX71
},
3460 { "surround51rear", DevFmtX51Rear
},
3464 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3466 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3468 device
->FmtChans
= chanlist
[i
].chans
;
3469 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3473 if(i
== COUNTOF(chanlist
))
3474 ERR("Unsupported channels: %s\n", fmt
);
3476 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3478 static const struct {
3479 const char name
[16];
3480 enum DevFmtType type
;
3482 { "int8", DevFmtByte
},
3483 { "uint8", DevFmtUByte
},
3484 { "int16", DevFmtShort
},
3485 { "uint16", DevFmtUShort
},
3486 { "int32", DevFmtInt
},
3487 { "uint32", DevFmtUInt
},
3488 { "float32", DevFmtFloat
},
3492 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3494 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3496 device
->FmtType
= typelist
[i
].type
;
3497 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3501 if(i
== COUNTOF(typelist
))
3502 ERR("Unsupported sample-type: %s\n", fmt
);
3505 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3507 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3508 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3509 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3510 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3513 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3514 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3516 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3517 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3518 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3519 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3521 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->MaxNoOfSources
);
3522 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3524 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3525 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3527 ConfigValueUInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3528 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3530 device
->NumStereoSources
= 1;
3531 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3533 // Find a playback device to open
3534 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3536 DELETE_OBJ(device
->Backend
);
3538 alcSetError(NULL
, err
);
3542 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3544 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3545 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3547 device
->DefaultSlot
= NULL
;
3548 ERR("Failed to initialize the default effect slot\n");
3550 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3552 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3553 device
->DefaultSlot
= NULL
;
3555 ERR("Failed to initialize the default effect\n");
3558 aluInitEffectPanning(device
->DefaultSlot
);
3562 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3564 device
->next
= head
;
3565 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3568 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3574 * Closes the given device.
3576 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3578 ALCdevice
*list
, *origdev
, *nextdev
;
3582 list
= ATOMIC_LOAD(&DeviceList
);
3586 } while((list
=list
->next
) != NULL
);
3587 if(!list
|| list
->Type
== Capture
)
3589 alcSetError(list
, ALC_INVALID_DEVICE
);
3595 nextdev
= device
->next
;
3596 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3601 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3605 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3608 ALCcontext
*next
= ctx
->next
;
3609 WARN("Releasing context %p\n", ctx
);
3610 ReleaseContext(ctx
, device
);
3613 if((device
->Flags
&DEVICE_RUNNING
))
3614 V0(device
->Backend
,stop
)();
3615 device
->Flags
&= ~DEVICE_RUNNING
;
3617 ALCdevice_DecRef(device
);
3623 /************************************************
3624 * ALC capture functions
3625 ************************************************/
3626 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3628 ALCdevice
*device
= NULL
;
3633 if(!CaptureBackend
.name
)
3635 alcSetError(NULL
, ALC_INVALID_VALUE
);
3641 alcSetError(NULL
, ALC_INVALID_VALUE
);
3645 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3648 device
= al_calloc(16, sizeof(ALCdevice
));
3651 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3656 InitRef(&device
->ref
, 1);
3657 device
->Connected
= ALC_TRUE
;
3658 device
->Type
= Capture
;
3660 VECTOR_INIT(device
->Hrtf_List
);
3661 AL_STRING_INIT(device
->Hrtf_Name
);
3663 AL_STRING_INIT(device
->DeviceName
);
3664 device
->Dry
.Buffer
= NULL
;
3665 device
->Dry
.NumChannels
= 0;
3666 device
->VirtOut
.Buffer
= NULL
;
3667 device
->VirtOut
.NumChannels
= 0;
3668 device
->RealOut
.Buffer
= NULL
;
3669 device
->RealOut
.NumChannels
= 0;
3671 InitUIntMap(&device
->BufferMap
, ~0);
3672 InitUIntMap(&device
->EffectMap
, ~0);
3673 InitUIntMap(&device
->FilterMap
, ~0);
3675 if(!CaptureBackend
.getFactory
)
3676 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3677 ALCbackend_Capture
);
3680 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3681 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3683 if(!device
->Backend
)
3686 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3690 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3691 device
->Frequency
= frequency
;
3693 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3694 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3697 alcSetError(NULL
, ALC_INVALID_ENUM
);
3700 device
->IsHeadphones
= AL_FALSE
;
3702 device
->UpdateSize
= samples
;
3703 device
->NumUpdates
= 1;
3705 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3708 alcSetError(NULL
, err
);
3713 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3715 device
->next
= head
;
3716 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3719 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3723 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3725 ALCdevice
*list
, *next
, *nextdev
;
3728 list
= ATOMIC_LOAD(&DeviceList
);
3732 } while((list
=list
->next
) != NULL
);
3733 if(!list
|| list
->Type
!= Capture
)
3735 alcSetError(list
, ALC_INVALID_DEVICE
);
3741 nextdev
= device
->next
;
3742 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3747 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3751 ALCdevice_DecRef(device
);
3756 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3758 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3759 alcSetError(device
, ALC_INVALID_DEVICE
);
3762 V0(device
->Backend
,lock
)();
3763 if(!device
->Connected
)
3764 alcSetError(device
, ALC_INVALID_DEVICE
);
3765 else if(!(device
->Flags
&DEVICE_RUNNING
))
3767 if(V0(device
->Backend
,start
)())
3768 device
->Flags
|= DEVICE_RUNNING
;
3771 aluHandleDisconnect(device
);
3772 alcSetError(device
, ALC_INVALID_DEVICE
);
3775 V0(device
->Backend
,unlock
)();
3778 if(device
) ALCdevice_DecRef(device
);
3781 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3783 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3784 alcSetError(device
, ALC_INVALID_DEVICE
);
3787 V0(device
->Backend
,lock
)();
3788 if((device
->Flags
&DEVICE_RUNNING
))
3789 V0(device
->Backend
,stop
)();
3790 device
->Flags
&= ~DEVICE_RUNNING
;
3791 V0(device
->Backend
,unlock
)();
3794 if(device
) ALCdevice_DecRef(device
);
3797 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3799 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3800 alcSetError(device
, ALC_INVALID_DEVICE
);
3803 ALCenum err
= ALC_INVALID_VALUE
;
3805 V0(device
->Backend
,lock
)();
3806 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3807 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3808 V0(device
->Backend
,unlock
)();
3810 if(err
!= ALC_NO_ERROR
)
3811 alcSetError(device
, err
);
3813 if(device
) ALCdevice_DecRef(device
);
3817 /************************************************
3818 * ALC loopback functions
3819 ************************************************/
3821 /* alcLoopbackOpenDeviceSOFT
3823 * Open a loopback device, for manual rendering.
3825 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3827 ALCbackendFactory
*factory
;
3832 /* Make sure the device name, if specified, is us. */
3833 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3835 alcSetError(NULL
, ALC_INVALID_VALUE
);
3839 device
= al_calloc(16, sizeof(ALCdevice
));
3842 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3847 InitRef(&device
->ref
, 1);
3848 device
->Connected
= ALC_TRUE
;
3849 device
->Type
= Loopback
;
3850 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3853 VECTOR_INIT(device
->Hrtf_List
);
3854 AL_STRING_INIT(device
->Hrtf_Name
);
3855 device
->Bs2b
= NULL
;
3856 device
->Uhj_Encoder
= NULL
;
3857 device
->Render_Mode
= NormalRender
;
3858 AL_STRING_INIT(device
->DeviceName
);
3859 device
->Dry
.Buffer
= NULL
;
3860 device
->Dry
.NumChannels
= 0;
3861 device
->VirtOut
.Buffer
= NULL
;
3862 device
->VirtOut
.NumChannels
= 0;
3863 device
->RealOut
.Buffer
= NULL
;
3864 device
->RealOut
.NumChannels
= 0;
3866 ATOMIC_INIT(&device
->ContextList
, NULL
);
3868 device
->ClockBase
= 0;
3869 device
->SamplesDone
= 0;
3871 device
->MaxNoOfSources
= 256;
3872 device
->AuxiliaryEffectSlotMax
= 4;
3873 device
->NumAuxSends
= MAX_SENDS
;
3875 InitUIntMap(&device
->BufferMap
, ~0);
3876 InitUIntMap(&device
->EffectMap
, ~0);
3877 InitUIntMap(&device
->FilterMap
, ~0);
3879 factory
= ALCloopbackFactory_getFactory();
3880 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3881 if(!device
->Backend
)
3884 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3889 device
->NumUpdates
= 0;
3890 device
->UpdateSize
= 0;
3892 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3893 device
->FmtChans
= DevFmtChannelsDefault
;
3894 device
->FmtType
= DevFmtTypeDefault
;
3895 device
->IsHeadphones
= AL_FALSE
;
3897 ConfigValueUInt(NULL
, NULL
, "sources", &device
->MaxNoOfSources
);
3898 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3900 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3901 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3903 ConfigValueUInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
3904 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3906 device
->NumStereoSources
= 1;
3907 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3909 // Open the "backend"
3910 V(device
->Backend
,open
)("Loopback");
3913 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3915 device
->next
= head
;
3916 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3919 TRACE("Created device %p\n", device
);
3923 /* alcIsRenderFormatSupportedSOFT
3925 * Determines if the loopback device supports the given format for rendering.
3927 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3929 ALCboolean ret
= ALC_FALSE
;
3931 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3932 alcSetError(device
, ALC_INVALID_DEVICE
);
3934 alcSetError(device
, ALC_INVALID_VALUE
);
3937 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3938 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3939 freq
>= MIN_OUTPUT_RATE
)
3942 if(device
) ALCdevice_DecRef(device
);
3947 /* alcRenderSamplesSOFT
3949 * Renders some samples into a buffer, using the format last set by the
3950 * attributes given to alcCreateContext.
3952 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3954 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3955 alcSetError(device
, ALC_INVALID_DEVICE
);
3956 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3957 alcSetError(device
, ALC_INVALID_VALUE
);
3959 aluMixData(device
, buffer
, samples
);
3960 if(device
) ALCdevice_DecRef(device
);
3964 /************************************************
3965 * ALC DSP pause/resume functions
3966 ************************************************/
3968 /* alcDevicePauseSOFT
3970 * Pause the DSP to stop audio processing.
3972 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3974 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3975 alcSetError(device
, ALC_INVALID_DEVICE
);
3979 if((device
->Flags
&DEVICE_RUNNING
))
3980 V0(device
->Backend
,stop
)();
3981 device
->Flags
&= ~DEVICE_RUNNING
;
3982 device
->Flags
|= DEVICE_PAUSED
;
3985 if(device
) ALCdevice_DecRef(device
);
3988 /* alcDeviceResumeSOFT
3990 * Resume the DSP to restart audio processing.
3992 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3994 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3995 alcSetError(device
, ALC_INVALID_DEVICE
);
3999 if((device
->Flags
&DEVICE_PAUSED
))
4001 device
->Flags
&= ~DEVICE_PAUSED
;
4002 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
4004 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
4005 device
->Flags
|= DEVICE_RUNNING
;
4008 alcSetError(device
, ALC_INVALID_DEVICE
);
4009 V0(device
->Backend
,lock
)();
4010 aluHandleDisconnect(device
);
4011 V0(device
->Backend
,unlock
)();
4017 if(device
) ALCdevice_DecRef(device
);
4021 /************************************************
4022 * ALC HRTF functions
4023 ************************************************/
4025 /* alcGetStringiSOFT
4027 * Gets a string parameter at the given index.
4029 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
4031 const ALCchar
*str
= NULL
;
4033 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
4034 alcSetError(device
, ALC_INVALID_DEVICE
);
4035 else switch(paramName
)
4037 case ALC_HRTF_SPECIFIER_SOFT
:
4038 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->Hrtf_List
))
4039 str
= al_string_get_cstr(VECTOR_ELEM(device
->Hrtf_List
, index
).name
);
4041 alcSetError(device
, ALC_INVALID_VALUE
);
4045 alcSetError(device
, ALC_INVALID_ENUM
);
4048 if(device
) ALCdevice_DecRef(device
);
4053 /* alcResetDeviceSOFT
4055 * Resets the given device output, using the specified attribute list.
4057 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4062 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4065 alcSetError(device
, ALC_INVALID_DEVICE
);
4066 if(device
) ALCdevice_DecRef(device
);
4070 if((err
=UpdateDeviceParams(device
, attribs
)) != ALC_NO_ERROR
)
4073 alcSetError(device
, err
);
4074 if(err
== ALC_INVALID_DEVICE
)
4076 V0(device
->Backend
,lock
)();
4077 aluHandleDisconnect(device
);
4078 V0(device
->Backend
,unlock
)();
4080 ALCdevice_DecRef(device
);
4084 ALCdevice_DecRef(device
);