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"
46 #include "backends/base.h"
47 #include "midi/base.h"
50 /************************************************
52 ************************************************/
55 ALCbackendFactory
* (*getFactory
)(void);
56 ALCboolean (*Init
)(BackendFuncs
*);
58 void (*Probe
)(enum DevProbe
);
62 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
63 static struct BackendInfo BackendList
[] = {
65 { "jack", ALCjackBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
67 #ifdef HAVE_PULSEAUDIO
68 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
71 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
74 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
77 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
80 { "solaris", ALCsolarisBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
83 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
86 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
89 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
92 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
95 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
98 { "port", NULL
, alc_pa_init
, alc_pa_deinit
, alc_pa_probe
, EmptyFuncs
},
101 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
104 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
106 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
109 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
113 static struct BackendInfo PlaybackBackend
;
114 static struct BackendInfo CaptureBackend
;
117 /************************************************
118 * Functions, enums, and errors
119 ************************************************/
120 typedef struct ALCfunction
{
121 const ALCchar
*funcName
;
125 typedef struct ALCenums
{
126 const ALCchar
*enumName
;
130 #define DECL(x) { #x, (ALCvoid*)(x) }
131 static const ALCfunction alcFunctions
[] = {
132 DECL(alcCreateContext
),
133 DECL(alcMakeContextCurrent
),
134 DECL(alcProcessContext
),
135 DECL(alcSuspendContext
),
136 DECL(alcDestroyContext
),
137 DECL(alcGetCurrentContext
),
138 DECL(alcGetContextsDevice
),
140 DECL(alcCloseDevice
),
142 DECL(alcIsExtensionPresent
),
143 DECL(alcGetProcAddress
),
144 DECL(alcGetEnumValue
),
146 DECL(alcGetIntegerv
),
147 DECL(alcCaptureOpenDevice
),
148 DECL(alcCaptureCloseDevice
),
149 DECL(alcCaptureStart
),
150 DECL(alcCaptureStop
),
151 DECL(alcCaptureSamples
),
153 DECL(alcSetThreadContext
),
154 DECL(alcGetThreadContext
),
156 DECL(alcLoopbackOpenDeviceSOFT
),
157 DECL(alcIsRenderFormatSupportedSOFT
),
158 DECL(alcRenderSamplesSOFT
),
160 DECL(alcDevicePauseSOFT
),
161 DECL(alcDeviceResumeSOFT
),
163 DECL(alcGetInteger64vSOFT
),
165 DECL(alcResetDeviceSOFT
),
180 DECL(alIsExtensionPresent
),
181 DECL(alGetProcAddress
),
182 DECL(alGetEnumValue
),
189 DECL(alGetListenerf
),
190 DECL(alGetListener3f
),
191 DECL(alGetListenerfv
),
192 DECL(alGetListeneri
),
193 DECL(alGetListener3i
),
194 DECL(alGetListeneriv
),
196 DECL(alDeleteSources
),
212 DECL(alSourceRewindv
),
213 DECL(alSourcePausev
),
216 DECL(alSourceRewind
),
218 DECL(alSourceQueueBuffers
),
219 DECL(alSourceUnqueueBuffers
),
221 DECL(alDeleteBuffers
),
236 DECL(alDopplerFactor
),
237 DECL(alDopplerVelocity
),
238 DECL(alSpeedOfSound
),
239 DECL(alDistanceModel
),
242 DECL(alDeleteFilters
),
253 DECL(alDeleteEffects
),
263 DECL(alGenAuxiliaryEffectSlots
),
264 DECL(alDeleteAuxiliaryEffectSlots
),
265 DECL(alIsAuxiliaryEffectSlot
),
266 DECL(alAuxiliaryEffectSloti
),
267 DECL(alAuxiliaryEffectSlotiv
),
268 DECL(alAuxiliaryEffectSlotf
),
269 DECL(alAuxiliaryEffectSlotfv
),
270 DECL(alGetAuxiliaryEffectSloti
),
271 DECL(alGetAuxiliaryEffectSlotiv
),
272 DECL(alGetAuxiliaryEffectSlotf
),
273 DECL(alGetAuxiliaryEffectSlotfv
),
275 DECL(alBufferSubDataSOFT
),
277 DECL(alBufferSamplesSOFT
),
278 DECL(alBufferSubSamplesSOFT
),
279 DECL(alGetBufferSamplesSOFT
),
280 DECL(alIsBufferFormatSupportedSOFT
),
282 DECL(alDeferUpdatesSOFT
),
283 DECL(alProcessUpdatesSOFT
),
286 DECL(alSource3dSOFT
),
287 DECL(alSourcedvSOFT
),
288 DECL(alGetSourcedSOFT
),
289 DECL(alGetSource3dSOFT
),
290 DECL(alGetSourcedvSOFT
),
291 DECL(alSourcei64SOFT
),
292 DECL(alSource3i64SOFT
),
293 DECL(alSourcei64vSOFT
),
294 DECL(alGetSourcei64SOFT
),
295 DECL(alGetSource3i64SOFT
),
296 DECL(alGetSourcei64vSOFT
),
298 DECL(alGenSoundfontsSOFT
),
299 DECL(alDeleteSoundfontsSOFT
),
300 DECL(alIsSoundfontSOFT
),
301 DECL(alGetSoundfontivSOFT
),
302 DECL(alSoundfontPresetsSOFT
),
303 DECL(alGenPresetsSOFT
),
304 DECL(alDeletePresetsSOFT
),
305 DECL(alIsPresetSOFT
),
307 DECL(alPresetivSOFT
),
308 DECL(alGetPresetivSOFT
),
309 DECL(alPresetFontsoundsSOFT
),
310 DECL(alGenFontsoundsSOFT
),
311 DECL(alDeleteFontsoundsSOFT
),
312 DECL(alIsFontsoundSOFT
),
313 DECL(alFontsoundiSOFT
),
314 DECL(alFontsound2iSOFT
),
315 DECL(alFontsoundivSOFT
),
316 DECL(alGetFontsoundivSOFT
),
317 DECL(alFontsoundModulatoriSOFT
),
318 DECL(alGetFontsoundModulatorivSOFT
),
319 DECL(alMidiSoundfontSOFT
),
320 DECL(alMidiSoundfontvSOFT
),
321 DECL(alMidiEventSOFT
),
322 DECL(alMidiSysExSOFT
),
323 DECL(alMidiPlaySOFT
),
324 DECL(alMidiPauseSOFT
),
325 DECL(alMidiStopSOFT
),
326 DECL(alMidiResetSOFT
),
327 DECL(alMidiGainSOFT
),
328 DECL(alGetInteger64SOFT
),
329 DECL(alGetInteger64vSOFT
),
330 DECL(alLoadSoundfontSOFT
),
336 #define DECL(x) { #x, (x) }
337 static const ALCenums enumeration
[] = {
342 DECL(ALC_MAJOR_VERSION
),
343 DECL(ALC_MINOR_VERSION
),
344 DECL(ALC_ATTRIBUTES_SIZE
),
345 DECL(ALC_ALL_ATTRIBUTES
),
346 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
347 DECL(ALC_DEVICE_SPECIFIER
),
348 DECL(ALC_ALL_DEVICES_SPECIFIER
),
349 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
350 DECL(ALC_EXTENSIONS
),
354 DECL(ALC_MONO_SOURCES
),
355 DECL(ALC_STEREO_SOURCES
),
356 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
357 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
358 DECL(ALC_CAPTURE_SAMPLES
),
361 DECL(ALC_EFX_MAJOR_VERSION
),
362 DECL(ALC_EFX_MINOR_VERSION
),
363 DECL(ALC_MAX_AUXILIARY_SENDS
),
365 DECL(ALC_FORMAT_CHANNELS_SOFT
),
366 DECL(ALC_FORMAT_TYPE_SOFT
),
369 DECL(ALC_STEREO_SOFT
),
371 DECL(ALC_5POINT1_SOFT
),
372 DECL(ALC_6POINT1_SOFT
),
373 DECL(ALC_7POINT1_SOFT
),
376 DECL(ALC_UNSIGNED_BYTE_SOFT
),
377 DECL(ALC_SHORT_SOFT
),
378 DECL(ALC_UNSIGNED_SHORT_SOFT
),
380 DECL(ALC_UNSIGNED_INT_SOFT
),
381 DECL(ALC_FLOAT_SOFT
),
384 DECL(ALC_DONT_CARE_SOFT
),
385 DECL(ALC_HRTF_STATUS_SOFT
),
386 DECL(ALC_HRTF_DISABLED_SOFT
),
387 DECL(ALC_HRTF_ENABLED_SOFT
),
388 DECL(ALC_HRTF_DENIED_SOFT
),
389 DECL(ALC_HRTF_REQUIRED_SOFT
),
390 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
391 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
394 DECL(ALC_INVALID_DEVICE
),
395 DECL(ALC_INVALID_CONTEXT
),
396 DECL(ALC_INVALID_ENUM
),
397 DECL(ALC_INVALID_VALUE
),
398 DECL(ALC_OUT_OF_MEMORY
),
406 DECL(AL_SOURCE_RELATIVE
),
407 DECL(AL_CONE_INNER_ANGLE
),
408 DECL(AL_CONE_OUTER_ANGLE
),
418 DECL(AL_ORIENTATION
),
419 DECL(AL_REFERENCE_DISTANCE
),
420 DECL(AL_ROLLOFF_FACTOR
),
421 DECL(AL_CONE_OUTER_GAIN
),
422 DECL(AL_MAX_DISTANCE
),
424 DECL(AL_SAMPLE_OFFSET
),
425 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
426 DECL(AL_BYTE_OFFSET
),
427 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
428 DECL(AL_SOURCE_TYPE
),
431 DECL(AL_UNDETERMINED
),
432 DECL(AL_METERS_PER_UNIT
),
433 DECL(AL_LOOP_POINTS_SOFT
),
434 DECL(AL_DIRECT_CHANNELS_SOFT
),
436 DECL(AL_DIRECT_FILTER
),
437 DECL(AL_AUXILIARY_SEND_FILTER
),
438 DECL(AL_AIR_ABSORPTION_FACTOR
),
439 DECL(AL_ROOM_ROLLOFF_FACTOR
),
440 DECL(AL_CONE_OUTER_GAINHF
),
441 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
442 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
443 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
445 DECL(AL_SOURCE_STATE
),
451 DECL(AL_BUFFERS_QUEUED
),
452 DECL(AL_BUFFERS_PROCESSED
),
454 DECL(AL_FORMAT_MONO8
),
455 DECL(AL_FORMAT_MONO16
),
456 DECL(AL_FORMAT_MONO_FLOAT32
),
457 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
458 DECL(AL_FORMAT_STEREO8
),
459 DECL(AL_FORMAT_STEREO16
),
460 DECL(AL_FORMAT_STEREO_FLOAT32
),
461 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
462 DECL(AL_FORMAT_MONO_IMA4
),
463 DECL(AL_FORMAT_STEREO_IMA4
),
464 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
465 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
466 DECL(AL_FORMAT_QUAD8_LOKI
),
467 DECL(AL_FORMAT_QUAD16_LOKI
),
468 DECL(AL_FORMAT_QUAD8
),
469 DECL(AL_FORMAT_QUAD16
),
470 DECL(AL_FORMAT_QUAD32
),
471 DECL(AL_FORMAT_51CHN8
),
472 DECL(AL_FORMAT_51CHN16
),
473 DECL(AL_FORMAT_51CHN32
),
474 DECL(AL_FORMAT_61CHN8
),
475 DECL(AL_FORMAT_61CHN16
),
476 DECL(AL_FORMAT_61CHN32
),
477 DECL(AL_FORMAT_71CHN8
),
478 DECL(AL_FORMAT_71CHN16
),
479 DECL(AL_FORMAT_71CHN32
),
480 DECL(AL_FORMAT_REAR8
),
481 DECL(AL_FORMAT_REAR16
),
482 DECL(AL_FORMAT_REAR32
),
483 DECL(AL_FORMAT_MONO_MULAW
),
484 DECL(AL_FORMAT_MONO_MULAW_EXT
),
485 DECL(AL_FORMAT_STEREO_MULAW
),
486 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
487 DECL(AL_FORMAT_QUAD_MULAW
),
488 DECL(AL_FORMAT_51CHN_MULAW
),
489 DECL(AL_FORMAT_61CHN_MULAW
),
490 DECL(AL_FORMAT_71CHN_MULAW
),
491 DECL(AL_FORMAT_REAR_MULAW
),
492 DECL(AL_FORMAT_MONO_ALAW_EXT
),
493 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
496 DECL(AL_MONO16_SOFT
),
497 DECL(AL_MONO32F_SOFT
),
498 DECL(AL_STEREO8_SOFT
),
499 DECL(AL_STEREO16_SOFT
),
500 DECL(AL_STEREO32F_SOFT
),
502 DECL(AL_QUAD16_SOFT
),
503 DECL(AL_QUAD32F_SOFT
),
505 DECL(AL_REAR16_SOFT
),
506 DECL(AL_REAR32F_SOFT
),
507 DECL(AL_5POINT1_8_SOFT
),
508 DECL(AL_5POINT1_16_SOFT
),
509 DECL(AL_5POINT1_32F_SOFT
),
510 DECL(AL_6POINT1_8_SOFT
),
511 DECL(AL_6POINT1_16_SOFT
),
512 DECL(AL_6POINT1_32F_SOFT
),
513 DECL(AL_7POINT1_8_SOFT
),
514 DECL(AL_7POINT1_16_SOFT
),
515 DECL(AL_7POINT1_32F_SOFT
),
516 DECL(AL_FORMAT_BFORMAT2D_8
),
517 DECL(AL_FORMAT_BFORMAT2D_16
),
518 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
519 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
520 DECL(AL_FORMAT_BFORMAT3D_8
),
521 DECL(AL_FORMAT_BFORMAT3D_16
),
522 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
523 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
526 DECL(AL_STEREO_SOFT
),
529 DECL(AL_5POINT1_SOFT
),
530 DECL(AL_6POINT1_SOFT
),
531 DECL(AL_7POINT1_SOFT
),
534 DECL(AL_UNSIGNED_BYTE_SOFT
),
536 DECL(AL_UNSIGNED_SHORT_SOFT
),
538 DECL(AL_UNSIGNED_INT_SOFT
),
540 DECL(AL_DOUBLE_SOFT
),
542 DECL(AL_UNSIGNED_BYTE3_SOFT
),
548 DECL(AL_INTERNAL_FORMAT_SOFT
),
549 DECL(AL_BYTE_LENGTH_SOFT
),
550 DECL(AL_SAMPLE_LENGTH_SOFT
),
551 DECL(AL_SEC_LENGTH_SOFT
),
552 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
553 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
560 DECL(AL_INVALID_NAME
),
561 DECL(AL_INVALID_ENUM
),
562 DECL(AL_INVALID_VALUE
),
563 DECL(AL_INVALID_OPERATION
),
564 DECL(AL_OUT_OF_MEMORY
),
571 DECL(AL_DOPPLER_FACTOR
),
572 DECL(AL_DOPPLER_VELOCITY
),
573 DECL(AL_DISTANCE_MODEL
),
574 DECL(AL_SPEED_OF_SOUND
),
575 DECL(AL_SOURCE_DISTANCE_MODEL
),
576 DECL(AL_DEFERRED_UPDATES_SOFT
),
578 DECL(AL_INVERSE_DISTANCE
),
579 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
580 DECL(AL_LINEAR_DISTANCE
),
581 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
582 DECL(AL_EXPONENT_DISTANCE
),
583 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
585 DECL(AL_FILTER_TYPE
),
586 DECL(AL_FILTER_NULL
),
587 DECL(AL_FILTER_LOWPASS
),
588 DECL(AL_FILTER_HIGHPASS
),
589 DECL(AL_FILTER_BANDPASS
),
591 DECL(AL_LOWPASS_GAIN
),
592 DECL(AL_LOWPASS_GAINHF
),
594 DECL(AL_HIGHPASS_GAIN
),
595 DECL(AL_HIGHPASS_GAINLF
),
597 DECL(AL_BANDPASS_GAIN
),
598 DECL(AL_BANDPASS_GAINHF
),
599 DECL(AL_BANDPASS_GAINLF
),
601 DECL(AL_EFFECT_TYPE
),
602 DECL(AL_EFFECT_NULL
),
603 DECL(AL_EFFECT_REVERB
),
604 DECL(AL_EFFECT_EAXREVERB
),
605 DECL(AL_EFFECT_CHORUS
),
606 DECL(AL_EFFECT_DISTORTION
),
607 DECL(AL_EFFECT_ECHO
),
608 DECL(AL_EFFECT_FLANGER
),
610 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
611 DECL(AL_EFFECT_VOCAL_MORPHER
),
612 DECL(AL_EFFECT_PITCH_SHIFTER
),
614 DECL(AL_EFFECT_RING_MODULATOR
),
616 DECL(AL_EFFECT_AUTOWAH
),
618 DECL(AL_EFFECT_COMPRESSOR
),
619 DECL(AL_EFFECT_EQUALIZER
),
620 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
621 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
623 DECL(AL_EAXREVERB_DENSITY
),
624 DECL(AL_EAXREVERB_DIFFUSION
),
625 DECL(AL_EAXREVERB_GAIN
),
626 DECL(AL_EAXREVERB_GAINHF
),
627 DECL(AL_EAXREVERB_GAINLF
),
628 DECL(AL_EAXREVERB_DECAY_TIME
),
629 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
630 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
631 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
632 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
633 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
634 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
635 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
636 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
637 DECL(AL_EAXREVERB_ECHO_TIME
),
638 DECL(AL_EAXREVERB_ECHO_DEPTH
),
639 DECL(AL_EAXREVERB_MODULATION_TIME
),
640 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
641 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
642 DECL(AL_EAXREVERB_HFREFERENCE
),
643 DECL(AL_EAXREVERB_LFREFERENCE
),
644 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
645 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
647 DECL(AL_REVERB_DENSITY
),
648 DECL(AL_REVERB_DIFFUSION
),
649 DECL(AL_REVERB_GAIN
),
650 DECL(AL_REVERB_GAINHF
),
651 DECL(AL_REVERB_DECAY_TIME
),
652 DECL(AL_REVERB_DECAY_HFRATIO
),
653 DECL(AL_REVERB_REFLECTIONS_GAIN
),
654 DECL(AL_REVERB_REFLECTIONS_DELAY
),
655 DECL(AL_REVERB_LATE_REVERB_GAIN
),
656 DECL(AL_REVERB_LATE_REVERB_DELAY
),
657 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
658 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
659 DECL(AL_REVERB_DECAY_HFLIMIT
),
661 DECL(AL_CHORUS_WAVEFORM
),
662 DECL(AL_CHORUS_PHASE
),
663 DECL(AL_CHORUS_RATE
),
664 DECL(AL_CHORUS_DEPTH
),
665 DECL(AL_CHORUS_FEEDBACK
),
666 DECL(AL_CHORUS_DELAY
),
668 DECL(AL_DISTORTION_EDGE
),
669 DECL(AL_DISTORTION_GAIN
),
670 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
671 DECL(AL_DISTORTION_EQCENTER
),
672 DECL(AL_DISTORTION_EQBANDWIDTH
),
675 DECL(AL_ECHO_LRDELAY
),
676 DECL(AL_ECHO_DAMPING
),
677 DECL(AL_ECHO_FEEDBACK
),
678 DECL(AL_ECHO_SPREAD
),
680 DECL(AL_FLANGER_WAVEFORM
),
681 DECL(AL_FLANGER_PHASE
),
682 DECL(AL_FLANGER_RATE
),
683 DECL(AL_FLANGER_DEPTH
),
684 DECL(AL_FLANGER_FEEDBACK
),
685 DECL(AL_FLANGER_DELAY
),
687 DECL(AL_RING_MODULATOR_FREQUENCY
),
688 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
689 DECL(AL_RING_MODULATOR_WAVEFORM
),
692 DECL(AL_AUTOWAH_ATTACK_TIME
),
693 DECL(AL_AUTOWAH_PEAK_GAIN
),
694 DECL(AL_AUTOWAH_RELEASE_TIME
),
695 DECL(AL_AUTOWAH_RESONANCE
),
698 DECL(AL_COMPRESSOR_ONOFF
),
700 DECL(AL_EQUALIZER_LOW_GAIN
),
701 DECL(AL_EQUALIZER_LOW_CUTOFF
),
702 DECL(AL_EQUALIZER_MID1_GAIN
),
703 DECL(AL_EQUALIZER_MID1_CENTER
),
704 DECL(AL_EQUALIZER_MID1_WIDTH
),
705 DECL(AL_EQUALIZER_MID2_GAIN
),
706 DECL(AL_EQUALIZER_MID2_CENTER
),
707 DECL(AL_EQUALIZER_MID2_WIDTH
),
708 DECL(AL_EQUALIZER_HIGH_GAIN
),
709 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
711 DECL(AL_DEDICATED_GAIN
),
717 static const ALCchar alcNoError
[] = "No Error";
718 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
719 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
720 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
721 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
722 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
725 /************************************************
727 ************************************************/
729 /* Enumerated device names */
730 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
732 static al_string alcAllDevicesList
;
733 static al_string alcCaptureDeviceList
;
735 /* Default is always the first in the list */
736 static ALCchar
*alcDefaultAllDevicesSpecifier
;
737 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
739 /* Default context extensions */
740 static const ALchar alExtList
[] =
741 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
742 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
743 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
744 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
745 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
746 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
747 "AL_SOFT_source_latency AL_SOFT_source_length";
749 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
751 /* Thread-local current context */
752 static altss_t LocalContext
;
753 /* Process-wide current context */
754 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
756 /* Mixing thread piority level */
761 enum LogLevel LogLevel
= LogWarning
;
763 enum LogLevel LogLevel
= LogError
;
766 /* Flag to trap ALC device errors */
767 static ALCboolean TrapALCError
= ALC_FALSE
;
769 /* One-time configuration init control */
770 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
772 /* Default effect that applies to sources that don't have an effect on send 0 */
773 static ALeffect DefaultEffect
;
775 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
778 static ALCboolean SuspendDefers
= ALC_TRUE
;
781 /************************************************
783 ************************************************/
784 static const ALCchar alcNoDeviceExtList
[] =
785 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
786 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
787 static const ALCchar alcExtensionList
[] =
788 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
789 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
790 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
791 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
792 static const ALCint alcMajorVersion
= 1;
793 static const ALCint alcMinorVersion
= 1;
795 static const ALCint alcEFXMajorVersion
= 1;
796 static const ALCint alcEFXMinorVersion
= 0;
799 /************************************************
801 ************************************************/
802 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
804 static almtx_t ListLock
;
805 static inline void LockLists(void)
807 int lockret
= almtx_lock(&ListLock
);
808 assert(lockret
== althrd_success
);
810 static inline void UnlockLists(void)
812 int unlockret
= almtx_unlock(&ListLock
);
813 assert(unlockret
== althrd_success
);
816 /************************************************
817 * Library initialization
818 ************************************************/
820 static void alc_init(void);
821 static void alc_deinit(void);
822 static void alc_deinit_safe(void);
824 #ifndef AL_LIBTYPE_STATIC
825 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
829 case DLL_PROCESS_ATTACH
:
830 /* Pin the DLL so we won't get unloaded until the process terminates */
831 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
832 (WCHAR
*)hModule
, &hModule
);
836 case DLL_THREAD_DETACH
:
839 case DLL_PROCESS_DETACH
:
848 #elif defined(_MSC_VER)
849 #pragma section(".CRT$XCU",read)
850 static void alc_constructor(void);
851 static void alc_destructor(void);
852 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
854 static void alc_constructor(void)
856 atexit(alc_destructor
);
860 static void alc_destructor(void)
864 #elif defined(HAVE_GCC_DESTRUCTOR)
865 static void alc_init(void) __attribute__((constructor
));
866 static void alc_deinit(void) __attribute__((destructor
));
868 #error "No static initialization available on this platform!"
871 #elif defined(HAVE_GCC_DESTRUCTOR)
873 static void alc_init(void) __attribute__((constructor
));
874 static void alc_deinit(void) __attribute__((destructor
));
877 #error "No global initialization available on this platform!"
880 static void ReleaseThreadCtx(void *ptr
);
881 static void alc_init(void)
888 AL_STRING_INIT(alcAllDevicesList
);
889 AL_STRING_INIT(alcCaptureDeviceList
);
891 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
892 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
895 str
= getenv("__ALSOFT_REVERSE_Z");
896 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
899 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
900 assert(ret
== althrd_success
);
902 ret
= almtx_init(&ListLock
, almtx_recursive
);
903 assert(ret
== althrd_success
);
908 static void alc_initconfig(void)
910 const char *devs
, *str
;
915 str
= getenv("ALSOFT_LOGLEVEL");
918 long lvl
= strtol(str
, NULL
, 0);
919 if(lvl
>= NoLog
&& lvl
<= LogRef
)
923 str
= getenv("ALSOFT_LOGFILE");
926 FILE *logfile
= al_fopen(str
, "wt");
927 if(logfile
) LogFile
= logfile
;
928 else ERR("Failed to open log file '%s'\n", str
);
933 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
934 for(i
= 1;BackendList
[i
].name
;i
++)
935 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
936 TRACE("Supported backends: %s\n", buf
);
940 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
943 if(strcasecmp(str
, "ignore") == 0)
945 SuspendDefers
= ALC_FALSE
;
946 TRACE("Selected context suspend behavior, \"ignore\"\n");
949 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
953 #if defined(HAVE_SSE4_1)
954 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE4_1
;
955 #elif defined(HAVE_SSE2)
956 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
957 #elif defined(HAVE_SSE)
958 capfilter
|= CPU_CAP_SSE
;
961 capfilter
|= CPU_CAP_NEON
;
963 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
965 if(strcasecmp(str
, "all") == 0)
970 const char *next
= str
;
974 while(isspace(str
[0]))
976 next
= strchr(str
, ',');
978 if(!str
[0] || str
[0] == ',')
981 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
982 while(len
> 0 && isspace(str
[len
-1]))
984 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
985 capfilter
&= ~CPU_CAP_SSE
;
986 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
987 capfilter
&= ~CPU_CAP_SSE2
;
988 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
989 capfilter
&= ~CPU_CAP_SSE4_1
;
990 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
991 capfilter
&= ~CPU_CAP_NEON
;
993 WARN("Invalid CPU extension \"%s\"\n", str
);
997 FillCPUCaps(capfilter
);
1004 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
1006 if(ConfigValueStr(NULL
, NULL
, "resampler", &str
))
1008 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
1009 DefaultResampler
= PointResampler
;
1010 else if(strcasecmp(str
, "linear") == 0)
1011 DefaultResampler
= LinearResampler
;
1012 else if(strcasecmp(str
, "sinc4") == 0)
1013 DefaultResampler
= FIR4Resampler
;
1014 else if(strcasecmp(str
, "cubic") == 0)
1016 ERR("Resampler option \"cubic\" is deprecated, using sinc4\n");
1017 DefaultResampler
= FIR4Resampler
;
1022 n
= strtol(str
, &end
, 0);
1023 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== FIR4Resampler
))
1024 DefaultResampler
= n
;
1026 WARN("Invalid resampler: %s\n", str
);
1031 str
= getenv("ALSOFT_TRAP_ERROR");
1032 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1034 TrapALError
= AL_TRUE
;
1035 TrapALCError
= AL_TRUE
;
1039 str
= getenv("ALSOFT_TRAP_AL_ERROR");
1040 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1041 TrapALError
= AL_TRUE
;
1042 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
1044 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1045 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1046 TrapALCError
= ALC_TRUE
;
1047 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1050 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1051 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1053 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1055 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1056 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1060 const char *next
= devs
;
1061 int endlist
, delitem
;
1066 while(isspace(devs
[0]))
1068 next
= strchr(devs
, ',');
1070 delitem
= (devs
[0] == '-');
1071 if(devs
[0] == '-') devs
++;
1073 if(!devs
[0] || devs
[0] == ',')
1080 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1081 while(len
> 0 && isspace(devs
[len
-1]))
1083 for(n
= i
;BackendList
[n
].name
;n
++)
1085 if(len
== strlen(BackendList
[n
].name
) &&
1086 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1091 BackendList
[n
] = BackendList
[n
+1];
1093 } while(BackendList
[n
].name
);
1097 struct BackendInfo Bkp
= BackendList
[n
];
1100 BackendList
[n
] = BackendList
[n
-1];
1103 BackendList
[n
] = Bkp
;
1114 BackendList
[i
].name
= NULL
;
1115 BackendList
[i
].getFactory
= NULL
;
1116 BackendList
[i
].Init
= NULL
;
1117 BackendList
[i
].Deinit
= NULL
;
1118 BackendList
[i
].Probe
= NULL
;
1122 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1124 if(BackendList
[i
].getFactory
)
1126 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1127 if(!V0(factory
,init
)())
1129 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1133 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1134 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1136 PlaybackBackend
= BackendList
[i
];
1137 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1139 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1141 CaptureBackend
= BackendList
[i
];
1142 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1148 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1150 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1154 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1155 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1157 PlaybackBackend
= BackendList
[i
];
1158 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1160 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1162 CaptureBackend
= BackendList
[i
];
1163 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1167 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1171 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1174 const char *next
= str
;
1178 next
= strchr(str
, ',');
1180 if(!str
[0] || next
== str
)
1183 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1184 for(n
= 0;EffectList
[n
].name
;n
++)
1186 if(len
== strlen(EffectList
[n
].name
) &&
1187 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1188 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1193 InitEffectFactoryMap();
1195 InitEffect(&DefaultEffect
);
1196 str
= getenv("ALSOFT_DEFAULT_REVERB");
1197 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1198 LoadReverbPreset(str
, &DefaultEffect
);
1200 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1203 /************************************************
1204 * Library deinitialization
1205 ************************************************/
1206 static void alc_cleanup(void)
1210 AL_STRING_DEINIT(alcAllDevicesList
);
1211 AL_STRING_DEINIT(alcCaptureDeviceList
);
1213 free(alcDefaultAllDevicesSpecifier
);
1214 alcDefaultAllDevicesSpecifier
= NULL
;
1215 free(alcCaptureDefaultDeviceSpecifier
);
1216 alcCaptureDefaultDeviceSpecifier
= NULL
;
1218 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1223 } while((dev
=dev
->next
) != NULL
);
1224 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1227 DeinitEffectFactoryMap();
1230 static void alc_deinit_safe(void)
1238 almtx_destroy(&ListLock
);
1239 altss_delete(LocalContext
);
1241 if(LogFile
!= stderr
)
1246 static void alc_deinit(void)
1252 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1253 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1255 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1257 if(!BackendList
[i
].getFactory
)
1258 BackendList
[i
].Deinit();
1261 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1262 V0(factory
,deinit
)();
1266 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1267 V0(factory
,deinit
)();
1274 /************************************************
1275 * Device enumeration
1276 ************************************************/
1277 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1282 al_string_clear(list
);
1284 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1286 if(!PlaybackBackend
.getFactory
)
1287 PlaybackBackend
.Probe(type
);
1290 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1291 V(factory
,probe
)(type
);
1294 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1296 if(!CaptureBackend
.getFactory
)
1297 CaptureBackend
.Probe(type
);
1300 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1301 V(factory
,probe
)(type
);
1306 static void ProbeAllDevicesList(void)
1307 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1308 static void ProbeCaptureDeviceList(void)
1309 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1311 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1313 size_t len
= strlen(name
);
1315 al_string_append_range(devnames
, name
, name
+len
+1);
1317 void AppendAllDevicesList(const ALCchar
*name
)
1318 { AppendDevice(name
, &alcAllDevicesList
); }
1319 void AppendCaptureDeviceList(const ALCchar
*name
)
1320 { AppendDevice(name
, &alcCaptureDeviceList
); }
1323 /************************************************
1324 * Device format information
1325 ************************************************/
1326 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1330 case DevFmtByte
: return "Signed Byte";
1331 case DevFmtUByte
: return "Unsigned Byte";
1332 case DevFmtShort
: return "Signed Short";
1333 case DevFmtUShort
: return "Unsigned Short";
1334 case DevFmtInt
: return "Signed Int";
1335 case DevFmtUInt
: return "Unsigned Int";
1336 case DevFmtFloat
: return "Float";
1338 return "(unknown type)";
1340 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1344 case DevFmtMono
: return "Mono";
1345 case DevFmtStereo
: return "Stereo";
1346 case DevFmtQuad
: return "Quadraphonic";
1347 case DevFmtX51
: return "5.1 Surround";
1348 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1349 case DevFmtX61
: return "6.1 Surround";
1350 case DevFmtX71
: return "7.1 Surround";
1351 case DevFmtBFormat3D
: return "B-Format 3D";
1353 return "(unknown channels)";
1356 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1357 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1361 case DevFmtByte
: return sizeof(ALbyte
);
1362 case DevFmtUByte
: return sizeof(ALubyte
);
1363 case DevFmtShort
: return sizeof(ALshort
);
1364 case DevFmtUShort
: return sizeof(ALushort
);
1365 case DevFmtInt
: return sizeof(ALint
);
1366 case DevFmtUInt
: return sizeof(ALuint
);
1367 case DevFmtFloat
: return sizeof(ALfloat
);
1371 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1375 case DevFmtMono
: return 1;
1376 case DevFmtStereo
: return 2;
1377 case DevFmtQuad
: return 4;
1378 case DevFmtX51
: return 6;
1379 case DevFmtX51Rear
: return 6;
1380 case DevFmtX61
: return 7;
1381 case DevFmtX71
: return 8;
1382 case DevFmtBFormat3D
: return 4;
1387 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1388 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1390 static const struct {
1392 enum DevFmtChannels channels
;
1393 enum DevFmtType type
;
1395 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1396 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1397 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1399 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1400 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1401 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1403 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1404 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1405 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1407 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1408 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1409 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1411 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1412 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1413 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1415 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1416 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1417 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1421 for(i
= 0;i
< COUNTOF(list
);i
++)
1423 if(list
[i
].format
== format
)
1425 *chans
= list
[i
].channels
;
1426 *type
= list
[i
].type
;
1434 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1439 case ALC_UNSIGNED_BYTE_SOFT
:
1440 case ALC_SHORT_SOFT
:
1441 case ALC_UNSIGNED_SHORT_SOFT
:
1443 case ALC_UNSIGNED_INT_SOFT
:
1444 case ALC_FLOAT_SOFT
:
1450 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1455 case ALC_STEREO_SOFT
:
1457 case ALC_5POINT1_SOFT
:
1458 case ALC_6POINT1_SOFT
:
1459 case ALC_7POINT1_SOFT
:
1466 /************************************************
1467 * Miscellaneous ALC helpers
1468 ************************************************/
1469 enum HrtfRequestMode
{
1475 extern inline void LockContext(ALCcontext
*context
);
1476 extern inline void UnlockContext(ALCcontext
*context
);
1478 void ALCdevice_Lock(ALCdevice
*device
)
1480 V0(device
->Backend
,lock
)();
1483 void ALCdevice_Unlock(ALCdevice
*device
)
1485 V0(device
->Backend
,unlock
)();
1489 /* SetDefaultWFXChannelOrder
1491 * Sets the default channel order used by WaveFormatEx.
1493 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1497 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1498 device
->ChannelName
[i
] = InvalidChannel
;
1500 switch(device
->FmtChans
)
1503 device
->ChannelName
[0] = FrontCenter
;
1506 device
->ChannelName
[0] = FrontLeft
;
1507 device
->ChannelName
[1] = FrontRight
;
1510 device
->ChannelName
[0] = FrontLeft
;
1511 device
->ChannelName
[1] = FrontRight
;
1512 device
->ChannelName
[2] = BackLeft
;
1513 device
->ChannelName
[3] = BackRight
;
1516 device
->ChannelName
[0] = FrontLeft
;
1517 device
->ChannelName
[1] = FrontRight
;
1518 device
->ChannelName
[2] = FrontCenter
;
1519 device
->ChannelName
[3] = LFE
;
1520 device
->ChannelName
[4] = SideLeft
;
1521 device
->ChannelName
[5] = SideRight
;
1524 device
->ChannelName
[0] = FrontLeft
;
1525 device
->ChannelName
[1] = FrontRight
;
1526 device
->ChannelName
[2] = FrontCenter
;
1527 device
->ChannelName
[3] = LFE
;
1528 device
->ChannelName
[4] = BackLeft
;
1529 device
->ChannelName
[5] = BackRight
;
1532 device
->ChannelName
[0] = FrontLeft
;
1533 device
->ChannelName
[1] = FrontRight
;
1534 device
->ChannelName
[2] = FrontCenter
;
1535 device
->ChannelName
[3] = LFE
;
1536 device
->ChannelName
[4] = BackCenter
;
1537 device
->ChannelName
[5] = SideLeft
;
1538 device
->ChannelName
[6] = SideRight
;
1541 device
->ChannelName
[0] = FrontLeft
;
1542 device
->ChannelName
[1] = FrontRight
;
1543 device
->ChannelName
[2] = FrontCenter
;
1544 device
->ChannelName
[3] = LFE
;
1545 device
->ChannelName
[4] = BackLeft
;
1546 device
->ChannelName
[5] = BackRight
;
1547 device
->ChannelName
[6] = SideLeft
;
1548 device
->ChannelName
[7] = SideRight
;
1550 case DevFmtBFormat3D
:
1551 device
->ChannelName
[0] = BFormatW
;
1552 device
->ChannelName
[1] = BFormatX
;
1553 device
->ChannelName
[2] = BFormatY
;
1554 device
->ChannelName
[3] = BFormatZ
;
1559 /* SetDefaultChannelOrder
1561 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1563 void SetDefaultChannelOrder(ALCdevice
*device
)
1567 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1568 device
->ChannelName
[i
] = InvalidChannel
;
1570 switch(device
->FmtChans
)
1573 device
->ChannelName
[0] = FrontLeft
;
1574 device
->ChannelName
[1] = FrontRight
;
1575 device
->ChannelName
[2] = BackLeft
;
1576 device
->ChannelName
[3] = BackRight
;
1577 device
->ChannelName
[4] = FrontCenter
;
1578 device
->ChannelName
[5] = LFE
;
1581 device
->ChannelName
[0] = FrontLeft
;
1582 device
->ChannelName
[1] = FrontRight
;
1583 device
->ChannelName
[2] = BackLeft
;
1584 device
->ChannelName
[3] = BackRight
;
1585 device
->ChannelName
[4] = FrontCenter
;
1586 device
->ChannelName
[5] = LFE
;
1587 device
->ChannelName
[6] = SideLeft
;
1588 device
->ChannelName
[7] = SideRight
;
1591 /* Same as WFX order */
1597 case DevFmtBFormat3D
:
1598 SetDefaultWFXChannelOrder(device
);
1603 extern inline ALint
GetChannelIdxByName(const ALCdevice
*device
, enum Channel chan
);
1606 /* ALCcontext_DeferUpdates
1608 * Defers/suspends updates for the given context's listener and sources. This
1609 * does *NOT* stop mixing, but rather prevents certain property changes from
1612 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1614 ALCdevice
*device
= context
->Device
;
1617 SetMixerFPUMode(&oldMode
);
1619 V0(device
->Backend
,lock
)();
1620 if(!context
->DeferUpdates
)
1622 context
->DeferUpdates
= AL_TRUE
;
1624 /* Make sure all pending updates are performed */
1625 UpdateContextSources(context
);
1626 #define UPDATE_SLOT(iter) do { \
1627 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1628 V((*iter)->EffectState,update)(device, *iter); \
1630 VECTOR_FOR_EACH(ALeffectslot
*, context
->ActiveAuxSlots
, UPDATE_SLOT
);
1633 V0(device
->Backend
,unlock
)();
1635 RestoreFPUMode(&oldMode
);
1638 /* ALCcontext_ProcessUpdates
1640 * Resumes update processing after being deferred.
1642 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1644 ALCdevice
*device
= context
->Device
;
1646 V0(device
->Backend
,lock
)();
1647 if(context
->DeferUpdates
)
1651 context
->DeferUpdates
= AL_FALSE
;
1653 LockUIntMapRead(&context
->SourceMap
);
1654 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1656 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1659 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1660 Source
->Offset
>= 0.0)
1662 ReadLock(&Source
->queue_lock
);
1663 ApplyOffset(Source
);
1664 ReadUnlock(&Source
->queue_lock
);
1667 new_state
= Source
->new_state
;
1668 Source
->new_state
= AL_NONE
;
1670 SetSourceState(Source
, context
, new_state
);
1672 UnlockUIntMapRead(&context
->SourceMap
);
1674 V0(device
->Backend
,unlock
)();
1680 * Stores the latest ALC device error
1682 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1687 /* DebugBreak() will cause an exception if there is no debugger */
1688 if(IsDebuggerPresent())
1690 #elif defined(SIGTRAP)
1696 ATOMIC_STORE(&device
->LastError
, errorCode
);
1698 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1704 * Updates the device's base clock time with however many samples have been
1705 * done. This is used so frequency changes on the device don't cause the time
1706 * to jump forward or back.
1708 static inline void UpdateClockBase(ALCdevice
*device
)
1710 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1711 device
->SamplesDone
= 0;
1714 /* UpdateDeviceParams
1716 * Updates device parameters according to the attribute list (caller is
1717 * responsible for holding the list lock).
1719 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1721 ALCcontext
*context
;
1722 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1723 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1724 enum DevFmtChannels oldChans
;
1725 enum DevFmtType oldType
;
1730 // Check for attributes
1731 if(device
->Type
== Loopback
)
1737 GotAll
= GotFreq
|GotChans
|GotType
1739 ALCuint freq
, numMono
, numStereo
, numSends
;
1740 enum DevFmtChannels schans
;
1741 enum DevFmtType stype
;
1742 ALCuint attrIdx
= 0;
1747 WARN("Missing attributes for loopback device\n");
1748 return ALC_INVALID_VALUE
;
1751 numMono
= device
->NumMonoSources
;
1752 numStereo
= device
->NumStereoSources
;
1753 numSends
= device
->NumAuxSends
;
1754 schans
= device
->FmtChans
;
1755 stype
= device
->FmtType
;
1756 freq
= device
->Frequency
;
1758 while(attrList
[attrIdx
])
1760 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1762 ALCint val
= attrList
[attrIdx
+ 1];
1763 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1764 return ALC_INVALID_VALUE
;
1769 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1771 ALCint val
= attrList
[attrIdx
+ 1];
1772 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1773 return ALC_INVALID_VALUE
;
1778 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1780 freq
= attrList
[attrIdx
+ 1];
1781 if(freq
< MIN_OUTPUT_RATE
)
1782 return ALC_INVALID_VALUE
;
1786 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1788 numStereo
= attrList
[attrIdx
+ 1];
1789 if(numStereo
> device
->MaxNoOfSources
)
1790 numStereo
= device
->MaxNoOfSources
;
1792 numMono
= device
->MaxNoOfSources
- numStereo
;
1795 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1796 numSends
= attrList
[attrIdx
+ 1];
1798 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1800 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1801 hrtf_appreq
= Hrtf_Disable
;
1802 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1803 hrtf_appreq
= Hrtf_Enable
;
1805 hrtf_appreq
= Hrtf_Default
;
1811 if(gotFmt
!= GotAll
)
1813 WARN("Missing format for loopback device\n");
1814 return ALC_INVALID_VALUE
;
1817 ConfigValueUInt(NULL
, NULL
, "sends", &numSends
);
1818 numSends
= minu(MAX_SENDS
, numSends
);
1820 if((device
->Flags
&DEVICE_RUNNING
))
1821 V0(device
->Backend
,stop
)();
1822 device
->Flags
&= ~DEVICE_RUNNING
;
1824 UpdateClockBase(device
);
1826 device
->Frequency
= freq
;
1827 device
->FmtChans
= schans
;
1828 device
->FmtType
= stype
;
1829 device
->NumMonoSources
= numMono
;
1830 device
->NumStereoSources
= numStereo
;
1831 device
->NumAuxSends
= numSends
;
1833 else if(attrList
&& attrList
[0])
1835 ALCuint freq
, numMono
, numStereo
, numSends
;
1836 ALCuint attrIdx
= 0;
1838 /* If a context is already running on the device, stop playback so the
1839 * device attributes can be updated. */
1840 if((device
->Flags
&DEVICE_RUNNING
))
1841 V0(device
->Backend
,stop
)();
1842 device
->Flags
&= ~DEVICE_RUNNING
;
1844 freq
= device
->Frequency
;
1845 numMono
= device
->NumMonoSources
;
1846 numStereo
= device
->NumStereoSources
;
1847 numSends
= device
->NumAuxSends
;
1849 while(attrList
[attrIdx
])
1851 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1853 freq
= attrList
[attrIdx
+ 1];
1854 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1857 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1859 numStereo
= attrList
[attrIdx
+ 1];
1860 if(numStereo
> device
->MaxNoOfSources
)
1861 numStereo
= device
->MaxNoOfSources
;
1863 numMono
= device
->MaxNoOfSources
- numStereo
;
1866 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1867 numSends
= attrList
[attrIdx
+ 1];
1869 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1871 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1872 hrtf_appreq
= Hrtf_Disable
;
1873 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1874 hrtf_appreq
= Hrtf_Enable
;
1876 hrtf_appreq
= Hrtf_Default
;
1882 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1883 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1885 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1886 numSends
= minu(MAX_SENDS
, numSends
);
1888 UpdateClockBase(device
);
1890 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1892 /* SSE and Neon do best with the update size being a multiple of 4 */
1893 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1894 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1896 device
->Frequency
= freq
;
1897 device
->NumMonoSources
= numMono
;
1898 device
->NumStereoSources
= numStereo
;
1899 device
->NumAuxSends
= numSends
;
1902 if((device
->Flags
&DEVICE_RUNNING
))
1903 return ALC_NO_ERROR
;
1905 al_free(device
->DryBuffer
);
1906 device
->DryBuffer
= NULL
;
1908 UpdateClockBase(device
);
1910 device
->Hrtf_Status
= ALC_HRTF_DISABLED_SOFT
;
1911 if(device
->Type
!= Loopback
)
1914 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
1916 if(strcasecmp(hrtf
, "true") == 0)
1917 hrtf_userreq
= Hrtf_Enable
;
1918 else if(strcasecmp(hrtf
, "false") == 0)
1919 hrtf_userreq
= Hrtf_Disable
;
1920 else if(strcasecmp(hrtf
, "auto") != 0)
1921 ERR("Unexpected hrtf value: %s\n", hrtf
);
1924 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
1926 if(FindHrtfFormat(device
->DeviceName
, &device
->FmtChans
, &device
->Frequency
))
1927 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
1930 hrtf_userreq
= hrtf_appreq
= Hrtf_Default
;
1931 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1935 else if(hrtf_appreq
== Hrtf_Enable
)
1937 enum DevFmtChannels chans
= device
->FmtChans
;
1938 ALCuint freq
= device
->Frequency
;
1939 if(!FindHrtfFormat(device
->DeviceName
, &chans
, &freq
) ||
1940 chans
!= device
->FmtChans
|| freq
!= device
->Frequency
)
1942 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1943 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1944 hrtf_appreq
= Hrtf_Default
;
1945 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1949 oldFreq
= device
->Frequency
;
1950 oldChans
= device
->FmtChans
;
1951 oldType
= device
->FmtType
;
1953 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1954 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1955 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1956 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1957 device
->UpdateSize
, device
->NumUpdates
1960 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1961 return ALC_INVALID_DEVICE
;
1963 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1965 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1966 DevFmtChannelsString(device
->FmtChans
));
1967 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1969 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1971 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1972 DevFmtTypeString(device
->FmtType
));
1973 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1975 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1977 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1978 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1981 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1982 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1983 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1986 if((device
->UpdateSize
&3) != 0)
1988 if((CPUCapFlags
&CPU_CAP_SSE
))
1989 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1990 if((CPUCapFlags
&CPU_CAP_NEON
))
1991 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1994 device
->Hrtf
= NULL
;
1995 device
->Hrtf_Mode
= DisabledHrtf
;
1996 if(device
->FmtChans
!= DevFmtStereo
)
1998 if(hrtf_appreq
== Hrtf_Enable
)
1999 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2002 device
->Bs2b
= NULL
;
2006 bool headphones
= device
->IsHeadphones
;
2007 enum HrtfMode hrtf_mode
= FullHrtf
;
2008 ALCenum hrtf_status
= device
->Hrtf_Status
;
2013 if(device
->Type
!= Loopback
)
2015 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "stereo-mode", &mode
))
2017 if(strcasecmp(mode
, "headphones") == 0)
2019 else if(strcasecmp(mode
, "speakers") == 0)
2021 else if(strcasecmp(mode
, "auto") != 0)
2022 ERR("Unexpected stereo-mode: %s\n", mode
);
2025 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf-mode", &mode
))
2027 if(strcasecmp(mode
, "full") == 0)
2028 hrtf_mode
= FullHrtf
;
2029 else if(strcasecmp(mode
, "basic") == 0)
2030 hrtf_mode
= BasicHrtf
;
2032 ERR("Unexpected hrtf-mode: %s\n", mode
);
2037 if(hrtf_userreq
== Hrtf_Default
)
2039 usehrtf
= (headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2040 (hrtf_appreq
== Hrtf_Enable
);
2041 if(headphones
&& hrtf_appreq
!= Hrtf_Disable
)
2042 hrtf_status
= ALC_HRTF_HEADPHONES_DETECTED_SOFT
;
2044 hrtf_status
= ALC_HRTF_ENABLED_SOFT
;
2048 usehrtf
= (hrtf_userreq
== Hrtf_Enable
);
2050 hrtf_status
= ALC_HRTF_DENIED_SOFT
;
2052 hrtf_status
= ALC_HRTF_REQUIRED_SOFT
;
2056 device
->Hrtf_Status
= hrtf_status
;
2059 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2060 device
->Hrtf
= GetHrtf(device
->DeviceName
, device
->FmtChans
, device
->Frequency
);
2064 device
->Hrtf_Mode
= hrtf_mode
;
2065 device
->Hrtf_Status
= hrtf_status
;
2066 TRACE("HRTF enabled\n");
2068 device
->Bs2b
= NULL
;
2072 TRACE("HRTF disabled\n");
2074 bs2blevel
= ((headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2075 (hrtf_appreq
== Hrtf_Enable
)) ? 5 : 0;
2076 if(device
->Type
!= Loopback
)
2077 ConfigValueInt(al_string_get_cstr(device
->DeviceName
), NULL
, "cf_level", &bs2blevel
);
2078 if(bs2blevel
> 0 && bs2blevel
<= 6)
2082 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
2083 bs2b_clear(device
->Bs2b
);
2085 bs2b_set_params(device
->Bs2b
, bs2blevel
, device
->Frequency
);
2086 TRACE("BS2B enabled\n");
2091 device
->Bs2b
= NULL
;
2092 TRACE("BS2B disabled\n");
2097 aluInitPanning(device
);
2099 /* With HRTF, allocate two extra channels for the post-filter output. */
2100 size
= sizeof(device
->DryBuffer
[0]) * (device
->NumChannels
+ (device
->Hrtf
? 2 : 0));
2101 device
->DryBuffer
= al_calloc(16, size
);
2102 if(!device
->DryBuffer
)
2104 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2105 return ALC_INVALID_DEVICE
;
2108 V(device
->Synth
,update
)(device
);
2110 SetMixerFPUMode(&oldMode
);
2111 V0(device
->Backend
,lock
)();
2112 context
= ATOMIC_LOAD(&device
->ContextList
);
2117 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2118 LockUIntMapRead(&context
->EffectSlotMap
);
2119 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2121 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2123 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2125 UnlockUIntMapRead(&context
->EffectSlotMap
);
2126 V0(device
->Backend
,unlock
)();
2127 RestoreFPUMode(&oldMode
);
2128 return ALC_INVALID_DEVICE
;
2130 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2131 V(slot
->EffectState
,update
)(device
, slot
);
2133 UnlockUIntMapRead(&context
->EffectSlotMap
);
2135 LockUIntMapRead(&context
->SourceMap
);
2136 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2138 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2139 ALuint s
= device
->NumAuxSends
;
2140 while(s
< MAX_SENDS
)
2142 if(source
->Send
[s
].Slot
)
2143 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2144 source
->Send
[s
].Slot
= NULL
;
2145 source
->Send
[s
].Gain
= 1.0f
;
2146 source
->Send
[s
].GainHF
= 1.0f
;
2149 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2151 UnlockUIntMapRead(&context
->SourceMap
);
2153 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2155 ALvoice
*voice
= &context
->Voices
[pos
];
2156 ALsource
*source
= voice
->Source
;
2157 ALuint s
= device
->NumAuxSends
;
2159 while(s
< MAX_SENDS
)
2161 voice
->Send
[s
].Moving
= AL_FALSE
;
2162 voice
->Send
[s
].Counter
= 0;
2168 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2169 voice
->Update(voice
, source
, context
);
2173 context
= context
->next
;
2175 if(device
->DefaultSlot
)
2177 ALeffectslot
*slot
= device
->DefaultSlot
;
2179 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2181 V0(device
->Backend
,unlock
)();
2182 RestoreFPUMode(&oldMode
);
2183 return ALC_INVALID_DEVICE
;
2185 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2186 V(slot
->EffectState
,update
)(device
, slot
);
2188 V0(device
->Backend
,unlock
)();
2189 RestoreFPUMode(&oldMode
);
2191 if(!(device
->Flags
&DEVICE_PAUSED
))
2193 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2194 return ALC_INVALID_DEVICE
;
2195 device
->Flags
|= DEVICE_RUNNING
;
2198 return ALC_NO_ERROR
;
2203 * Frees the device structure, and destroys any objects the app failed to
2204 * delete. Called once there's no more references on the device.
2206 static ALCvoid
FreeDevice(ALCdevice
*device
)
2208 TRACE("%p\n", device
);
2210 V0(device
->Backend
,close
)();
2211 DELETE_OBJ(device
->Backend
);
2212 device
->Backend
= NULL
;
2214 DELETE_OBJ(device
->Synth
);
2215 device
->Synth
= NULL
;
2217 if(device
->DefaultSlot
)
2219 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2220 device
->DefaultSlot
= NULL
;
2224 if(device
->DefaultSfont
)
2225 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
2226 device
->DefaultSfont
= NULL
;
2228 if(device
->BufferMap
.size
> 0)
2230 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2231 ReleaseALBuffers(device
);
2233 ResetUIntMap(&device
->BufferMap
);
2235 if(device
->EffectMap
.size
> 0)
2237 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2238 ReleaseALEffects(device
);
2240 ResetUIntMap(&device
->EffectMap
);
2242 if(device
->FilterMap
.size
> 0)
2244 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2245 ReleaseALFilters(device
);
2247 ResetUIntMap(&device
->FilterMap
);
2249 if(device
->SfontMap
.size
> 0)
2251 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2252 ReleaseALSoundfonts(device
);
2254 ResetUIntMap(&device
->SfontMap
);
2256 if(device
->PresetMap
.size
> 0)
2258 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2259 ReleaseALPresets(device
);
2261 ResetUIntMap(&device
->PresetMap
);
2263 if(device
->FontsoundMap
.size
> 0)
2265 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2266 ReleaseALFontsounds(device
);
2268 ResetUIntMap(&device
->FontsoundMap
);
2271 device
->Bs2b
= NULL
;
2273 AL_STRING_DEINIT(device
->DeviceName
);
2275 al_free(device
->DryBuffer
);
2276 device
->DryBuffer
= NULL
;
2282 void ALCdevice_IncRef(ALCdevice
*device
)
2285 ref
= IncrementRef(&device
->ref
);
2286 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2289 void ALCdevice_DecRef(ALCdevice
*device
)
2292 ref
= DecrementRef(&device
->ref
);
2293 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2294 if(ref
== 0) FreeDevice(device
);
2299 * Checks if the device handle is valid, and increments its ref count if so.
2301 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2303 ALCdevice
*tmpDevice
;
2309 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2310 while(tmpDevice
&& tmpDevice
!= device
)
2311 tmpDevice
= tmpDevice
->next
;
2314 ALCdevice_IncRef(tmpDevice
);
2322 * Initializes context fields
2324 static ALvoid
InitContext(ALCcontext
*Context
)
2326 ALlistener
*listener
= Context
->Listener
;
2327 //Initialise listener
2328 listener
->Gain
= 1.0f
;
2329 listener
->MetersPerUnit
= 1.0f
;
2330 aluVectorSet(&listener
->Position
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
2331 aluVectorSet(&listener
->Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2332 listener
->Forward
[0] = 0.0f
;
2333 listener
->Forward
[1] = 0.0f
;
2334 listener
->Forward
[2] = -1.0f
;
2335 listener
->Up
[0] = 0.0f
;
2336 listener
->Up
[1] = 1.0f
;
2337 listener
->Up
[2] = 0.0f
;
2338 aluMatrixSet(&listener
->Params
.Matrix
,
2339 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2340 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2341 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2342 0.0f
, 0.0f
, 0.0f
, 1.0f
2344 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2347 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2348 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2349 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2350 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2353 Context
->DistanceModel
= DefaultDistanceModel
;
2354 Context
->SourceDistanceModel
= AL_FALSE
;
2355 Context
->DopplerFactor
= 1.0f
;
2356 Context
->DopplerVelocity
= 1.0f
;
2357 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2358 Context
->DeferUpdates
= AL_FALSE
;
2360 Context
->ExtensionList
= alExtList
;
2366 * Cleans up the context, and destroys any remaining objects the app failed to
2367 * delete. Called once there's no more references on the context.
2369 static void FreeContext(ALCcontext
*context
)
2371 TRACE("%p\n", context
);
2373 if(context
->SourceMap
.size
> 0)
2375 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2376 ReleaseALSources(context
);
2378 ResetUIntMap(&context
->SourceMap
);
2380 if(context
->EffectSlotMap
.size
> 0)
2382 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2383 ReleaseALAuxiliaryEffectSlots(context
);
2385 ResetUIntMap(&context
->EffectSlotMap
);
2387 al_free(context
->Voices
);
2388 context
->Voices
= NULL
;
2389 context
->VoiceCount
= 0;
2390 context
->MaxVoices
= 0;
2392 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2394 ALCdevice_DecRef(context
->Device
);
2395 context
->Device
= NULL
;
2397 //Invalidate context
2398 memset(context
, 0, sizeof(ALCcontext
));
2404 * Removes the context reference from the given device and removes it from
2405 * being current on the running thread or globally.
2407 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2409 ALCcontext
*nextctx
;
2410 ALCcontext
*origctx
;
2412 if(altss_get(LocalContext
) == context
)
2414 WARN("%p released while current on thread\n", context
);
2415 altss_set(LocalContext
, NULL
);
2416 ALCcontext_DecRef(context
);
2420 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2421 ALCcontext_DecRef(context
);
2423 ALCdevice_Lock(device
);
2425 nextctx
= context
->next
;
2426 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2432 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2434 ALCdevice_Unlock(device
);
2436 ALCcontext_DecRef(context
);
2439 void ALCcontext_IncRef(ALCcontext
*context
)
2442 ref
= IncrementRef(&context
->ref
);
2443 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2446 void ALCcontext_DecRef(ALCcontext
*context
)
2449 ref
= DecrementRef(&context
->ref
);
2450 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2451 if(ref
== 0) FreeContext(context
);
2454 static void ReleaseThreadCtx(void *ptr
)
2456 WARN("%p current for thread being destroyed\n", ptr
);
2457 ALCcontext_DecRef(ptr
);
2462 * Checks that the given context is valid, and increments its reference count.
2464 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2469 dev
= ATOMIC_LOAD(&DeviceList
);
2472 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2477 ALCcontext_IncRef(ctx
);
2493 * Returns the currently active context for this thread, and adds a reference
2494 * without locking it.
2496 ALCcontext
*GetContextRef(void)
2498 ALCcontext
*context
;
2500 context
= altss_get(LocalContext
);
2502 ALCcontext_IncRef(context
);
2506 context
= ATOMIC_LOAD(&GlobalContext
);
2508 ALCcontext_IncRef(context
);
2516 /************************************************
2517 * Standard ALC functions
2518 ************************************************/
2522 * Return last ALC generated error code for the given device
2524 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2528 if(VerifyDevice(device
))
2530 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2531 ALCdevice_DecRef(device
);
2534 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2540 /* alcSuspendContext
2542 * Suspends updates for the given context
2544 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2549 context
= VerifyContext(context
);
2551 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2554 ALCcontext_DeferUpdates(context
);
2555 ALCcontext_DecRef(context
);
2559 /* alcProcessContext
2561 * Resumes processing updates for the given context
2563 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2568 context
= VerifyContext(context
);
2570 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2573 ALCcontext_ProcessUpdates(context
);
2574 ALCcontext_DecRef(context
);
2581 * Returns information about the device, and error strings
2583 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2585 const ALCchar
*value
= NULL
;
2593 case ALC_INVALID_ENUM
:
2594 value
= alcErrInvalidEnum
;
2597 case ALC_INVALID_VALUE
:
2598 value
= alcErrInvalidValue
;
2601 case ALC_INVALID_DEVICE
:
2602 value
= alcErrInvalidDevice
;
2605 case ALC_INVALID_CONTEXT
:
2606 value
= alcErrInvalidContext
;
2609 case ALC_OUT_OF_MEMORY
:
2610 value
= alcErrOutOfMemory
;
2613 case ALC_DEVICE_SPECIFIER
:
2614 value
= alcDefaultName
;
2617 case ALC_ALL_DEVICES_SPECIFIER
:
2618 if(VerifyDevice(Device
))
2620 value
= al_string_get_cstr(Device
->DeviceName
);
2621 ALCdevice_DecRef(Device
);
2625 ProbeAllDevicesList();
2626 value
= al_string_get_cstr(alcAllDevicesList
);
2630 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2631 if(VerifyDevice(Device
))
2633 value
= al_string_get_cstr(Device
->DeviceName
);
2634 ALCdevice_DecRef(Device
);
2638 ProbeCaptureDeviceList();
2639 value
= al_string_get_cstr(alcCaptureDeviceList
);
2643 /* Default devices are always first in the list */
2644 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2645 value
= alcDefaultName
;
2648 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2649 if(al_string_empty(alcAllDevicesList
))
2650 ProbeAllDevicesList();
2652 Device
= VerifyDevice(Device
);
2654 free(alcDefaultAllDevicesSpecifier
);
2655 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2656 if(!alcDefaultAllDevicesSpecifier
)
2657 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2659 value
= alcDefaultAllDevicesSpecifier
;
2660 if(Device
) ALCdevice_DecRef(Device
);
2663 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2664 if(al_string_empty(alcCaptureDeviceList
))
2665 ProbeCaptureDeviceList();
2667 Device
= VerifyDevice(Device
);
2669 free(alcCaptureDefaultDeviceSpecifier
);
2670 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2671 if(!alcCaptureDefaultDeviceSpecifier
)
2672 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2674 value
= alcCaptureDefaultDeviceSpecifier
;
2675 if(Device
) ALCdevice_DecRef(Device
);
2678 case ALC_EXTENSIONS
:
2679 if(!VerifyDevice(Device
))
2680 value
= alcNoDeviceExtList
;
2683 value
= alcExtensionList
;
2684 ALCdevice_DecRef(Device
);
2689 Device
= VerifyDevice(Device
);
2690 alcSetError(Device
, ALC_INVALID_ENUM
);
2691 if(Device
) ALCdevice_DecRef(Device
);
2699 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2703 if(size
<= 0 || values
== NULL
)
2705 alcSetError(device
, ALC_INVALID_VALUE
);
2713 case ALC_MAJOR_VERSION
:
2714 values
[0] = alcMajorVersion
;
2716 case ALC_MINOR_VERSION
:
2717 values
[0] = alcMinorVersion
;
2720 case ALC_ATTRIBUTES_SIZE
:
2721 case ALC_ALL_ATTRIBUTES
:
2725 case ALC_MONO_SOURCES
:
2726 case ALC_STEREO_SOURCES
:
2727 case ALC_CAPTURE_SAMPLES
:
2728 case ALC_FORMAT_CHANNELS_SOFT
:
2729 case ALC_FORMAT_TYPE_SOFT
:
2730 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2734 alcSetError(NULL
, ALC_INVALID_ENUM
);
2740 if(device
->Type
== Capture
)
2744 case ALC_CAPTURE_SAMPLES
:
2745 V0(device
->Backend
,lock
)();
2746 values
[0] = V0(device
->Backend
,availableSamples
)();
2747 V0(device
->Backend
,unlock
)();
2751 values
[0] = device
->Connected
;
2755 alcSetError(device
, ALC_INVALID_ENUM
);
2764 case ALC_MAJOR_VERSION
:
2765 values
[0] = alcMajorVersion
;
2768 case ALC_MINOR_VERSION
:
2769 values
[0] = alcMinorVersion
;
2772 case ALC_EFX_MAJOR_VERSION
:
2773 values
[0] = alcEFXMajorVersion
;
2776 case ALC_EFX_MINOR_VERSION
:
2777 values
[0] = alcEFXMinorVersion
;
2780 case ALC_ATTRIBUTES_SIZE
:
2784 case ALC_ALL_ATTRIBUTES
:
2787 alcSetError(device
, ALC_INVALID_VALUE
);
2792 values
[i
++] = ALC_FREQUENCY
;
2793 values
[i
++] = device
->Frequency
;
2795 if(device
->Type
!= Loopback
)
2797 values
[i
++] = ALC_REFRESH
;
2798 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2800 values
[i
++] = ALC_SYNC
;
2801 values
[i
++] = ALC_FALSE
;
2805 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2806 values
[i
++] = device
->FmtChans
;
2808 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2809 values
[i
++] = device
->FmtType
;
2812 values
[i
++] = ALC_MONO_SOURCES
;
2813 values
[i
++] = device
->NumMonoSources
;
2815 values
[i
++] = ALC_STEREO_SOURCES
;
2816 values
[i
++] = device
->NumStereoSources
;
2818 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2819 values
[i
++] = device
->NumAuxSends
;
2821 values
[i
++] = ALC_HRTF_SOFT
;
2822 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2824 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2825 values
[i
++] = device
->Hrtf_Status
;
2831 values
[0] = device
->Frequency
;
2835 if(device
->Type
== Loopback
)
2837 alcSetError(device
, ALC_INVALID_DEVICE
);
2840 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2844 if(device
->Type
== Loopback
)
2846 alcSetError(device
, ALC_INVALID_DEVICE
);
2849 values
[0] = ALC_FALSE
;
2852 case ALC_FORMAT_CHANNELS_SOFT
:
2853 if(device
->Type
!= Loopback
)
2855 alcSetError(device
, ALC_INVALID_DEVICE
);
2858 values
[0] = device
->FmtChans
;
2861 case ALC_FORMAT_TYPE_SOFT
:
2862 if(device
->Type
!= Loopback
)
2864 alcSetError(device
, ALC_INVALID_DEVICE
);
2867 values
[0] = device
->FmtType
;
2870 case ALC_MONO_SOURCES
:
2871 values
[0] = device
->NumMonoSources
;
2874 case ALC_STEREO_SOURCES
:
2875 values
[0] = device
->NumStereoSources
;
2878 case ALC_MAX_AUXILIARY_SENDS
:
2879 values
[0] = device
->NumAuxSends
;
2883 values
[0] = device
->Connected
;
2887 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2890 case ALC_HRTF_STATUS_SOFT
:
2891 values
[0] = device
->Hrtf_Status
;
2895 alcSetError(device
, ALC_INVALID_ENUM
);
2903 * Returns information about the device and the version of OpenAL
2905 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2907 device
= VerifyDevice(device
);
2908 if(size
<= 0 || values
== NULL
)
2909 alcSetError(device
, ALC_INVALID_VALUE
);
2911 GetIntegerv(device
, param
, size
, values
);
2912 if(device
) ALCdevice_DecRef(device
);
2915 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2920 device
= VerifyDevice(device
);
2921 if(size
<= 0 || values
== NULL
)
2922 alcSetError(device
, ALC_INVALID_VALUE
);
2923 else if(!device
|| device
->Type
== Capture
)
2925 ivals
= malloc(size
* sizeof(ALCint
));
2926 size
= GetIntegerv(device
, pname
, size
, ivals
);
2927 for(i
= 0;i
< size
;i
++)
2928 values
[i
] = ivals
[i
];
2931 else /* render device */
2935 case ALC_ATTRIBUTES_SIZE
:
2939 case ALC_ALL_ATTRIBUTES
:
2941 alcSetError(device
, ALC_INVALID_VALUE
);
2946 V0(device
->Backend
,lock
)();
2947 values
[i
++] = ALC_FREQUENCY
;
2948 values
[i
++] = device
->Frequency
;
2950 if(device
->Type
!= Loopback
)
2952 values
[i
++] = ALC_REFRESH
;
2953 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2955 values
[i
++] = ALC_SYNC
;
2956 values
[i
++] = ALC_FALSE
;
2960 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2961 values
[i
++] = device
->FmtChans
;
2963 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2964 values
[i
++] = device
->FmtType
;
2967 values
[i
++] = ALC_MONO_SOURCES
;
2968 values
[i
++] = device
->NumMonoSources
;
2970 values
[i
++] = ALC_STEREO_SOURCES
;
2971 values
[i
++] = device
->NumStereoSources
;
2973 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2974 values
[i
++] = device
->NumAuxSends
;
2976 values
[i
++] = ALC_HRTF_SOFT
;
2977 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2979 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2980 values
[i
++] = device
->Hrtf_Status
;
2982 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2983 values
[i
++] = device
->ClockBase
+
2984 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2987 V0(device
->Backend
,unlock
)();
2991 case ALC_DEVICE_CLOCK_SOFT
:
2992 V0(device
->Backend
,lock
)();
2993 *values
= device
->ClockBase
+
2994 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2995 V0(device
->Backend
,unlock
)();
2999 ivals
= malloc(size
* sizeof(ALCint
));
3000 size
= GetIntegerv(device
, pname
, size
, ivals
);
3001 for(i
= 0;i
< size
;i
++)
3002 values
[i
] = ivals
[i
];
3008 ALCdevice_DecRef(device
);
3012 /* alcIsExtensionPresent
3014 * Determines if there is support for a particular extension
3016 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3018 ALCboolean bResult
= ALC_FALSE
;
3020 device
= VerifyDevice(device
);
3023 alcSetError(device
, ALC_INVALID_VALUE
);
3026 size_t len
= strlen(extName
);
3027 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3030 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3031 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3036 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3040 } while(isspace(*ptr
));
3045 ALCdevice_DecRef(device
);
3050 /* alcGetProcAddress
3052 * Retrieves the function address for a particular extension function
3054 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3056 ALCvoid
*ptr
= NULL
;
3060 device
= VerifyDevice(device
);
3061 alcSetError(device
, ALC_INVALID_VALUE
);
3062 if(device
) ALCdevice_DecRef(device
);
3067 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3069 ptr
= alcFunctions
[i
].address
;
3078 * Get the value for a particular ALC enumeration name
3080 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3086 device
= VerifyDevice(device
);
3087 alcSetError(device
, ALC_INVALID_VALUE
);
3088 if(device
) ALCdevice_DecRef(device
);
3093 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3095 val
= enumeration
[i
].value
;
3104 * Create and attach a context to the given device.
3106 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3108 ALCcontext
*ALContext
;
3112 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
3115 alcSetError(device
, ALC_INVALID_DEVICE
);
3116 if(device
) ALCdevice_DecRef(device
);
3120 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3122 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3125 alcSetError(device
, err
);
3126 if(err
== ALC_INVALID_DEVICE
)
3128 V0(device
->Backend
,lock
)();
3129 aluHandleDisconnect(device
);
3130 V0(device
->Backend
,unlock
)();
3132 ALCdevice_DecRef(device
);
3136 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3139 InitRef(&ALContext
->ref
, 1);
3140 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3142 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3144 ALContext
->VoiceCount
= 0;
3145 ALContext
->MaxVoices
= 256;
3146 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3148 if(!ALContext
|| !ALContext
->Voices
)
3150 if(!ATOMIC_LOAD(&device
->ContextList
))
3152 V0(device
->Backend
,stop
)();
3153 device
->Flags
&= ~DEVICE_RUNNING
;
3159 al_free(ALContext
->Voices
);
3160 ALContext
->Voices
= NULL
;
3162 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3168 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3169 ALCdevice_DecRef(device
);
3173 ALContext
->Device
= device
;
3174 ALCdevice_IncRef(device
);
3175 InitContext(ALContext
);
3178 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3180 ALContext
->next
= head
;
3181 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3185 ALCdevice_DecRef(device
);
3187 TRACE("Created context %p\n", ALContext
);
3191 /* alcDestroyContext
3193 * Remove a context from its device
3195 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3200 /* alcGetContextsDevice sets an error for invalid contexts */
3201 Device
= alcGetContextsDevice(context
);
3204 ReleaseContext(context
, Device
);
3205 if(!ATOMIC_LOAD(&Device
->ContextList
))
3207 V0(Device
->Backend
,stop
)();
3208 Device
->Flags
&= ~DEVICE_RUNNING
;
3215 /* alcGetCurrentContext
3217 * Returns the currently active context on the calling thread
3219 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3221 ALCcontext
*Context
= altss_get(LocalContext
);
3222 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3226 /* alcGetThreadContext
3228 * Returns the currently active thread-local context
3230 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3232 return altss_get(LocalContext
);
3236 /* alcMakeContextCurrent
3238 * Makes the given context the active process-wide context, and removes the
3239 * thread-local context for the calling thread.
3241 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3243 /* context must be valid or NULL */
3244 if(context
&& !(context
=VerifyContext(context
)))
3246 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3249 /* context's reference count is already incremented */
3250 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3251 if(context
) ALCcontext_DecRef(context
);
3253 if((context
=altss_get(LocalContext
)) != NULL
)
3255 altss_set(LocalContext
, NULL
);
3256 ALCcontext_DecRef(context
);
3262 /* alcSetThreadContext
3264 * Makes the given context the active context for the current thread
3266 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3270 /* context must be valid or NULL */
3271 if(context
&& !(context
=VerifyContext(context
)))
3273 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3276 /* context's reference count is already incremented */
3277 old
= altss_get(LocalContext
);
3278 altss_set(LocalContext
, context
);
3279 if(old
) ALCcontext_DecRef(old
);
3285 /* alcGetContextsDevice
3287 * Returns the device that a particular context is attached to
3289 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3293 if(!(Context
=VerifyContext(Context
)))
3295 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3298 Device
= Context
->Device
;
3299 ALCcontext_DecRef(Context
);
3305 /* alcResetDeviceSOFT
3307 * Resets the given device output, using the specified attribute list.
3309 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
3314 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
3317 alcSetError(device
, ALC_INVALID_DEVICE
);
3318 if(device
) ALCdevice_DecRef(device
);
3322 if((err
=UpdateDeviceParams(device
, attribs
)) != ALC_NO_ERROR
)
3325 alcSetError(device
, err
);
3326 if(err
== ALC_INVALID_DEVICE
)
3328 V0(device
->Backend
,lock
)();
3329 aluHandleDisconnect(device
);
3330 V0(device
->Backend
,unlock
)();
3332 ALCdevice_DecRef(device
);
3336 ALCdevice_DecRef(device
);
3343 * Opens the named device.
3345 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3353 if(!PlaybackBackend
.name
)
3355 alcSetError(NULL
, ALC_INVALID_VALUE
);
3359 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3361 /* Some old Windows apps hardcode these expecting OpenAL to use a
3362 * specific audio API, even when they're not enumerated. Creative's
3363 * router effectively ignores them too.
3365 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3366 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3371 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3374 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3379 InitRef(&device
->ref
, 1);
3380 device
->Connected
= ALC_TRUE
;
3381 device
->Type
= Playback
;
3382 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3385 device
->Bs2b
= NULL
;
3386 device
->Hrtf_Mode
= DisabledHrtf
;
3387 AL_STRING_INIT(device
->DeviceName
);
3388 device
->DryBuffer
= NULL
;
3390 ATOMIC_INIT(&device
->ContextList
, NULL
);
3392 device
->ClockBase
= 0;
3393 device
->SamplesDone
= 0;
3395 device
->MaxNoOfSources
= 256;
3396 device
->AuxiliaryEffectSlotMax
= 4;
3397 device
->NumAuxSends
= MAX_SENDS
;
3399 InitUIntMap(&device
->BufferMap
, ~0);
3400 InitUIntMap(&device
->EffectMap
, ~0);
3401 InitUIntMap(&device
->FilterMap
, ~0);
3402 InitUIntMap(&device
->SfontMap
, ~0);
3403 InitUIntMap(&device
->PresetMap
, ~0);
3404 InitUIntMap(&device
->FontsoundMap
, ~0);
3407 device
->FmtChans
= DevFmtChannelsDefault
;
3408 device
->FmtType
= DevFmtTypeDefault
;
3409 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3410 device
->IsHeadphones
= AL_FALSE
;
3411 device
->NumUpdates
= 4;
3412 device
->UpdateSize
= 1024;
3414 if(!PlaybackBackend
.getFactory
)
3415 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3416 ALCbackend_Playback
);
3419 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3420 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3422 if(!device
->Backend
)
3425 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3430 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3432 static const struct {
3433 const char name
[16];
3434 enum DevFmtChannels chans
;
3436 { "mono", DevFmtMono
},
3437 { "stereo", DevFmtStereo
},
3438 { "quad", DevFmtQuad
},
3439 { "surround51", DevFmtX51
},
3440 { "surround61", DevFmtX61
},
3441 { "surround71", DevFmtX71
},
3442 { "surround51rear", DevFmtX51Rear
},
3446 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3448 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3450 device
->FmtChans
= chanlist
[i
].chans
;
3451 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3455 if(i
== COUNTOF(chanlist
))
3456 ERR("Unsupported channels: %s\n", fmt
);
3458 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3460 static const struct {
3461 const char name
[16];
3462 enum DevFmtType type
;
3464 { "int8", DevFmtByte
},
3465 { "uint8", DevFmtUByte
},
3466 { "int16", DevFmtShort
},
3467 { "uint16", DevFmtUShort
},
3468 { "int32", DevFmtInt
},
3469 { "uint32", DevFmtUInt
},
3470 { "float32", DevFmtFloat
},
3474 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3476 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3478 device
->FmtType
= typelist
[i
].type
;
3479 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3483 if(i
== COUNTOF(typelist
))
3484 ERR("Unsupported sample-type: %s\n", fmt
);
3487 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3489 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3490 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3491 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3492 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3495 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3496 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3498 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3499 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3500 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3501 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3503 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->MaxNoOfSources
);
3504 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3506 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3507 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3509 ConfigValueUInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3510 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3512 device
->NumStereoSources
= 1;
3513 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3515 device
->Synth
= SynthCreate(device
);
3518 DELETE_OBJ(device
->Backend
);
3520 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3524 // Find a playback device to open
3525 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3527 DELETE_OBJ(device
->Synth
);
3528 DELETE_OBJ(device
->Backend
);
3530 alcSetError(NULL
, err
);
3534 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3536 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3537 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3539 device
->DefaultSlot
= NULL
;
3540 ERR("Failed to initialize the default effect slot\n");
3542 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3544 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3545 device
->DefaultSlot
= NULL
;
3547 ERR("Failed to initialize the default effect\n");
3552 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3554 device
->next
= head
;
3555 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3558 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3564 * Closes the given device.
3566 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3568 ALCdevice
*list
, *origdev
, *nextdev
;
3572 list
= ATOMIC_LOAD(&DeviceList
);
3576 } while((list
=list
->next
) != NULL
);
3577 if(!list
|| list
->Type
== Capture
)
3579 alcSetError(list
, ALC_INVALID_DEVICE
);
3585 nextdev
= device
->next
;
3586 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3591 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3595 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3598 ALCcontext
*next
= ctx
->next
;
3599 WARN("Releasing context %p\n", ctx
);
3600 ReleaseContext(ctx
, device
);
3603 if((device
->Flags
&DEVICE_RUNNING
))
3604 V0(device
->Backend
,stop
)();
3605 device
->Flags
&= ~DEVICE_RUNNING
;
3607 ALCdevice_DecRef(device
);
3613 /************************************************
3614 * ALC capture functions
3615 ************************************************/
3616 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3618 ALCdevice
*device
= NULL
;
3623 if(!CaptureBackend
.name
)
3625 alcSetError(NULL
, ALC_INVALID_VALUE
);
3631 alcSetError(NULL
, ALC_INVALID_VALUE
);
3635 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3638 device
= al_calloc(16, sizeof(ALCdevice
));
3641 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3646 InitRef(&device
->ref
, 1);
3647 device
->Connected
= ALC_TRUE
;
3648 device
->Type
= Capture
;
3650 AL_STRING_INIT(device
->DeviceName
);
3651 device
->DryBuffer
= NULL
;
3653 InitUIntMap(&device
->BufferMap
, ~0);
3654 InitUIntMap(&device
->EffectMap
, ~0);
3655 InitUIntMap(&device
->FilterMap
, ~0);
3656 InitUIntMap(&device
->SfontMap
, ~0);
3657 InitUIntMap(&device
->PresetMap
, ~0);
3658 InitUIntMap(&device
->FontsoundMap
, ~0);
3660 if(!CaptureBackend
.getFactory
)
3661 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3662 ALCbackend_Capture
);
3665 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3666 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3668 if(!device
->Backend
)
3671 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3675 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3676 device
->Frequency
= frequency
;
3678 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3679 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3682 alcSetError(NULL
, ALC_INVALID_ENUM
);
3685 device
->IsHeadphones
= AL_FALSE
;
3687 device
->UpdateSize
= samples
;
3688 device
->NumUpdates
= 1;
3690 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3693 alcSetError(NULL
, err
);
3698 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3700 device
->next
= head
;
3701 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3704 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3708 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3710 ALCdevice
*list
, *next
, *nextdev
;
3713 list
= ATOMIC_LOAD(&DeviceList
);
3717 } while((list
=list
->next
) != NULL
);
3718 if(!list
|| list
->Type
!= Capture
)
3720 alcSetError(list
, ALC_INVALID_DEVICE
);
3726 nextdev
= device
->next
;
3727 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3732 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3736 ALCdevice_DecRef(device
);
3741 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3743 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3744 alcSetError(device
, ALC_INVALID_DEVICE
);
3747 V0(device
->Backend
,lock
)();
3748 if(!device
->Connected
)
3749 alcSetError(device
, ALC_INVALID_DEVICE
);
3750 else if(!(device
->Flags
&DEVICE_RUNNING
))
3752 if(V0(device
->Backend
,start
)())
3753 device
->Flags
|= DEVICE_RUNNING
;
3756 aluHandleDisconnect(device
);
3757 alcSetError(device
, ALC_INVALID_DEVICE
);
3760 V0(device
->Backend
,unlock
)();
3763 if(device
) ALCdevice_DecRef(device
);
3766 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3768 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3769 alcSetError(device
, ALC_INVALID_DEVICE
);
3772 V0(device
->Backend
,lock
)();
3773 if((device
->Flags
&DEVICE_RUNNING
))
3774 V0(device
->Backend
,stop
)();
3775 device
->Flags
&= ~DEVICE_RUNNING
;
3776 V0(device
->Backend
,unlock
)();
3779 if(device
) ALCdevice_DecRef(device
);
3782 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3784 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3785 alcSetError(device
, ALC_INVALID_DEVICE
);
3788 ALCenum err
= ALC_INVALID_VALUE
;
3790 V0(device
->Backend
,lock
)();
3791 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3792 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3793 V0(device
->Backend
,unlock
)();
3795 if(err
!= ALC_NO_ERROR
)
3796 alcSetError(device
, err
);
3798 if(device
) ALCdevice_DecRef(device
);
3802 /************************************************
3803 * ALC loopback functions
3804 ************************************************/
3806 /* alcLoopbackOpenDeviceSOFT
3808 * Open a loopback device, for manual rendering.
3810 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3812 ALCbackendFactory
*factory
;
3817 /* Make sure the device name, if specified, is us. */
3818 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3820 alcSetError(NULL
, ALC_INVALID_VALUE
);
3824 device
= al_calloc(16, sizeof(ALCdevice
));
3827 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3832 InitRef(&device
->ref
, 1);
3833 device
->Connected
= ALC_TRUE
;
3834 device
->Type
= Loopback
;
3835 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3838 device
->Bs2b
= NULL
;
3839 device
->Hrtf_Mode
= DisabledHrtf
;
3840 AL_STRING_INIT(device
->DeviceName
);
3841 device
->DryBuffer
= NULL
;
3843 ATOMIC_INIT(&device
->ContextList
, NULL
);
3845 device
->ClockBase
= 0;
3846 device
->SamplesDone
= 0;
3848 device
->MaxNoOfSources
= 256;
3849 device
->AuxiliaryEffectSlotMax
= 4;
3850 device
->NumAuxSends
= MAX_SENDS
;
3852 InitUIntMap(&device
->BufferMap
, ~0);
3853 InitUIntMap(&device
->EffectMap
, ~0);
3854 InitUIntMap(&device
->FilterMap
, ~0);
3855 InitUIntMap(&device
->SfontMap
, ~0);
3856 InitUIntMap(&device
->PresetMap
, ~0);
3857 InitUIntMap(&device
->FontsoundMap
, ~0);
3859 factory
= ALCloopbackFactory_getFactory();
3860 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3861 if(!device
->Backend
)
3864 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3869 device
->NumUpdates
= 0;
3870 device
->UpdateSize
= 0;
3872 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3873 device
->FmtChans
= DevFmtChannelsDefault
;
3874 device
->FmtType
= DevFmtTypeDefault
;
3875 device
->IsHeadphones
= AL_FALSE
;
3877 ConfigValueUInt(NULL
, NULL
, "sources", &device
->MaxNoOfSources
);
3878 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3880 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3881 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3883 ConfigValueUInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
3884 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3886 device
->NumStereoSources
= 1;
3887 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3889 device
->Synth
= SynthCreate(device
);
3892 DELETE_OBJ(device
->Backend
);
3894 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3898 // Open the "backend"
3899 V(device
->Backend
,open
)("Loopback");
3902 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3904 device
->next
= head
;
3905 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3908 TRACE("Created device %p\n", device
);
3912 /* alcIsRenderFormatSupportedSOFT
3914 * Determines if the loopback device supports the given format for rendering.
3916 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3918 ALCboolean ret
= ALC_FALSE
;
3920 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3921 alcSetError(device
, ALC_INVALID_DEVICE
);
3923 alcSetError(device
, ALC_INVALID_VALUE
);
3926 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3927 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3928 freq
>= MIN_OUTPUT_RATE
)
3931 if(device
) ALCdevice_DecRef(device
);
3936 /* alcRenderSamplesSOFT
3938 * Renders some samples into a buffer, using the format last set by the
3939 * attributes given to alcCreateContext.
3941 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3943 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3944 alcSetError(device
, ALC_INVALID_DEVICE
);
3945 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3946 alcSetError(device
, ALC_INVALID_VALUE
);
3948 aluMixData(device
, buffer
, samples
);
3949 if(device
) ALCdevice_DecRef(device
);
3953 /************************************************
3954 * ALC DSP pause/resume functions
3955 ************************************************/
3957 /* alcDevicePauseSOFT
3959 * Pause the DSP to stop audio processing.
3961 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3963 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3964 alcSetError(device
, ALC_INVALID_DEVICE
);
3968 if((device
->Flags
&DEVICE_RUNNING
))
3969 V0(device
->Backend
,stop
)();
3970 device
->Flags
&= ~DEVICE_RUNNING
;
3971 device
->Flags
|= DEVICE_PAUSED
;
3974 if(device
) ALCdevice_DecRef(device
);
3977 /* alcDeviceResumeSOFT
3979 * Resume the DSP to restart audio processing.
3981 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3983 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3984 alcSetError(device
, ALC_INVALID_DEVICE
);
3988 if((device
->Flags
&DEVICE_PAUSED
))
3990 device
->Flags
&= ~DEVICE_PAUSED
;
3991 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3993 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3994 device
->Flags
|= DEVICE_RUNNING
;
3997 alcSetError(device
, ALC_INVALID_DEVICE
);
3998 V0(device
->Backend
,lock
)();
3999 aluHandleDisconnect(device
);
4000 V0(device
->Backend
,unlock
)();
4006 if(device
) ALCdevice_DecRef(device
);