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"
45 #include "backends/base.h"
48 /************************************************
50 ************************************************/
53 ALCbackendFactory
* (*getFactory
)(void);
54 ALCboolean (*Init
)(BackendFuncs
*);
56 void (*Probe
)(enum DevProbe
);
60 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
61 static struct BackendInfo BackendList
[] = {
63 { "jack", ALCjackBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
65 #ifdef HAVE_PULSEAUDIO
66 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
69 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
72 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
75 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
78 { "solaris", ALCsolarisBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
81 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
84 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
87 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
90 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
93 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
96 { "port", ALCportBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
99 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
102 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
104 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
107 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
111 static struct BackendInfo PlaybackBackend
;
112 static struct BackendInfo CaptureBackend
;
115 /************************************************
116 * Functions, enums, and errors
117 ************************************************/
118 typedef struct ALCfunction
{
119 const ALCchar
*funcName
;
123 typedef struct ALCenums
{
124 const ALCchar
*enumName
;
128 #define DECL(x) { #x, (ALCvoid*)(x) }
129 static const ALCfunction alcFunctions
[] = {
130 DECL(alcCreateContext
),
131 DECL(alcMakeContextCurrent
),
132 DECL(alcProcessContext
),
133 DECL(alcSuspendContext
),
134 DECL(alcDestroyContext
),
135 DECL(alcGetCurrentContext
),
136 DECL(alcGetContextsDevice
),
138 DECL(alcCloseDevice
),
140 DECL(alcIsExtensionPresent
),
141 DECL(alcGetProcAddress
),
142 DECL(alcGetEnumValue
),
144 DECL(alcGetIntegerv
),
145 DECL(alcCaptureOpenDevice
),
146 DECL(alcCaptureCloseDevice
),
147 DECL(alcCaptureStart
),
148 DECL(alcCaptureStop
),
149 DECL(alcCaptureSamples
),
151 DECL(alcSetThreadContext
),
152 DECL(alcGetThreadContext
),
154 DECL(alcLoopbackOpenDeviceSOFT
),
155 DECL(alcIsRenderFormatSupportedSOFT
),
156 DECL(alcRenderSamplesSOFT
),
158 DECL(alcDevicePauseSOFT
),
159 DECL(alcDeviceResumeSOFT
),
161 DECL(alcGetStringiSOFT
),
162 DECL(alcResetDeviceSOFT
),
164 DECL(alcGetInteger64vSOFT
),
179 DECL(alIsExtensionPresent
),
180 DECL(alGetProcAddress
),
181 DECL(alGetEnumValue
),
188 DECL(alGetListenerf
),
189 DECL(alGetListener3f
),
190 DECL(alGetListenerfv
),
191 DECL(alGetListeneri
),
192 DECL(alGetListener3i
),
193 DECL(alGetListeneriv
),
195 DECL(alDeleteSources
),
211 DECL(alSourceRewindv
),
212 DECL(alSourcePausev
),
215 DECL(alSourceRewind
),
217 DECL(alSourceQueueBuffers
),
218 DECL(alSourceUnqueueBuffers
),
220 DECL(alDeleteBuffers
),
235 DECL(alDopplerFactor
),
236 DECL(alDopplerVelocity
),
237 DECL(alSpeedOfSound
),
238 DECL(alDistanceModel
),
241 DECL(alDeleteFilters
),
252 DECL(alDeleteEffects
),
262 DECL(alGenAuxiliaryEffectSlots
),
263 DECL(alDeleteAuxiliaryEffectSlots
),
264 DECL(alIsAuxiliaryEffectSlot
),
265 DECL(alAuxiliaryEffectSloti
),
266 DECL(alAuxiliaryEffectSlotiv
),
267 DECL(alAuxiliaryEffectSlotf
),
268 DECL(alAuxiliaryEffectSlotfv
),
269 DECL(alGetAuxiliaryEffectSloti
),
270 DECL(alGetAuxiliaryEffectSlotiv
),
271 DECL(alGetAuxiliaryEffectSlotf
),
272 DECL(alGetAuxiliaryEffectSlotfv
),
274 DECL(alBufferSubDataSOFT
),
276 DECL(alBufferSamplesSOFT
),
277 DECL(alBufferSubSamplesSOFT
),
278 DECL(alGetBufferSamplesSOFT
),
279 DECL(alIsBufferFormatSupportedSOFT
),
281 DECL(alDeferUpdatesSOFT
),
282 DECL(alProcessUpdatesSOFT
),
285 DECL(alSource3dSOFT
),
286 DECL(alSourcedvSOFT
),
287 DECL(alGetSourcedSOFT
),
288 DECL(alGetSource3dSOFT
),
289 DECL(alGetSourcedvSOFT
),
290 DECL(alSourcei64SOFT
),
291 DECL(alSource3i64SOFT
),
292 DECL(alSourcei64vSOFT
),
293 DECL(alGetSourcei64SOFT
),
294 DECL(alGetSource3i64SOFT
),
295 DECL(alGetSourcei64vSOFT
),
301 #define DECL(x) { #x, (x) }
302 static const ALCenums enumeration
[] = {
307 DECL(ALC_MAJOR_VERSION
),
308 DECL(ALC_MINOR_VERSION
),
309 DECL(ALC_ATTRIBUTES_SIZE
),
310 DECL(ALC_ALL_ATTRIBUTES
),
311 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
312 DECL(ALC_DEVICE_SPECIFIER
),
313 DECL(ALC_ALL_DEVICES_SPECIFIER
),
314 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
315 DECL(ALC_EXTENSIONS
),
319 DECL(ALC_MONO_SOURCES
),
320 DECL(ALC_STEREO_SOURCES
),
321 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
322 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
323 DECL(ALC_CAPTURE_SAMPLES
),
326 DECL(ALC_EFX_MAJOR_VERSION
),
327 DECL(ALC_EFX_MINOR_VERSION
),
328 DECL(ALC_MAX_AUXILIARY_SENDS
),
330 DECL(ALC_FORMAT_CHANNELS_SOFT
),
331 DECL(ALC_FORMAT_TYPE_SOFT
),
334 DECL(ALC_STEREO_SOFT
),
336 DECL(ALC_5POINT1_SOFT
),
337 DECL(ALC_6POINT1_SOFT
),
338 DECL(ALC_7POINT1_SOFT
),
341 DECL(ALC_UNSIGNED_BYTE_SOFT
),
342 DECL(ALC_SHORT_SOFT
),
343 DECL(ALC_UNSIGNED_SHORT_SOFT
),
345 DECL(ALC_UNSIGNED_INT_SOFT
),
346 DECL(ALC_FLOAT_SOFT
),
349 DECL(ALC_DONT_CARE_SOFT
),
350 DECL(ALC_HRTF_STATUS_SOFT
),
351 DECL(ALC_HRTF_DISABLED_SOFT
),
352 DECL(ALC_HRTF_ENABLED_SOFT
),
353 DECL(ALC_HRTF_DENIED_SOFT
),
354 DECL(ALC_HRTF_REQUIRED_SOFT
),
355 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
356 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
357 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
358 DECL(ALC_HRTF_SPECIFIER_SOFT
),
359 DECL(ALC_HRTF_ID_SOFT
),
362 DECL(ALC_INVALID_DEVICE
),
363 DECL(ALC_INVALID_CONTEXT
),
364 DECL(ALC_INVALID_ENUM
),
365 DECL(ALC_INVALID_VALUE
),
366 DECL(ALC_OUT_OF_MEMORY
),
374 DECL(AL_SOURCE_RELATIVE
),
375 DECL(AL_CONE_INNER_ANGLE
),
376 DECL(AL_CONE_OUTER_ANGLE
),
386 DECL(AL_ORIENTATION
),
387 DECL(AL_REFERENCE_DISTANCE
),
388 DECL(AL_ROLLOFF_FACTOR
),
389 DECL(AL_CONE_OUTER_GAIN
),
390 DECL(AL_MAX_DISTANCE
),
392 DECL(AL_SAMPLE_OFFSET
),
393 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
394 DECL(AL_BYTE_OFFSET
),
395 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
396 DECL(AL_SOURCE_TYPE
),
399 DECL(AL_UNDETERMINED
),
400 DECL(AL_METERS_PER_UNIT
),
401 DECL(AL_LOOP_POINTS_SOFT
),
402 DECL(AL_DIRECT_CHANNELS_SOFT
),
404 DECL(AL_DIRECT_FILTER
),
405 DECL(AL_AUXILIARY_SEND_FILTER
),
406 DECL(AL_AIR_ABSORPTION_FACTOR
),
407 DECL(AL_ROOM_ROLLOFF_FACTOR
),
408 DECL(AL_CONE_OUTER_GAINHF
),
409 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
410 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
413 DECL(AL_SOURCE_STATE
),
419 DECL(AL_BUFFERS_QUEUED
),
420 DECL(AL_BUFFERS_PROCESSED
),
422 DECL(AL_FORMAT_MONO8
),
423 DECL(AL_FORMAT_MONO16
),
424 DECL(AL_FORMAT_MONO_FLOAT32
),
425 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
426 DECL(AL_FORMAT_STEREO8
),
427 DECL(AL_FORMAT_STEREO16
),
428 DECL(AL_FORMAT_STEREO_FLOAT32
),
429 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
430 DECL(AL_FORMAT_MONO_IMA4
),
431 DECL(AL_FORMAT_STEREO_IMA4
),
432 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
433 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
434 DECL(AL_FORMAT_QUAD8_LOKI
),
435 DECL(AL_FORMAT_QUAD16_LOKI
),
436 DECL(AL_FORMAT_QUAD8
),
437 DECL(AL_FORMAT_QUAD16
),
438 DECL(AL_FORMAT_QUAD32
),
439 DECL(AL_FORMAT_51CHN8
),
440 DECL(AL_FORMAT_51CHN16
),
441 DECL(AL_FORMAT_51CHN32
),
442 DECL(AL_FORMAT_61CHN8
),
443 DECL(AL_FORMAT_61CHN16
),
444 DECL(AL_FORMAT_61CHN32
),
445 DECL(AL_FORMAT_71CHN8
),
446 DECL(AL_FORMAT_71CHN16
),
447 DECL(AL_FORMAT_71CHN32
),
448 DECL(AL_FORMAT_REAR8
),
449 DECL(AL_FORMAT_REAR16
),
450 DECL(AL_FORMAT_REAR32
),
451 DECL(AL_FORMAT_MONO_MULAW
),
452 DECL(AL_FORMAT_MONO_MULAW_EXT
),
453 DECL(AL_FORMAT_STEREO_MULAW
),
454 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
455 DECL(AL_FORMAT_QUAD_MULAW
),
456 DECL(AL_FORMAT_51CHN_MULAW
),
457 DECL(AL_FORMAT_61CHN_MULAW
),
458 DECL(AL_FORMAT_71CHN_MULAW
),
459 DECL(AL_FORMAT_REAR_MULAW
),
460 DECL(AL_FORMAT_MONO_ALAW_EXT
),
461 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
464 DECL(AL_MONO16_SOFT
),
465 DECL(AL_MONO32F_SOFT
),
466 DECL(AL_STEREO8_SOFT
),
467 DECL(AL_STEREO16_SOFT
),
468 DECL(AL_STEREO32F_SOFT
),
470 DECL(AL_QUAD16_SOFT
),
471 DECL(AL_QUAD32F_SOFT
),
473 DECL(AL_REAR16_SOFT
),
474 DECL(AL_REAR32F_SOFT
),
475 DECL(AL_5POINT1_8_SOFT
),
476 DECL(AL_5POINT1_16_SOFT
),
477 DECL(AL_5POINT1_32F_SOFT
),
478 DECL(AL_6POINT1_8_SOFT
),
479 DECL(AL_6POINT1_16_SOFT
),
480 DECL(AL_6POINT1_32F_SOFT
),
481 DECL(AL_7POINT1_8_SOFT
),
482 DECL(AL_7POINT1_16_SOFT
),
483 DECL(AL_7POINT1_32F_SOFT
),
484 DECL(AL_FORMAT_BFORMAT2D_8
),
485 DECL(AL_FORMAT_BFORMAT2D_16
),
486 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
487 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
488 DECL(AL_FORMAT_BFORMAT3D_8
),
489 DECL(AL_FORMAT_BFORMAT3D_16
),
490 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
491 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
494 DECL(AL_STEREO_SOFT
),
497 DECL(AL_5POINT1_SOFT
),
498 DECL(AL_6POINT1_SOFT
),
499 DECL(AL_7POINT1_SOFT
),
502 DECL(AL_UNSIGNED_BYTE_SOFT
),
504 DECL(AL_UNSIGNED_SHORT_SOFT
),
506 DECL(AL_UNSIGNED_INT_SOFT
),
508 DECL(AL_DOUBLE_SOFT
),
510 DECL(AL_UNSIGNED_BYTE3_SOFT
),
516 DECL(AL_INTERNAL_FORMAT_SOFT
),
517 DECL(AL_BYTE_LENGTH_SOFT
),
518 DECL(AL_SAMPLE_LENGTH_SOFT
),
519 DECL(AL_SEC_LENGTH_SOFT
),
520 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
521 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
528 DECL(AL_INVALID_NAME
),
529 DECL(AL_INVALID_ENUM
),
530 DECL(AL_INVALID_VALUE
),
531 DECL(AL_INVALID_OPERATION
),
532 DECL(AL_OUT_OF_MEMORY
),
539 DECL(AL_DOPPLER_FACTOR
),
540 DECL(AL_DOPPLER_VELOCITY
),
541 DECL(AL_DISTANCE_MODEL
),
542 DECL(AL_SPEED_OF_SOUND
),
543 DECL(AL_SOURCE_DISTANCE_MODEL
),
544 DECL(AL_DEFERRED_UPDATES_SOFT
),
546 DECL(AL_INVERSE_DISTANCE
),
547 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
548 DECL(AL_LINEAR_DISTANCE
),
549 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
550 DECL(AL_EXPONENT_DISTANCE
),
551 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
553 DECL(AL_FILTER_TYPE
),
554 DECL(AL_FILTER_NULL
),
555 DECL(AL_FILTER_LOWPASS
),
556 DECL(AL_FILTER_HIGHPASS
),
557 DECL(AL_FILTER_BANDPASS
),
559 DECL(AL_LOWPASS_GAIN
),
560 DECL(AL_LOWPASS_GAINHF
),
562 DECL(AL_HIGHPASS_GAIN
),
563 DECL(AL_HIGHPASS_GAINLF
),
565 DECL(AL_BANDPASS_GAIN
),
566 DECL(AL_BANDPASS_GAINHF
),
567 DECL(AL_BANDPASS_GAINLF
),
569 DECL(AL_EFFECT_TYPE
),
570 DECL(AL_EFFECT_NULL
),
571 DECL(AL_EFFECT_REVERB
),
572 DECL(AL_EFFECT_EAXREVERB
),
573 DECL(AL_EFFECT_CHORUS
),
574 DECL(AL_EFFECT_DISTORTION
),
575 DECL(AL_EFFECT_ECHO
),
576 DECL(AL_EFFECT_FLANGER
),
578 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
579 DECL(AL_EFFECT_VOCAL_MORPHER
),
580 DECL(AL_EFFECT_PITCH_SHIFTER
),
582 DECL(AL_EFFECT_RING_MODULATOR
),
584 DECL(AL_EFFECT_AUTOWAH
),
586 DECL(AL_EFFECT_COMPRESSOR
),
587 DECL(AL_EFFECT_EQUALIZER
),
588 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
589 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
591 DECL(AL_EAXREVERB_DENSITY
),
592 DECL(AL_EAXREVERB_DIFFUSION
),
593 DECL(AL_EAXREVERB_GAIN
),
594 DECL(AL_EAXREVERB_GAINHF
),
595 DECL(AL_EAXREVERB_GAINLF
),
596 DECL(AL_EAXREVERB_DECAY_TIME
),
597 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
598 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
599 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
600 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
601 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
602 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
603 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
604 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
605 DECL(AL_EAXREVERB_ECHO_TIME
),
606 DECL(AL_EAXREVERB_ECHO_DEPTH
),
607 DECL(AL_EAXREVERB_MODULATION_TIME
),
608 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
609 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
610 DECL(AL_EAXREVERB_HFREFERENCE
),
611 DECL(AL_EAXREVERB_LFREFERENCE
),
612 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
613 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
615 DECL(AL_REVERB_DENSITY
),
616 DECL(AL_REVERB_DIFFUSION
),
617 DECL(AL_REVERB_GAIN
),
618 DECL(AL_REVERB_GAINHF
),
619 DECL(AL_REVERB_DECAY_TIME
),
620 DECL(AL_REVERB_DECAY_HFRATIO
),
621 DECL(AL_REVERB_REFLECTIONS_GAIN
),
622 DECL(AL_REVERB_REFLECTIONS_DELAY
),
623 DECL(AL_REVERB_LATE_REVERB_GAIN
),
624 DECL(AL_REVERB_LATE_REVERB_DELAY
),
625 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
626 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
627 DECL(AL_REVERB_DECAY_HFLIMIT
),
629 DECL(AL_CHORUS_WAVEFORM
),
630 DECL(AL_CHORUS_PHASE
),
631 DECL(AL_CHORUS_RATE
),
632 DECL(AL_CHORUS_DEPTH
),
633 DECL(AL_CHORUS_FEEDBACK
),
634 DECL(AL_CHORUS_DELAY
),
636 DECL(AL_DISTORTION_EDGE
),
637 DECL(AL_DISTORTION_GAIN
),
638 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
639 DECL(AL_DISTORTION_EQCENTER
),
640 DECL(AL_DISTORTION_EQBANDWIDTH
),
643 DECL(AL_ECHO_LRDELAY
),
644 DECL(AL_ECHO_DAMPING
),
645 DECL(AL_ECHO_FEEDBACK
),
646 DECL(AL_ECHO_SPREAD
),
648 DECL(AL_FLANGER_WAVEFORM
),
649 DECL(AL_FLANGER_PHASE
),
650 DECL(AL_FLANGER_RATE
),
651 DECL(AL_FLANGER_DEPTH
),
652 DECL(AL_FLANGER_FEEDBACK
),
653 DECL(AL_FLANGER_DELAY
),
655 DECL(AL_RING_MODULATOR_FREQUENCY
),
656 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
657 DECL(AL_RING_MODULATOR_WAVEFORM
),
660 DECL(AL_AUTOWAH_ATTACK_TIME
),
661 DECL(AL_AUTOWAH_PEAK_GAIN
),
662 DECL(AL_AUTOWAH_RELEASE_TIME
),
663 DECL(AL_AUTOWAH_RESONANCE
),
666 DECL(AL_COMPRESSOR_ONOFF
),
668 DECL(AL_EQUALIZER_LOW_GAIN
),
669 DECL(AL_EQUALIZER_LOW_CUTOFF
),
670 DECL(AL_EQUALIZER_MID1_GAIN
),
671 DECL(AL_EQUALIZER_MID1_CENTER
),
672 DECL(AL_EQUALIZER_MID1_WIDTH
),
673 DECL(AL_EQUALIZER_MID2_GAIN
),
674 DECL(AL_EQUALIZER_MID2_CENTER
),
675 DECL(AL_EQUALIZER_MID2_WIDTH
),
676 DECL(AL_EQUALIZER_HIGH_GAIN
),
677 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
679 DECL(AL_DEDICATED_GAIN
),
685 static const ALCchar alcNoError
[] = "No Error";
686 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
687 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
688 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
689 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
690 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
693 /************************************************
695 ************************************************/
697 /* Enumerated device names */
698 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
700 static al_string alcAllDevicesList
;
701 static al_string alcCaptureDeviceList
;
703 /* Default is always the first in the list */
704 static ALCchar
*alcDefaultAllDevicesSpecifier
;
705 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
707 /* Default context extensions */
708 static const ALchar alExtList
[] =
709 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
710 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
711 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
712 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
713 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
714 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
715 "AL_SOFT_source_latency AL_SOFT_source_length";
717 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
719 /* Thread-local current context */
720 static altss_t LocalContext
;
721 /* Process-wide current context */
722 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
724 /* Mixing thread piority level */
729 enum LogLevel LogLevel
= LogWarning
;
731 enum LogLevel LogLevel
= LogError
;
734 /* Flag to trap ALC device errors */
735 static ALCboolean TrapALCError
= ALC_FALSE
;
737 /* One-time configuration init control */
738 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
740 /* Default effect that applies to sources that don't have an effect on send 0 */
741 static ALeffect DefaultEffect
;
743 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
746 static ALCboolean SuspendDefers
= ALC_TRUE
;
749 /************************************************
751 ************************************************/
752 static const ALCchar alcNoDeviceExtList
[] =
753 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
754 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
755 static const ALCchar alcExtensionList
[] =
756 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
757 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
758 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
759 "ALC_SOFT_loopback ALC_SOFT_pause_device";
760 static const ALCint alcMajorVersion
= 1;
761 static const ALCint alcMinorVersion
= 1;
763 static const ALCint alcEFXMajorVersion
= 1;
764 static const ALCint alcEFXMinorVersion
= 0;
767 /************************************************
769 ************************************************/
770 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
772 static almtx_t ListLock
;
773 static inline void LockLists(void)
775 int lockret
= almtx_lock(&ListLock
);
776 assert(lockret
== althrd_success
);
778 static inline void UnlockLists(void)
780 int unlockret
= almtx_unlock(&ListLock
);
781 assert(unlockret
== althrd_success
);
784 /************************************************
785 * Library initialization
786 ************************************************/
788 static void alc_init(void);
789 static void alc_deinit(void);
790 static void alc_deinit_safe(void);
792 #ifndef AL_LIBTYPE_STATIC
793 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
797 case DLL_PROCESS_ATTACH
:
798 /* Pin the DLL so we won't get unloaded until the process terminates */
799 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
800 (WCHAR
*)hModule
, &hModule
);
804 case DLL_THREAD_DETACH
:
807 case DLL_PROCESS_DETACH
:
816 #elif defined(_MSC_VER)
817 #pragma section(".CRT$XCU",read)
818 static void alc_constructor(void);
819 static void alc_destructor(void);
820 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
822 static void alc_constructor(void)
824 atexit(alc_destructor
);
828 static void alc_destructor(void)
832 #elif defined(HAVE_GCC_DESTRUCTOR)
833 static void alc_init(void) __attribute__((constructor
));
834 static void alc_deinit(void) __attribute__((destructor
));
836 #error "No static initialization available on this platform!"
839 #elif defined(HAVE_GCC_DESTRUCTOR)
841 static void alc_init(void) __attribute__((constructor
));
842 static void alc_deinit(void) __attribute__((destructor
));
845 #error "No global initialization available on this platform!"
848 static void ReleaseThreadCtx(void *ptr
);
849 static void alc_init(void)
856 AL_STRING_INIT(alcAllDevicesList
);
857 AL_STRING_INIT(alcCaptureDeviceList
);
859 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
860 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
863 str
= getenv("__ALSOFT_REVERSE_Z");
864 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
867 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
868 assert(ret
== althrd_success
);
870 ret
= almtx_init(&ListLock
, almtx_recursive
);
871 assert(ret
== althrd_success
);
876 static void alc_initconfig(void)
878 const char *devs
, *str
;
883 str
= getenv("ALSOFT_LOGLEVEL");
886 long lvl
= strtol(str
, NULL
, 0);
887 if(lvl
>= NoLog
&& lvl
<= LogRef
)
891 str
= getenv("ALSOFT_LOGFILE");
894 FILE *logfile
= al_fopen(str
, "wt");
895 if(logfile
) LogFile
= logfile
;
896 else ERR("Failed to open log file '%s'\n", str
);
901 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
902 for(i
= 1;BackendList
[i
].name
;i
++)
903 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
904 TRACE("Supported backends: %s\n", buf
);
908 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
911 if(strcasecmp(str
, "ignore") == 0)
913 SuspendDefers
= ALC_FALSE
;
914 TRACE("Selected context suspend behavior, \"ignore\"\n");
917 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
921 #if defined(HAVE_SSE4_1)
922 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
923 #elif defined(HAVE_SSE3)
924 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
925 #elif defined(HAVE_SSE2)
926 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
927 #elif defined(HAVE_SSE)
928 capfilter
|= CPU_CAP_SSE
;
931 capfilter
|= CPU_CAP_NEON
;
933 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
935 if(strcasecmp(str
, "all") == 0)
940 const char *next
= str
;
944 while(isspace(str
[0]))
946 next
= strchr(str
, ',');
948 if(!str
[0] || str
[0] == ',')
951 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
952 while(len
> 0 && isspace(str
[len
-1]))
954 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
955 capfilter
&= ~CPU_CAP_SSE
;
956 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
957 capfilter
&= ~CPU_CAP_SSE2
;
958 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
959 capfilter
&= ~CPU_CAP_SSE3
;
960 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
961 capfilter
&= ~CPU_CAP_SSE4_1
;
962 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
963 capfilter
&= ~CPU_CAP_NEON
;
965 WARN("Invalid CPU extension \"%s\"\n", str
);
969 FillCPUCaps(capfilter
);
976 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
980 str
= getenv("ALSOFT_TRAP_ERROR");
981 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
983 TrapALError
= AL_TRUE
;
984 TrapALCError
= AL_TRUE
;
988 str
= getenv("ALSOFT_TRAP_AL_ERROR");
989 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
990 TrapALError
= AL_TRUE
;
991 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
993 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
994 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
995 TrapALCError
= ALC_TRUE
;
996 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
999 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1000 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1002 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1004 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1005 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1009 const char *next
= devs
;
1010 int endlist
, delitem
;
1015 while(isspace(devs
[0]))
1017 next
= strchr(devs
, ',');
1019 delitem
= (devs
[0] == '-');
1020 if(devs
[0] == '-') devs
++;
1022 if(!devs
[0] || devs
[0] == ',')
1029 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1030 while(len
> 0 && isspace(devs
[len
-1]))
1032 for(n
= i
;BackendList
[n
].name
;n
++)
1034 if(len
== strlen(BackendList
[n
].name
) &&
1035 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1040 BackendList
[n
] = BackendList
[n
+1];
1042 } while(BackendList
[n
].name
);
1046 struct BackendInfo Bkp
= BackendList
[n
];
1049 BackendList
[n
] = BackendList
[n
-1];
1052 BackendList
[n
] = Bkp
;
1063 BackendList
[i
].name
= NULL
;
1064 BackendList
[i
].getFactory
= NULL
;
1065 BackendList
[i
].Init
= NULL
;
1066 BackendList
[i
].Deinit
= NULL
;
1067 BackendList
[i
].Probe
= NULL
;
1071 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1073 if(BackendList
[i
].getFactory
)
1075 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1076 if(!V0(factory
,init
)())
1078 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1082 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1083 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1085 PlaybackBackend
= BackendList
[i
];
1086 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1088 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1090 CaptureBackend
= BackendList
[i
];
1091 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1097 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1099 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1103 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1104 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1106 PlaybackBackend
= BackendList
[i
];
1107 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1109 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1111 CaptureBackend
= BackendList
[i
];
1112 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1116 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1120 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1123 const char *next
= str
;
1127 next
= strchr(str
, ',');
1129 if(!str
[0] || next
== str
)
1132 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1133 for(n
= 0;EffectList
[n
].name
;n
++)
1135 if(len
== strlen(EffectList
[n
].name
) &&
1136 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1137 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1142 InitEffectFactoryMap();
1144 InitEffect(&DefaultEffect
);
1145 str
= getenv("ALSOFT_DEFAULT_REVERB");
1146 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1147 LoadReverbPreset(str
, &DefaultEffect
);
1149 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1152 /************************************************
1153 * Library deinitialization
1154 ************************************************/
1155 static void alc_cleanup(void)
1159 AL_STRING_DEINIT(alcAllDevicesList
);
1160 AL_STRING_DEINIT(alcCaptureDeviceList
);
1162 free(alcDefaultAllDevicesSpecifier
);
1163 alcDefaultAllDevicesSpecifier
= NULL
;
1164 free(alcCaptureDefaultDeviceSpecifier
);
1165 alcCaptureDefaultDeviceSpecifier
= NULL
;
1167 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1172 } while((dev
=dev
->next
) != NULL
);
1173 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1176 DeinitEffectFactoryMap();
1179 static void alc_deinit_safe(void)
1187 almtx_destroy(&ListLock
);
1188 altss_delete(LocalContext
);
1190 if(LogFile
!= stderr
)
1195 static void alc_deinit(void)
1201 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1202 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1204 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1206 if(!BackendList
[i
].getFactory
)
1207 BackendList
[i
].Deinit();
1210 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1211 V0(factory
,deinit
)();
1215 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1216 V0(factory
,deinit
)();
1223 /************************************************
1224 * Device enumeration
1225 ************************************************/
1226 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1231 al_string_clear(list
);
1233 if(!backendinfo
->getFactory
)
1234 backendinfo
->Probe(type
);
1237 ALCbackendFactory
*factory
= backendinfo
->getFactory();
1238 V(factory
,probe
)(type
);
1243 static void ProbeAllDevicesList(void)
1244 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1245 static void ProbeCaptureDeviceList(void)
1246 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1248 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1250 size_t len
= strlen(name
);
1252 al_string_append_range(devnames
, name
, name
+len
+1);
1254 void AppendAllDevicesList(const ALCchar
*name
)
1255 { AppendDevice(name
, &alcAllDevicesList
); }
1256 void AppendCaptureDeviceList(const ALCchar
*name
)
1257 { AppendDevice(name
, &alcCaptureDeviceList
); }
1260 /************************************************
1261 * Device format information
1262 ************************************************/
1263 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1267 case DevFmtByte
: return "Signed Byte";
1268 case DevFmtUByte
: return "Unsigned Byte";
1269 case DevFmtShort
: return "Signed Short";
1270 case DevFmtUShort
: return "Unsigned Short";
1271 case DevFmtInt
: return "Signed Int";
1272 case DevFmtUInt
: return "Unsigned Int";
1273 case DevFmtFloat
: return "Float";
1275 return "(unknown type)";
1277 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1281 case DevFmtMono
: return "Mono";
1282 case DevFmtStereo
: return "Stereo";
1283 case DevFmtQuad
: return "Quadraphonic";
1284 case DevFmtX51
: return "5.1 Surround";
1285 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1286 case DevFmtX61
: return "6.1 Surround";
1287 case DevFmtX71
: return "7.1 Surround";
1288 case DevFmtBFormat3D
: return "B-Format 3D";
1290 return "(unknown channels)";
1293 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1294 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1298 case DevFmtByte
: return sizeof(ALbyte
);
1299 case DevFmtUByte
: return sizeof(ALubyte
);
1300 case DevFmtShort
: return sizeof(ALshort
);
1301 case DevFmtUShort
: return sizeof(ALushort
);
1302 case DevFmtInt
: return sizeof(ALint
);
1303 case DevFmtUInt
: return sizeof(ALuint
);
1304 case DevFmtFloat
: return sizeof(ALfloat
);
1308 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1312 case DevFmtMono
: return 1;
1313 case DevFmtStereo
: return 2;
1314 case DevFmtQuad
: return 4;
1315 case DevFmtX51
: return 6;
1316 case DevFmtX51Rear
: return 6;
1317 case DevFmtX61
: return 7;
1318 case DevFmtX71
: return 8;
1319 case DevFmtBFormat3D
: return 4;
1324 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1325 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1327 static const struct {
1329 enum DevFmtChannels channels
;
1330 enum DevFmtType type
;
1332 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1333 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1334 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1336 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1337 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1338 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1340 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1341 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1342 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1344 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1345 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1346 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1348 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1349 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1350 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1352 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1353 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1354 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1358 for(i
= 0;i
< COUNTOF(list
);i
++)
1360 if(list
[i
].format
== format
)
1362 *chans
= list
[i
].channels
;
1363 *type
= list
[i
].type
;
1371 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1376 case ALC_UNSIGNED_BYTE_SOFT
:
1377 case ALC_SHORT_SOFT
:
1378 case ALC_UNSIGNED_SHORT_SOFT
:
1380 case ALC_UNSIGNED_INT_SOFT
:
1381 case ALC_FLOAT_SOFT
:
1387 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1392 case ALC_STEREO_SOFT
:
1394 case ALC_5POINT1_SOFT
:
1395 case ALC_6POINT1_SOFT
:
1396 case ALC_7POINT1_SOFT
:
1403 /************************************************
1404 * Miscellaneous ALC helpers
1405 ************************************************/
1406 enum HrtfRequestMode
{
1412 extern inline void LockContext(ALCcontext
*context
);
1413 extern inline void UnlockContext(ALCcontext
*context
);
1415 void ALCdevice_Lock(ALCdevice
*device
)
1417 V0(device
->Backend
,lock
)();
1420 void ALCdevice_Unlock(ALCdevice
*device
)
1422 V0(device
->Backend
,unlock
)();
1426 /* SetDefaultWFXChannelOrder
1428 * Sets the default channel order used by WaveFormatEx.
1430 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1434 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1435 device
->ChannelName
[i
] = InvalidChannel
;
1437 switch(device
->FmtChans
)
1440 device
->ChannelName
[0] = FrontCenter
;
1443 device
->ChannelName
[0] = FrontLeft
;
1444 device
->ChannelName
[1] = FrontRight
;
1447 device
->ChannelName
[0] = FrontLeft
;
1448 device
->ChannelName
[1] = FrontRight
;
1449 device
->ChannelName
[2] = BackLeft
;
1450 device
->ChannelName
[3] = BackRight
;
1453 device
->ChannelName
[0] = FrontLeft
;
1454 device
->ChannelName
[1] = FrontRight
;
1455 device
->ChannelName
[2] = FrontCenter
;
1456 device
->ChannelName
[3] = LFE
;
1457 device
->ChannelName
[4] = SideLeft
;
1458 device
->ChannelName
[5] = SideRight
;
1461 device
->ChannelName
[0] = FrontLeft
;
1462 device
->ChannelName
[1] = FrontRight
;
1463 device
->ChannelName
[2] = FrontCenter
;
1464 device
->ChannelName
[3] = LFE
;
1465 device
->ChannelName
[4] = BackLeft
;
1466 device
->ChannelName
[5] = BackRight
;
1469 device
->ChannelName
[0] = FrontLeft
;
1470 device
->ChannelName
[1] = FrontRight
;
1471 device
->ChannelName
[2] = FrontCenter
;
1472 device
->ChannelName
[3] = LFE
;
1473 device
->ChannelName
[4] = BackCenter
;
1474 device
->ChannelName
[5] = SideLeft
;
1475 device
->ChannelName
[6] = SideRight
;
1478 device
->ChannelName
[0] = FrontLeft
;
1479 device
->ChannelName
[1] = FrontRight
;
1480 device
->ChannelName
[2] = FrontCenter
;
1481 device
->ChannelName
[3] = LFE
;
1482 device
->ChannelName
[4] = BackLeft
;
1483 device
->ChannelName
[5] = BackRight
;
1484 device
->ChannelName
[6] = SideLeft
;
1485 device
->ChannelName
[7] = SideRight
;
1487 case DevFmtBFormat3D
:
1488 device
->ChannelName
[0] = BFormatW
;
1489 device
->ChannelName
[1] = BFormatX
;
1490 device
->ChannelName
[2] = BFormatY
;
1491 device
->ChannelName
[3] = BFormatZ
;
1496 /* SetDefaultChannelOrder
1498 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1500 void SetDefaultChannelOrder(ALCdevice
*device
)
1504 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1505 device
->ChannelName
[i
] = InvalidChannel
;
1507 switch(device
->FmtChans
)
1510 device
->ChannelName
[0] = FrontLeft
;
1511 device
->ChannelName
[1] = FrontRight
;
1512 device
->ChannelName
[2] = BackLeft
;
1513 device
->ChannelName
[3] = BackRight
;
1514 device
->ChannelName
[4] = FrontCenter
;
1515 device
->ChannelName
[5] = LFE
;
1518 device
->ChannelName
[0] = FrontLeft
;
1519 device
->ChannelName
[1] = FrontRight
;
1520 device
->ChannelName
[2] = BackLeft
;
1521 device
->ChannelName
[3] = BackRight
;
1522 device
->ChannelName
[4] = FrontCenter
;
1523 device
->ChannelName
[5] = LFE
;
1524 device
->ChannelName
[6] = SideLeft
;
1525 device
->ChannelName
[7] = SideRight
;
1528 /* Same as WFX order */
1534 case DevFmtBFormat3D
:
1535 SetDefaultWFXChannelOrder(device
);
1540 extern inline ALint
GetChannelIdxByName(const ALCdevice
*device
, enum Channel chan
);
1543 /* ALCcontext_DeferUpdates
1545 * Defers/suspends updates for the given context's listener and sources. This
1546 * does *NOT* stop mixing, but rather prevents certain property changes from
1549 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1551 ALCdevice
*device
= context
->Device
;
1554 SetMixerFPUMode(&oldMode
);
1556 V0(device
->Backend
,lock
)();
1557 if(!context
->DeferUpdates
)
1559 context
->DeferUpdates
= AL_TRUE
;
1561 /* Make sure all pending updates are performed */
1562 UpdateContextSources(context
);
1563 #define UPDATE_SLOT(iter) do { \
1564 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1565 V((*iter)->EffectState,update)(device, *iter); \
1567 VECTOR_FOR_EACH(ALeffectslot
*, context
->ActiveAuxSlots
, UPDATE_SLOT
);
1570 V0(device
->Backend
,unlock
)();
1572 RestoreFPUMode(&oldMode
);
1575 /* ALCcontext_ProcessUpdates
1577 * Resumes update processing after being deferred.
1579 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1581 ALCdevice
*device
= context
->Device
;
1583 V0(device
->Backend
,lock
)();
1584 if(context
->DeferUpdates
)
1588 context
->DeferUpdates
= AL_FALSE
;
1590 LockUIntMapRead(&context
->SourceMap
);
1591 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1593 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1596 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1597 Source
->Offset
>= 0.0)
1599 WriteLock(&Source
->queue_lock
);
1600 ApplyOffset(Source
);
1601 WriteUnlock(&Source
->queue_lock
);
1604 new_state
= Source
->new_state
;
1605 Source
->new_state
= AL_NONE
;
1607 SetSourceState(Source
, context
, new_state
);
1609 UnlockUIntMapRead(&context
->SourceMap
);
1611 V0(device
->Backend
,unlock
)();
1617 * Stores the latest ALC device error
1619 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1624 /* DebugBreak() will cause an exception if there is no debugger */
1625 if(IsDebuggerPresent())
1627 #elif defined(SIGTRAP)
1633 ATOMIC_STORE(&device
->LastError
, errorCode
);
1635 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1641 * Updates the device's base clock time with however many samples have been
1642 * done. This is used so frequency changes on the device don't cause the time
1643 * to jump forward or back.
1645 static inline void UpdateClockBase(ALCdevice
*device
)
1647 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1648 device
->SamplesDone
= 0;
1651 /* UpdateDeviceParams
1653 * Updates device parameters according to the attribute list (caller is
1654 * responsible for holding the list lock).
1656 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1658 ALCcontext
*context
;
1659 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1660 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1661 enum DevFmtChannels oldChans
;
1662 enum DevFmtType oldType
;
1665 ALCsizei hrtf_id
= -1;
1668 // Check for attributes
1669 if(device
->Type
== Loopback
)
1675 GotAll
= GotFreq
|GotChans
|GotType
1677 ALCuint freq
, numMono
, numStereo
, numSends
;
1678 enum DevFmtChannels schans
;
1679 enum DevFmtType stype
;
1680 ALCuint attrIdx
= 0;
1685 WARN("Missing attributes for loopback device\n");
1686 return ALC_INVALID_VALUE
;
1689 numMono
= device
->NumMonoSources
;
1690 numStereo
= device
->NumStereoSources
;
1691 numSends
= device
->NumAuxSends
;
1692 schans
= device
->FmtChans
;
1693 stype
= device
->FmtType
;
1694 freq
= device
->Frequency
;
1696 while(attrList
[attrIdx
])
1698 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1700 ALCint val
= attrList
[attrIdx
+ 1];
1701 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1702 return ALC_INVALID_VALUE
;
1707 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1709 ALCint val
= attrList
[attrIdx
+ 1];
1710 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1711 return ALC_INVALID_VALUE
;
1716 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1718 freq
= attrList
[attrIdx
+ 1];
1719 if(freq
< MIN_OUTPUT_RATE
)
1720 return ALC_INVALID_VALUE
;
1724 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1726 numStereo
= attrList
[attrIdx
+ 1];
1727 if(numStereo
> device
->MaxNoOfSources
)
1728 numStereo
= device
->MaxNoOfSources
;
1730 numMono
= device
->MaxNoOfSources
- numStereo
;
1733 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1734 numSends
= attrList
[attrIdx
+ 1];
1736 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1738 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1739 hrtf_appreq
= Hrtf_Disable
;
1740 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1741 hrtf_appreq
= Hrtf_Enable
;
1743 hrtf_appreq
= Hrtf_Default
;
1746 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1747 hrtf_id
= attrList
[attrIdx
+ 1];
1752 if(gotFmt
!= GotAll
)
1754 WARN("Missing format for loopback device\n");
1755 return ALC_INVALID_VALUE
;
1758 ConfigValueUInt(NULL
, NULL
, "sends", &numSends
);
1759 numSends
= minu(MAX_SENDS
, numSends
);
1761 if((device
->Flags
&DEVICE_RUNNING
))
1762 V0(device
->Backend
,stop
)();
1763 device
->Flags
&= ~DEVICE_RUNNING
;
1765 UpdateClockBase(device
);
1767 device
->Frequency
= freq
;
1768 device
->FmtChans
= schans
;
1769 device
->FmtType
= stype
;
1770 device
->NumMonoSources
= numMono
;
1771 device
->NumStereoSources
= numStereo
;
1772 device
->NumAuxSends
= numSends
;
1774 else if(attrList
&& attrList
[0])
1776 ALCuint freq
, numMono
, numStereo
, numSends
;
1777 ALCuint attrIdx
= 0;
1779 /* If a context is already running on the device, stop playback so the
1780 * device attributes can be updated. */
1781 if((device
->Flags
&DEVICE_RUNNING
))
1782 V0(device
->Backend
,stop
)();
1783 device
->Flags
&= ~DEVICE_RUNNING
;
1785 freq
= device
->Frequency
;
1786 numMono
= device
->NumMonoSources
;
1787 numStereo
= device
->NumStereoSources
;
1788 numSends
= device
->NumAuxSends
;
1790 while(attrList
[attrIdx
])
1792 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1794 freq
= attrList
[attrIdx
+ 1];
1795 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1798 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1800 numStereo
= attrList
[attrIdx
+ 1];
1801 if(numStereo
> device
->MaxNoOfSources
)
1802 numStereo
= device
->MaxNoOfSources
;
1804 numMono
= device
->MaxNoOfSources
- numStereo
;
1807 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1808 numSends
= attrList
[attrIdx
+ 1];
1810 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1812 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1813 hrtf_appreq
= Hrtf_Disable
;
1814 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1815 hrtf_appreq
= Hrtf_Enable
;
1817 hrtf_appreq
= Hrtf_Default
;
1820 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1821 hrtf_id
= attrList
[attrIdx
+ 1];
1826 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1827 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1829 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1830 numSends
= minu(MAX_SENDS
, numSends
);
1832 UpdateClockBase(device
);
1834 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1836 /* SSE and Neon do best with the update size being a multiple of 4 */
1837 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1838 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1840 device
->Frequency
= freq
;
1841 device
->NumMonoSources
= numMono
;
1842 device
->NumStereoSources
= numStereo
;
1843 device
->NumAuxSends
= numSends
;
1846 if((device
->Flags
&DEVICE_RUNNING
))
1847 return ALC_NO_ERROR
;
1849 al_free(device
->DryBuffer
);
1850 device
->DryBuffer
= NULL
;
1852 UpdateClockBase(device
);
1854 device
->Hrtf_Status
= ALC_HRTF_DISABLED_SOFT
;
1855 if(device
->Type
!= Loopback
)
1858 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
1860 if(strcasecmp(hrtf
, "true") == 0)
1861 hrtf_userreq
= Hrtf_Enable
;
1862 else if(strcasecmp(hrtf
, "false") == 0)
1863 hrtf_userreq
= Hrtf_Disable
;
1864 else if(strcasecmp(hrtf
, "auto") != 0)
1865 ERR("Unexpected hrtf value: %s\n", hrtf
);
1868 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
1870 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1872 VECTOR_DEINIT(device
->Hrtf_List
);
1873 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1875 if(VECTOR_SIZE(device
->Hrtf_List
) > 0)
1877 device
->FmtChans
= DevFmtStereo
;
1878 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
1879 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
).hrtf
);
1881 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, 0).hrtf
);
1882 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
1886 hrtf_userreq
= hrtf_appreq
= Hrtf_Default
;
1887 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1891 else if(hrtf_appreq
== Hrtf_Enable
)
1894 /* Loopback device. We don't need to match to a specific HRTF entry
1895 * here. If the requested ID matches, we'll pick that later, if not,
1896 * we'll try to auto-select one anyway. */
1897 if(device
->FmtChans
!= DevFmtStereo
)
1898 i
= VECTOR_SIZE(device
->Hrtf_List
);
1901 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1903 VECTOR_DEINIT(device
->Hrtf_List
);
1904 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1906 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
1908 const struct Hrtf
*hrtf
= VECTOR_ELEM(device
->Hrtf_List
, i
).hrtf
;
1909 if(GetHrtfSampleRate(hrtf
) == device
->Frequency
)
1913 if(i
== VECTOR_SIZE(device
->Hrtf_List
))
1915 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1916 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1917 hrtf_appreq
= Hrtf_Default
;
1918 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1922 oldFreq
= device
->Frequency
;
1923 oldChans
= device
->FmtChans
;
1924 oldType
= device
->FmtType
;
1926 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1927 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1928 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1929 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1930 device
->UpdateSize
, device
->NumUpdates
1933 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1934 return ALC_INVALID_DEVICE
;
1936 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1938 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1939 DevFmtChannelsString(device
->FmtChans
));
1940 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1942 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1944 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1945 DevFmtTypeString(device
->FmtType
));
1946 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1948 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1950 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1951 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1954 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1955 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1956 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1959 if((device
->UpdateSize
&3) != 0)
1961 if((CPUCapFlags
&CPU_CAP_SSE
))
1962 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1963 if((CPUCapFlags
&CPU_CAP_NEON
))
1964 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1967 device
->Hrtf
= NULL
;
1968 device
->Hrtf_Mode
= DisabledHrtf
;
1969 al_string_clear(&device
->Hrtf_Name
);
1970 if(device
->FmtChans
!= DevFmtStereo
)
1972 if(hrtf_appreq
== Hrtf_Enable
)
1973 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1976 device
->Bs2b
= NULL
;
1980 bool headphones
= device
->IsHeadphones
;
1981 enum HrtfMode hrtf_mode
= FullHrtf
;
1982 ALCenum hrtf_status
= device
->Hrtf_Status
;
1987 if(device
->Type
!= Loopback
)
1989 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "stereo-mode", &mode
))
1991 if(strcasecmp(mode
, "headphones") == 0)
1993 else if(strcasecmp(mode
, "speakers") == 0)
1995 else if(strcasecmp(mode
, "auto") != 0)
1996 ERR("Unexpected stereo-mode: %s\n", mode
);
1999 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf-mode", &mode
))
2001 if(strcasecmp(mode
, "full") == 0)
2002 hrtf_mode
= FullHrtf
;
2003 else if(strcasecmp(mode
, "basic") == 0)
2004 hrtf_mode
= BasicHrtf
;
2006 ERR("Unexpected hrtf-mode: %s\n", mode
);
2011 if(hrtf_userreq
== Hrtf_Default
)
2013 usehrtf
= (headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2014 (hrtf_appreq
== Hrtf_Enable
);
2015 if(headphones
&& hrtf_appreq
!= Hrtf_Disable
)
2016 hrtf_status
= ALC_HRTF_HEADPHONES_DETECTED_SOFT
;
2018 hrtf_status
= ALC_HRTF_ENABLED_SOFT
;
2022 usehrtf
= (hrtf_userreq
== Hrtf_Enable
);
2024 hrtf_status
= ALC_HRTF_DENIED_SOFT
;
2026 hrtf_status
= ALC_HRTF_REQUIRED_SOFT
;
2030 device
->Hrtf_Status
= hrtf_status
;
2035 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2036 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
2038 VECTOR_DEINIT(device
->Hrtf_List
);
2039 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2042 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
2044 const HrtfEntry
*entry
= &VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
);
2045 if(GetHrtfSampleRate(entry
->hrtf
) == device
->Frequency
)
2047 device
->Hrtf
= entry
->hrtf
;
2048 al_string_copy(&device
->Hrtf_Name
, entry
->name
);
2053 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
2055 const HrtfEntry
*entry
= &VECTOR_ELEM(device
->Hrtf_List
, i
);
2056 if(GetHrtfSampleRate(entry
->hrtf
) == device
->Frequency
)
2058 device
->Hrtf
= entry
->hrtf
;
2059 al_string_copy(&device
->Hrtf_Name
, entry
->name
);
2067 device
->Hrtf_Mode
= hrtf_mode
;
2068 device
->Hrtf_Status
= hrtf_status
;
2069 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device
->Hrtf_Name
));
2071 device
->Bs2b
= NULL
;
2075 TRACE("HRTF disabled\n");
2077 bs2blevel
= ((headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2078 (hrtf_appreq
== Hrtf_Enable
)) ? 5 : 0;
2079 if(device
->Type
!= Loopback
)
2080 ConfigValueInt(al_string_get_cstr(device
->DeviceName
), NULL
, "cf_level", &bs2blevel
);
2081 if(bs2blevel
> 0 && bs2blevel
<= 6)
2085 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
2086 bs2b_clear(device
->Bs2b
);
2088 bs2b_set_params(device
->Bs2b
, bs2blevel
, device
->Frequency
);
2089 TRACE("BS2B enabled\n");
2094 device
->Bs2b
= NULL
;
2095 TRACE("BS2B disabled\n");
2100 aluInitPanning(device
);
2102 /* With HRTF, allocate two extra channels for the post-filter output. */
2103 size
= sizeof(device
->DryBuffer
[0]) * (device
->NumChannels
+ (device
->Hrtf
? 2 : 0));
2104 device
->DryBuffer
= al_calloc(16, size
);
2105 if(!device
->DryBuffer
)
2107 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2108 return ALC_INVALID_DEVICE
;
2111 SetMixerFPUMode(&oldMode
);
2112 V0(device
->Backend
,lock
)();
2113 context
= ATOMIC_LOAD(&device
->ContextList
);
2118 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2119 LockUIntMapRead(&context
->EffectSlotMap
);
2120 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2122 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2124 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2126 UnlockUIntMapRead(&context
->EffectSlotMap
);
2127 V0(device
->Backend
,unlock
)();
2128 RestoreFPUMode(&oldMode
);
2129 return ALC_INVALID_DEVICE
;
2131 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2132 V(slot
->EffectState
,update
)(device
, slot
);
2134 UnlockUIntMapRead(&context
->EffectSlotMap
);
2136 LockUIntMapRead(&context
->SourceMap
);
2137 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2139 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2140 ALuint s
= device
->NumAuxSends
;
2141 while(s
< MAX_SENDS
)
2143 if(source
->Send
[s
].Slot
)
2144 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2145 source
->Send
[s
].Slot
= NULL
;
2146 source
->Send
[s
].Gain
= 1.0f
;
2147 source
->Send
[s
].GainHF
= 1.0f
;
2150 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2152 UnlockUIntMapRead(&context
->SourceMap
);
2154 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2156 ALvoice
*voice
= &context
->Voices
[pos
];
2157 ALsource
*source
= voice
->Source
;
2158 ALuint s
= device
->NumAuxSends
;
2160 while(s
< MAX_SENDS
)
2162 voice
->Send
[s
].Moving
= AL_FALSE
;
2163 voice
->Send
[s
].Counter
= 0;
2169 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2170 voice
->Update(voice
, source
, context
);
2174 context
= context
->next
;
2176 if(device
->DefaultSlot
)
2178 ALeffectslot
*slot
= device
->DefaultSlot
;
2180 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2182 V0(device
->Backend
,unlock
)();
2183 RestoreFPUMode(&oldMode
);
2184 return ALC_INVALID_DEVICE
;
2186 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2187 V(slot
->EffectState
,update
)(device
, slot
);
2189 V0(device
->Backend
,unlock
)();
2190 RestoreFPUMode(&oldMode
);
2192 if(!(device
->Flags
&DEVICE_PAUSED
))
2194 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2195 return ALC_INVALID_DEVICE
;
2196 device
->Flags
|= DEVICE_RUNNING
;
2199 return ALC_NO_ERROR
;
2204 * Frees the device structure, and destroys any objects the app failed to
2205 * delete. Called once there's no more references on the device.
2207 static ALCvoid
FreeDevice(ALCdevice
*device
)
2209 TRACE("%p\n", device
);
2211 V0(device
->Backend
,close
)();
2212 DELETE_OBJ(device
->Backend
);
2213 device
->Backend
= NULL
;
2215 if(device
->DefaultSlot
)
2217 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2218 device
->DefaultSlot
= NULL
;
2222 if(device
->BufferMap
.size
> 0)
2224 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2225 ReleaseALBuffers(device
);
2227 ResetUIntMap(&device
->BufferMap
);
2229 if(device
->EffectMap
.size
> 0)
2231 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2232 ReleaseALEffects(device
);
2234 ResetUIntMap(&device
->EffectMap
);
2236 if(device
->FilterMap
.size
> 0)
2238 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2239 ReleaseALFilters(device
);
2241 ResetUIntMap(&device
->FilterMap
);
2243 AL_STRING_DEINIT(device
->Hrtf_Name
);
2244 FreeHrtfList(&device
->Hrtf_List
);
2247 device
->Bs2b
= NULL
;
2249 AL_STRING_DEINIT(device
->DeviceName
);
2251 al_free(device
->DryBuffer
);
2252 device
->DryBuffer
= NULL
;
2258 void ALCdevice_IncRef(ALCdevice
*device
)
2261 ref
= IncrementRef(&device
->ref
);
2262 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2265 void ALCdevice_DecRef(ALCdevice
*device
)
2268 ref
= DecrementRef(&device
->ref
);
2269 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2270 if(ref
== 0) FreeDevice(device
);
2275 * Checks if the device handle is valid, and increments its ref count if so.
2277 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2279 ALCdevice
*tmpDevice
;
2282 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2285 if(tmpDevice
== *device
)
2287 ALCdevice_IncRef(tmpDevice
);
2291 tmpDevice
= tmpDevice
->next
;
2302 * Initializes context fields
2304 static ALvoid
InitContext(ALCcontext
*Context
)
2306 ALlistener
*listener
= Context
->Listener
;
2307 //Initialise listener
2308 listener
->Gain
= 1.0f
;
2309 listener
->MetersPerUnit
= 1.0f
;
2310 aluVectorSet(&listener
->Position
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
2311 aluVectorSet(&listener
->Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2312 listener
->Forward
[0] = 0.0f
;
2313 listener
->Forward
[1] = 0.0f
;
2314 listener
->Forward
[2] = -1.0f
;
2315 listener
->Up
[0] = 0.0f
;
2316 listener
->Up
[1] = 1.0f
;
2317 listener
->Up
[2] = 0.0f
;
2318 aluMatrixdSet(&listener
->Params
.Matrix
,
2324 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2327 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2328 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2329 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2330 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2333 Context
->DistanceModel
= DefaultDistanceModel
;
2334 Context
->SourceDistanceModel
= AL_FALSE
;
2335 Context
->DopplerFactor
= 1.0f
;
2336 Context
->DopplerVelocity
= 1.0f
;
2337 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2338 Context
->DeferUpdates
= AL_FALSE
;
2340 Context
->ExtensionList
= alExtList
;
2346 * Cleans up the context, and destroys any remaining objects the app failed to
2347 * delete. Called once there's no more references on the context.
2349 static void FreeContext(ALCcontext
*context
)
2351 TRACE("%p\n", context
);
2353 if(context
->SourceMap
.size
> 0)
2355 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2356 ReleaseALSources(context
);
2358 ResetUIntMap(&context
->SourceMap
);
2360 if(context
->EffectSlotMap
.size
> 0)
2362 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2363 ReleaseALAuxiliaryEffectSlots(context
);
2365 ResetUIntMap(&context
->EffectSlotMap
);
2367 al_free(context
->Voices
);
2368 context
->Voices
= NULL
;
2369 context
->VoiceCount
= 0;
2370 context
->MaxVoices
= 0;
2372 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2374 ALCdevice_DecRef(context
->Device
);
2375 context
->Device
= NULL
;
2377 //Invalidate context
2378 memset(context
, 0, sizeof(ALCcontext
));
2384 * Removes the context reference from the given device and removes it from
2385 * being current on the running thread or globally.
2387 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2389 ALCcontext
*nextctx
;
2390 ALCcontext
*origctx
;
2392 if(altss_get(LocalContext
) == context
)
2394 WARN("%p released while current on thread\n", context
);
2395 altss_set(LocalContext
, NULL
);
2396 ALCcontext_DecRef(context
);
2400 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2401 ALCcontext_DecRef(context
);
2403 ALCdevice_Lock(device
);
2405 nextctx
= context
->next
;
2406 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2412 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2414 ALCdevice_Unlock(device
);
2416 ALCcontext_DecRef(context
);
2419 void ALCcontext_IncRef(ALCcontext
*context
)
2422 ref
= IncrementRef(&context
->ref
);
2423 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2426 void ALCcontext_DecRef(ALCcontext
*context
)
2429 ref
= DecrementRef(&context
->ref
);
2430 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2431 if(ref
== 0) FreeContext(context
);
2434 static void ReleaseThreadCtx(void *ptr
)
2436 WARN("%p current for thread being destroyed\n", ptr
);
2437 ALCcontext_DecRef(ptr
);
2442 * Checks that the given context is valid, and increments its reference count.
2444 static ALCboolean
VerifyContext(ALCcontext
**context
)
2449 dev
= ATOMIC_LOAD(&DeviceList
);
2452 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2457 ALCcontext_IncRef(ctx
);
2474 * Returns the currently active context for this thread, and adds a reference
2475 * without locking it.
2477 ALCcontext
*GetContextRef(void)
2479 ALCcontext
*context
;
2481 context
= altss_get(LocalContext
);
2483 ALCcontext_IncRef(context
);
2487 context
= ATOMIC_LOAD(&GlobalContext
);
2489 ALCcontext_IncRef(context
);
2497 /************************************************
2498 * Standard ALC functions
2499 ************************************************/
2503 * Return last ALC generated error code for the given device
2505 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2509 if(VerifyDevice(&device
))
2511 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2512 ALCdevice_DecRef(device
);
2515 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2521 /* alcSuspendContext
2523 * Suspends updates for the given context
2525 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2530 if(!VerifyContext(&context
))
2531 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2534 ALCcontext_DeferUpdates(context
);
2535 ALCcontext_DecRef(context
);
2539 /* alcProcessContext
2541 * Resumes processing updates for the given context
2543 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2548 if(!VerifyContext(&context
))
2549 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2552 ALCcontext_ProcessUpdates(context
);
2553 ALCcontext_DecRef(context
);
2560 * Returns information about the device, and error strings
2562 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2564 const ALCchar
*value
= NULL
;
2572 case ALC_INVALID_ENUM
:
2573 value
= alcErrInvalidEnum
;
2576 case ALC_INVALID_VALUE
:
2577 value
= alcErrInvalidValue
;
2580 case ALC_INVALID_DEVICE
:
2581 value
= alcErrInvalidDevice
;
2584 case ALC_INVALID_CONTEXT
:
2585 value
= alcErrInvalidContext
;
2588 case ALC_OUT_OF_MEMORY
:
2589 value
= alcErrOutOfMemory
;
2592 case ALC_DEVICE_SPECIFIER
:
2593 value
= alcDefaultName
;
2596 case ALC_ALL_DEVICES_SPECIFIER
:
2597 if(VerifyDevice(&Device
))
2599 value
= al_string_get_cstr(Device
->DeviceName
);
2600 ALCdevice_DecRef(Device
);
2604 ProbeAllDevicesList();
2605 value
= al_string_get_cstr(alcAllDevicesList
);
2609 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2610 if(VerifyDevice(&Device
))
2612 value
= al_string_get_cstr(Device
->DeviceName
);
2613 ALCdevice_DecRef(Device
);
2617 ProbeCaptureDeviceList();
2618 value
= al_string_get_cstr(alcCaptureDeviceList
);
2622 /* Default devices are always first in the list */
2623 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2624 value
= alcDefaultName
;
2627 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2628 if(al_string_empty(alcAllDevicesList
))
2629 ProbeAllDevicesList();
2631 VerifyDevice(&Device
);
2633 free(alcDefaultAllDevicesSpecifier
);
2634 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2635 if(!alcDefaultAllDevicesSpecifier
)
2636 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2638 value
= alcDefaultAllDevicesSpecifier
;
2639 if(Device
) ALCdevice_DecRef(Device
);
2642 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2643 if(al_string_empty(alcCaptureDeviceList
))
2644 ProbeCaptureDeviceList();
2646 VerifyDevice(&Device
);
2648 free(alcCaptureDefaultDeviceSpecifier
);
2649 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2650 if(!alcCaptureDefaultDeviceSpecifier
)
2651 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2653 value
= alcCaptureDefaultDeviceSpecifier
;
2654 if(Device
) ALCdevice_DecRef(Device
);
2657 case ALC_EXTENSIONS
:
2658 if(!VerifyDevice(&Device
))
2659 value
= alcNoDeviceExtList
;
2662 value
= alcExtensionList
;
2663 ALCdevice_DecRef(Device
);
2667 case ALC_HRTF_SPECIFIER_SOFT
:
2668 if(!VerifyDevice(&Device
))
2669 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2673 value
= (Device
->Hrtf
? al_string_get_cstr(Device
->Hrtf_Name
) : "");
2675 ALCdevice_DecRef(Device
);
2680 VerifyDevice(&Device
);
2681 alcSetError(Device
, ALC_INVALID_ENUM
);
2682 if(Device
) ALCdevice_DecRef(Device
);
2690 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2694 if(size
<= 0 || values
== NULL
)
2696 alcSetError(device
, ALC_INVALID_VALUE
);
2704 case ALC_MAJOR_VERSION
:
2705 values
[0] = alcMajorVersion
;
2707 case ALC_MINOR_VERSION
:
2708 values
[0] = alcMinorVersion
;
2711 case ALC_ATTRIBUTES_SIZE
:
2712 case ALC_ALL_ATTRIBUTES
:
2716 case ALC_MONO_SOURCES
:
2717 case ALC_STEREO_SOURCES
:
2718 case ALC_CAPTURE_SAMPLES
:
2719 case ALC_FORMAT_CHANNELS_SOFT
:
2720 case ALC_FORMAT_TYPE_SOFT
:
2721 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2725 alcSetError(NULL
, ALC_INVALID_ENUM
);
2731 if(device
->Type
== Capture
)
2735 case ALC_CAPTURE_SAMPLES
:
2736 V0(device
->Backend
,lock
)();
2737 values
[0] = V0(device
->Backend
,availableSamples
)();
2738 V0(device
->Backend
,unlock
)();
2742 values
[0] = device
->Connected
;
2746 alcSetError(device
, ALC_INVALID_ENUM
);
2755 case ALC_MAJOR_VERSION
:
2756 values
[0] = alcMajorVersion
;
2759 case ALC_MINOR_VERSION
:
2760 values
[0] = alcMinorVersion
;
2763 case ALC_EFX_MAJOR_VERSION
:
2764 values
[0] = alcEFXMajorVersion
;
2767 case ALC_EFX_MINOR_VERSION
:
2768 values
[0] = alcEFXMinorVersion
;
2771 case ALC_ATTRIBUTES_SIZE
:
2775 case ALC_ALL_ATTRIBUTES
:
2778 alcSetError(device
, ALC_INVALID_VALUE
);
2783 values
[i
++] = ALC_FREQUENCY
;
2784 values
[i
++] = device
->Frequency
;
2786 if(device
->Type
!= Loopback
)
2788 values
[i
++] = ALC_REFRESH
;
2789 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2791 values
[i
++] = ALC_SYNC
;
2792 values
[i
++] = ALC_FALSE
;
2796 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2797 values
[i
++] = device
->FmtChans
;
2799 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2800 values
[i
++] = device
->FmtType
;
2803 values
[i
++] = ALC_MONO_SOURCES
;
2804 values
[i
++] = device
->NumMonoSources
;
2806 values
[i
++] = ALC_STEREO_SOURCES
;
2807 values
[i
++] = device
->NumStereoSources
;
2809 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2810 values
[i
++] = device
->NumAuxSends
;
2812 values
[i
++] = ALC_HRTF_SOFT
;
2813 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2815 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2816 values
[i
++] = device
->Hrtf_Status
;
2822 values
[0] = device
->Frequency
;
2826 if(device
->Type
== Loopback
)
2828 alcSetError(device
, ALC_INVALID_DEVICE
);
2831 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2835 if(device
->Type
== Loopback
)
2837 alcSetError(device
, ALC_INVALID_DEVICE
);
2840 values
[0] = ALC_FALSE
;
2843 case ALC_FORMAT_CHANNELS_SOFT
:
2844 if(device
->Type
!= Loopback
)
2846 alcSetError(device
, ALC_INVALID_DEVICE
);
2849 values
[0] = device
->FmtChans
;
2852 case ALC_FORMAT_TYPE_SOFT
:
2853 if(device
->Type
!= Loopback
)
2855 alcSetError(device
, ALC_INVALID_DEVICE
);
2858 values
[0] = device
->FmtType
;
2861 case ALC_MONO_SOURCES
:
2862 values
[0] = device
->NumMonoSources
;
2865 case ALC_STEREO_SOURCES
:
2866 values
[0] = device
->NumStereoSources
;
2869 case ALC_MAX_AUXILIARY_SENDS
:
2870 values
[0] = device
->NumAuxSends
;
2874 values
[0] = device
->Connected
;
2878 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2881 case ALC_HRTF_STATUS_SOFT
:
2882 values
[0] = device
->Hrtf_Status
;
2885 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
2886 FreeHrtfList(&device
->Hrtf_List
);
2887 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2888 values
[0] = (ALCint
)VECTOR_SIZE(device
->Hrtf_List
);
2892 alcSetError(device
, ALC_INVALID_ENUM
);
2900 * Returns information about the device and the version of OpenAL
2902 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2904 VerifyDevice(&device
);
2905 if(size
<= 0 || values
== NULL
)
2906 alcSetError(device
, ALC_INVALID_VALUE
);
2908 GetIntegerv(device
, param
, size
, values
);
2909 if(device
) ALCdevice_DecRef(device
);
2912 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2917 VerifyDevice(&device
);
2918 if(size
<= 0 || values
== NULL
)
2919 alcSetError(device
, ALC_INVALID_VALUE
);
2920 else if(!device
|| device
->Type
== Capture
)
2922 ivals
= malloc(size
* sizeof(ALCint
));
2923 size
= GetIntegerv(device
, pname
, size
, ivals
);
2924 for(i
= 0;i
< size
;i
++)
2925 values
[i
] = ivals
[i
];
2928 else /* render device */
2932 case ALC_ATTRIBUTES_SIZE
:
2936 case ALC_ALL_ATTRIBUTES
:
2938 alcSetError(device
, ALC_INVALID_VALUE
);
2943 V0(device
->Backend
,lock
)();
2944 values
[i
++] = ALC_FREQUENCY
;
2945 values
[i
++] = device
->Frequency
;
2947 if(device
->Type
!= Loopback
)
2949 values
[i
++] = ALC_REFRESH
;
2950 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2952 values
[i
++] = ALC_SYNC
;
2953 values
[i
++] = ALC_FALSE
;
2957 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2958 values
[i
++] = device
->FmtChans
;
2960 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2961 values
[i
++] = device
->FmtType
;
2964 values
[i
++] = ALC_MONO_SOURCES
;
2965 values
[i
++] = device
->NumMonoSources
;
2967 values
[i
++] = ALC_STEREO_SOURCES
;
2968 values
[i
++] = device
->NumStereoSources
;
2970 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2971 values
[i
++] = device
->NumAuxSends
;
2973 values
[i
++] = ALC_HRTF_SOFT
;
2974 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2976 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2977 values
[i
++] = device
->Hrtf_Status
;
2979 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2980 values
[i
++] = device
->ClockBase
+
2981 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2984 V0(device
->Backend
,unlock
)();
2988 case ALC_DEVICE_CLOCK_SOFT
:
2989 V0(device
->Backend
,lock
)();
2990 *values
= device
->ClockBase
+
2991 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2992 V0(device
->Backend
,unlock
)();
2996 ivals
= malloc(size
* sizeof(ALCint
));
2997 size
= GetIntegerv(device
, pname
, size
, ivals
);
2998 for(i
= 0;i
< size
;i
++)
2999 values
[i
] = ivals
[i
];
3005 ALCdevice_DecRef(device
);
3009 /* alcIsExtensionPresent
3011 * Determines if there is support for a particular extension
3013 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3015 ALCboolean bResult
= ALC_FALSE
;
3017 VerifyDevice(&device
);
3020 alcSetError(device
, ALC_INVALID_VALUE
);
3023 size_t len
= strlen(extName
);
3024 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3027 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3028 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3033 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3037 } while(isspace(*ptr
));
3042 ALCdevice_DecRef(device
);
3047 /* alcGetProcAddress
3049 * Retrieves the function address for a particular extension function
3051 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3053 ALCvoid
*ptr
= NULL
;
3057 VerifyDevice(&device
);
3058 alcSetError(device
, ALC_INVALID_VALUE
);
3059 if(device
) ALCdevice_DecRef(device
);
3064 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3066 ptr
= alcFunctions
[i
].address
;
3075 * Get the value for a particular ALC enumeration name
3077 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3083 VerifyDevice(&device
);
3084 alcSetError(device
, ALC_INVALID_VALUE
);
3085 if(device
) ALCdevice_DecRef(device
);
3090 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3092 val
= enumeration
[i
].value
;
3101 * Create and attach a context to the given device.
3103 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3105 ALCcontext
*ALContext
;
3109 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3112 alcSetError(device
, ALC_INVALID_DEVICE
);
3113 if(device
) ALCdevice_DecRef(device
);
3117 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3119 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3122 alcSetError(device
, err
);
3123 if(err
== ALC_INVALID_DEVICE
)
3125 V0(device
->Backend
,lock
)();
3126 aluHandleDisconnect(device
);
3127 V0(device
->Backend
,unlock
)();
3129 ALCdevice_DecRef(device
);
3133 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3136 InitRef(&ALContext
->ref
, 1);
3137 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3139 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3141 ALContext
->VoiceCount
= 0;
3142 ALContext
->MaxVoices
= 256;
3143 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3145 if(!ALContext
|| !ALContext
->Voices
)
3147 if(!ATOMIC_LOAD(&device
->ContextList
))
3149 V0(device
->Backend
,stop
)();
3150 device
->Flags
&= ~DEVICE_RUNNING
;
3156 al_free(ALContext
->Voices
);
3157 ALContext
->Voices
= NULL
;
3159 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3165 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3166 ALCdevice_DecRef(device
);
3170 ALContext
->Device
= device
;
3171 ALCdevice_IncRef(device
);
3172 InitContext(ALContext
);
3175 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3177 ALContext
->next
= head
;
3178 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3182 ALCdevice_DecRef(device
);
3184 TRACE("Created context %p\n", ALContext
);
3188 /* alcDestroyContext
3190 * Remove a context from its device
3192 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3197 /* alcGetContextsDevice sets an error for invalid contexts */
3198 Device
= alcGetContextsDevice(context
);
3201 ReleaseContext(context
, Device
);
3202 if(!ATOMIC_LOAD(&Device
->ContextList
))
3204 V0(Device
->Backend
,stop
)();
3205 Device
->Flags
&= ~DEVICE_RUNNING
;
3212 /* alcGetCurrentContext
3214 * Returns the currently active context on the calling thread
3216 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3218 ALCcontext
*Context
= altss_get(LocalContext
);
3219 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3223 /* alcGetThreadContext
3225 * Returns the currently active thread-local context
3227 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3229 return altss_get(LocalContext
);
3233 /* alcMakeContextCurrent
3235 * Makes the given context the active process-wide context, and removes the
3236 * thread-local context for the calling thread.
3238 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3240 /* context must be valid or NULL */
3241 if(context
&& !VerifyContext(&context
))
3243 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3246 /* context's reference count is already incremented */
3247 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3248 if(context
) ALCcontext_DecRef(context
);
3250 if((context
=altss_get(LocalContext
)) != NULL
)
3252 altss_set(LocalContext
, NULL
);
3253 ALCcontext_DecRef(context
);
3259 /* alcSetThreadContext
3261 * Makes the given context the active context for the current thread
3263 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3267 /* context must be valid or NULL */
3268 if(context
&& !VerifyContext(&context
))
3270 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3273 /* context's reference count is already incremented */
3274 old
= altss_get(LocalContext
);
3275 altss_set(LocalContext
, context
);
3276 if(old
) ALCcontext_DecRef(old
);
3282 /* alcGetContextsDevice
3284 * Returns the device that a particular context is attached to
3286 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3290 if(!VerifyContext(&Context
))
3292 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3295 Device
= Context
->Device
;
3296 ALCcontext_DecRef(Context
);
3304 * Opens the named device.
3306 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3314 if(!PlaybackBackend
.name
)
3316 alcSetError(NULL
, ALC_INVALID_VALUE
);
3320 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3322 /* Some old Windows apps hardcode these expecting OpenAL to use a
3323 * specific audio API, even when they're not enumerated. Creative's
3324 * router effectively ignores them too.
3326 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3327 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3332 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3335 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3340 InitRef(&device
->ref
, 1);
3341 device
->Connected
= ALC_TRUE
;
3342 device
->Type
= Playback
;
3343 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3346 device
->Bs2b
= NULL
;
3347 VECTOR_INIT(device
->Hrtf_List
);
3348 AL_STRING_INIT(device
->Hrtf_Name
);
3349 device
->Hrtf_Mode
= DisabledHrtf
;
3350 AL_STRING_INIT(device
->DeviceName
);
3351 device
->DryBuffer
= NULL
;
3353 ATOMIC_INIT(&device
->ContextList
, NULL
);
3355 device
->ClockBase
= 0;
3356 device
->SamplesDone
= 0;
3358 device
->MaxNoOfSources
= 256;
3359 device
->AuxiliaryEffectSlotMax
= 4;
3360 device
->NumAuxSends
= MAX_SENDS
;
3362 InitUIntMap(&device
->BufferMap
, ~0);
3363 InitUIntMap(&device
->EffectMap
, ~0);
3364 InitUIntMap(&device
->FilterMap
, ~0);
3367 device
->FmtChans
= DevFmtChannelsDefault
;
3368 device
->FmtType
= DevFmtTypeDefault
;
3369 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3370 device
->IsHeadphones
= AL_FALSE
;
3371 device
->NumUpdates
= 4;
3372 device
->UpdateSize
= 1024;
3374 if(!PlaybackBackend
.getFactory
)
3375 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3376 ALCbackend_Playback
);
3379 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3380 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3382 if(!device
->Backend
)
3385 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3390 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3392 static const struct {
3393 const char name
[16];
3394 enum DevFmtChannels chans
;
3396 { "mono", DevFmtMono
},
3397 { "stereo", DevFmtStereo
},
3398 { "quad", DevFmtQuad
},
3399 { "surround51", DevFmtX51
},
3400 { "surround61", DevFmtX61
},
3401 { "surround71", DevFmtX71
},
3402 { "surround51rear", DevFmtX51Rear
},
3406 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3408 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3410 device
->FmtChans
= chanlist
[i
].chans
;
3411 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3415 if(i
== COUNTOF(chanlist
))
3416 ERR("Unsupported channels: %s\n", fmt
);
3418 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3420 static const struct {
3421 const char name
[16];
3422 enum DevFmtType type
;
3424 { "int8", DevFmtByte
},
3425 { "uint8", DevFmtUByte
},
3426 { "int16", DevFmtShort
},
3427 { "uint16", DevFmtUShort
},
3428 { "int32", DevFmtInt
},
3429 { "uint32", DevFmtUInt
},
3430 { "float32", DevFmtFloat
},
3434 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3436 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3438 device
->FmtType
= typelist
[i
].type
;
3439 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3443 if(i
== COUNTOF(typelist
))
3444 ERR("Unsupported sample-type: %s\n", fmt
);
3447 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3449 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3450 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3451 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3452 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3455 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3456 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3458 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3459 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3460 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3461 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3463 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->MaxNoOfSources
);
3464 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3466 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3467 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3469 ConfigValueUInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3470 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3472 device
->NumStereoSources
= 1;
3473 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3475 // Find a playback device to open
3476 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3478 DELETE_OBJ(device
->Backend
);
3480 alcSetError(NULL
, err
);
3484 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3486 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3487 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3489 device
->DefaultSlot
= NULL
;
3490 ERR("Failed to initialize the default effect slot\n");
3492 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3494 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3495 device
->DefaultSlot
= NULL
;
3497 ERR("Failed to initialize the default effect\n");
3500 aluInitEffectPanning(device
->DefaultSlot
);
3504 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3506 device
->next
= head
;
3507 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3510 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3516 * Closes the given device.
3518 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3520 ALCdevice
*list
, *origdev
, *nextdev
;
3524 list
= ATOMIC_LOAD(&DeviceList
);
3528 } while((list
=list
->next
) != NULL
);
3529 if(!list
|| list
->Type
== Capture
)
3531 alcSetError(list
, ALC_INVALID_DEVICE
);
3537 nextdev
= device
->next
;
3538 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3543 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3547 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3550 ALCcontext
*next
= ctx
->next
;
3551 WARN("Releasing context %p\n", ctx
);
3552 ReleaseContext(ctx
, device
);
3555 if((device
->Flags
&DEVICE_RUNNING
))
3556 V0(device
->Backend
,stop
)();
3557 device
->Flags
&= ~DEVICE_RUNNING
;
3559 ALCdevice_DecRef(device
);
3565 /************************************************
3566 * ALC capture functions
3567 ************************************************/
3568 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3570 ALCdevice
*device
= NULL
;
3575 if(!CaptureBackend
.name
)
3577 alcSetError(NULL
, ALC_INVALID_VALUE
);
3583 alcSetError(NULL
, ALC_INVALID_VALUE
);
3587 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3590 device
= al_calloc(16, sizeof(ALCdevice
));
3593 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3598 InitRef(&device
->ref
, 1);
3599 device
->Connected
= ALC_TRUE
;
3600 device
->Type
= Capture
;
3602 VECTOR_INIT(device
->Hrtf_List
);
3603 AL_STRING_INIT(device
->Hrtf_Name
);
3605 AL_STRING_INIT(device
->DeviceName
);
3606 device
->DryBuffer
= NULL
;
3608 InitUIntMap(&device
->BufferMap
, ~0);
3609 InitUIntMap(&device
->EffectMap
, ~0);
3610 InitUIntMap(&device
->FilterMap
, ~0);
3612 if(!CaptureBackend
.getFactory
)
3613 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3614 ALCbackend_Capture
);
3617 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3618 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3620 if(!device
->Backend
)
3623 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3627 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3628 device
->Frequency
= frequency
;
3630 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3631 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3634 alcSetError(NULL
, ALC_INVALID_ENUM
);
3637 device
->IsHeadphones
= AL_FALSE
;
3639 device
->UpdateSize
= samples
;
3640 device
->NumUpdates
= 1;
3642 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3645 alcSetError(NULL
, err
);
3650 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3652 device
->next
= head
;
3653 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3656 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3660 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3662 ALCdevice
*list
, *next
, *nextdev
;
3665 list
= ATOMIC_LOAD(&DeviceList
);
3669 } while((list
=list
->next
) != NULL
);
3670 if(!list
|| list
->Type
!= Capture
)
3672 alcSetError(list
, ALC_INVALID_DEVICE
);
3678 nextdev
= device
->next
;
3679 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3684 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3688 ALCdevice_DecRef(device
);
3693 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3695 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3696 alcSetError(device
, ALC_INVALID_DEVICE
);
3699 V0(device
->Backend
,lock
)();
3700 if(!device
->Connected
)
3701 alcSetError(device
, ALC_INVALID_DEVICE
);
3702 else if(!(device
->Flags
&DEVICE_RUNNING
))
3704 if(V0(device
->Backend
,start
)())
3705 device
->Flags
|= DEVICE_RUNNING
;
3708 aluHandleDisconnect(device
);
3709 alcSetError(device
, ALC_INVALID_DEVICE
);
3712 V0(device
->Backend
,unlock
)();
3715 if(device
) ALCdevice_DecRef(device
);
3718 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3720 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3721 alcSetError(device
, ALC_INVALID_DEVICE
);
3724 V0(device
->Backend
,lock
)();
3725 if((device
->Flags
&DEVICE_RUNNING
))
3726 V0(device
->Backend
,stop
)();
3727 device
->Flags
&= ~DEVICE_RUNNING
;
3728 V0(device
->Backend
,unlock
)();
3731 if(device
) ALCdevice_DecRef(device
);
3734 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3736 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3737 alcSetError(device
, ALC_INVALID_DEVICE
);
3740 ALCenum err
= ALC_INVALID_VALUE
;
3742 V0(device
->Backend
,lock
)();
3743 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3744 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3745 V0(device
->Backend
,unlock
)();
3747 if(err
!= ALC_NO_ERROR
)
3748 alcSetError(device
, err
);
3750 if(device
) ALCdevice_DecRef(device
);
3754 /************************************************
3755 * ALC loopback functions
3756 ************************************************/
3758 /* alcLoopbackOpenDeviceSOFT
3760 * Open a loopback device, for manual rendering.
3762 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3764 ALCbackendFactory
*factory
;
3769 /* Make sure the device name, if specified, is us. */
3770 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3772 alcSetError(NULL
, ALC_INVALID_VALUE
);
3776 device
= al_calloc(16, sizeof(ALCdevice
));
3779 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3784 InitRef(&device
->ref
, 1);
3785 device
->Connected
= ALC_TRUE
;
3786 device
->Type
= Loopback
;
3787 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3790 VECTOR_INIT(device
->Hrtf_List
);
3791 AL_STRING_INIT(device
->Hrtf_Name
);
3792 device
->Bs2b
= NULL
;
3793 device
->Hrtf_Mode
= DisabledHrtf
;
3794 AL_STRING_INIT(device
->DeviceName
);
3795 device
->DryBuffer
= NULL
;
3797 ATOMIC_INIT(&device
->ContextList
, NULL
);
3799 device
->ClockBase
= 0;
3800 device
->SamplesDone
= 0;
3802 device
->MaxNoOfSources
= 256;
3803 device
->AuxiliaryEffectSlotMax
= 4;
3804 device
->NumAuxSends
= MAX_SENDS
;
3806 InitUIntMap(&device
->BufferMap
, ~0);
3807 InitUIntMap(&device
->EffectMap
, ~0);
3808 InitUIntMap(&device
->FilterMap
, ~0);
3810 factory
= ALCloopbackFactory_getFactory();
3811 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3812 if(!device
->Backend
)
3815 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3820 device
->NumUpdates
= 0;
3821 device
->UpdateSize
= 0;
3823 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3824 device
->FmtChans
= DevFmtChannelsDefault
;
3825 device
->FmtType
= DevFmtTypeDefault
;
3826 device
->IsHeadphones
= AL_FALSE
;
3828 ConfigValueUInt(NULL
, NULL
, "sources", &device
->MaxNoOfSources
);
3829 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3831 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3832 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3834 ConfigValueUInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
3835 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3837 device
->NumStereoSources
= 1;
3838 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3840 // Open the "backend"
3841 V(device
->Backend
,open
)("Loopback");
3844 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3846 device
->next
= head
;
3847 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3850 TRACE("Created device %p\n", device
);
3854 /* alcIsRenderFormatSupportedSOFT
3856 * Determines if the loopback device supports the given format for rendering.
3858 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3860 ALCboolean ret
= ALC_FALSE
;
3862 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3863 alcSetError(device
, ALC_INVALID_DEVICE
);
3865 alcSetError(device
, ALC_INVALID_VALUE
);
3868 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3869 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3870 freq
>= MIN_OUTPUT_RATE
)
3873 if(device
) ALCdevice_DecRef(device
);
3878 /* alcRenderSamplesSOFT
3880 * Renders some samples into a buffer, using the format last set by the
3881 * attributes given to alcCreateContext.
3883 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3885 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3886 alcSetError(device
, ALC_INVALID_DEVICE
);
3887 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3888 alcSetError(device
, ALC_INVALID_VALUE
);
3890 aluMixData(device
, buffer
, samples
);
3891 if(device
) ALCdevice_DecRef(device
);
3895 /************************************************
3896 * ALC DSP pause/resume functions
3897 ************************************************/
3899 /* alcDevicePauseSOFT
3901 * Pause the DSP to stop audio processing.
3903 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3905 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3906 alcSetError(device
, ALC_INVALID_DEVICE
);
3910 if((device
->Flags
&DEVICE_RUNNING
))
3911 V0(device
->Backend
,stop
)();
3912 device
->Flags
&= ~DEVICE_RUNNING
;
3913 device
->Flags
|= DEVICE_PAUSED
;
3916 if(device
) ALCdevice_DecRef(device
);
3919 /* alcDeviceResumeSOFT
3921 * Resume the DSP to restart audio processing.
3923 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3925 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3926 alcSetError(device
, ALC_INVALID_DEVICE
);
3930 if((device
->Flags
&DEVICE_PAUSED
))
3932 device
->Flags
&= ~DEVICE_PAUSED
;
3933 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3935 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3936 device
->Flags
|= DEVICE_RUNNING
;
3939 alcSetError(device
, ALC_INVALID_DEVICE
);
3940 V0(device
->Backend
,lock
)();
3941 aluHandleDisconnect(device
);
3942 V0(device
->Backend
,unlock
)();
3948 if(device
) ALCdevice_DecRef(device
);
3952 /************************************************
3953 * ALC HRTF functions
3954 ************************************************/
3956 /* alcGetStringiSOFT
3958 * Gets a string parameter at the given index.
3960 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
3962 const ALCchar
*str
= NULL
;
3964 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
3965 alcSetError(device
, ALC_INVALID_DEVICE
);
3966 else switch(paramName
)
3968 case ALC_HRTF_SPECIFIER_SOFT
:
3969 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->Hrtf_List
))
3970 str
= al_string_get_cstr(VECTOR_ELEM(device
->Hrtf_List
, index
).name
);
3972 alcSetError(device
, ALC_INVALID_VALUE
);
3976 alcSetError(device
, ALC_INVALID_ENUM
);
3979 if(device
) ALCdevice_DecRef(device
);
3984 /* alcResetDeviceSOFT
3986 * Resets the given device output, using the specified attribute list.
3988 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
3993 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3996 alcSetError(device
, ALC_INVALID_DEVICE
);
3997 if(device
) ALCdevice_DecRef(device
);
4001 if((err
=UpdateDeviceParams(device
, attribs
)) != ALC_NO_ERROR
)
4004 alcSetError(device
, err
);
4005 if(err
== ALC_INVALID_DEVICE
)
4007 V0(device
->Backend
,lock
)();
4008 aluHandleDisconnect(device
);
4009 V0(device
->Backend
,unlock
)();
4011 ALCdevice_DecRef(device
);
4015 ALCdevice_DecRef(device
);