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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, 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, NULL }
63 static struct BackendInfo BackendList
[] = {
64 #ifdef HAVE_PULSEAUDIO
65 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
68 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
71 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
74 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
77 { "solaris", NULL
, alc_solaris_init
, alc_solaris_deinit
, alc_solaris_probe
, EmptyFuncs
},
80 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
83 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
86 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
89 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
92 { "winmm", NULL
, alcWinMMInit
, alcWinMMDeinit
, alcWinMMProbe
, EmptyFuncs
},
95 { "port", NULL
, alc_pa_init
, alc_pa_deinit
, alc_pa_probe
, EmptyFuncs
},
98 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
101 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
103 { "wave", NULL
, alc_wave_init
, alc_wave_deinit
, alc_wave_probe
, EmptyFuncs
},
106 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
110 static struct BackendInfo PlaybackBackend
;
111 static struct BackendInfo CaptureBackend
;
114 /************************************************
115 * Functions, enums, and errors
116 ************************************************/
117 typedef struct ALCfunction
{
118 const ALCchar
*funcName
;
122 typedef struct ALCenums
{
123 const ALCchar
*enumName
;
127 #define DECL(x) { #x, (ALCvoid*)(x) }
128 static const ALCfunction alcFunctions
[] = {
129 DECL(alcCreateContext
),
130 DECL(alcMakeContextCurrent
),
131 DECL(alcProcessContext
),
132 DECL(alcSuspendContext
),
133 DECL(alcDestroyContext
),
134 DECL(alcGetCurrentContext
),
135 DECL(alcGetContextsDevice
),
137 DECL(alcCloseDevice
),
139 DECL(alcIsExtensionPresent
),
140 DECL(alcGetProcAddress
),
141 DECL(alcGetEnumValue
),
143 DECL(alcGetIntegerv
),
144 DECL(alcCaptureOpenDevice
),
145 DECL(alcCaptureCloseDevice
),
146 DECL(alcCaptureStart
),
147 DECL(alcCaptureStop
),
148 DECL(alcCaptureSamples
),
150 DECL(alcSetThreadContext
),
151 DECL(alcGetThreadContext
),
153 DECL(alcLoopbackOpenDeviceSOFT
),
154 DECL(alcIsRenderFormatSupportedSOFT
),
155 DECL(alcRenderSamplesSOFT
),
157 DECL(alcDevicePauseSOFT
),
158 DECL(alcDeviceResumeSOFT
),
160 DECL(alcGetInteger64vSOFT
),
175 DECL(alIsExtensionPresent
),
176 DECL(alGetProcAddress
),
177 DECL(alGetEnumValue
),
184 DECL(alGetListenerf
),
185 DECL(alGetListener3f
),
186 DECL(alGetListenerfv
),
187 DECL(alGetListeneri
),
188 DECL(alGetListener3i
),
189 DECL(alGetListeneriv
),
191 DECL(alDeleteSources
),
207 DECL(alSourceRewindv
),
208 DECL(alSourcePausev
),
211 DECL(alSourceRewind
),
213 DECL(alSourceQueueBuffers
),
214 DECL(alSourceUnqueueBuffers
),
216 DECL(alDeleteBuffers
),
231 DECL(alDopplerFactor
),
232 DECL(alDopplerVelocity
),
233 DECL(alSpeedOfSound
),
234 DECL(alDistanceModel
),
237 DECL(alDeleteFilters
),
248 DECL(alDeleteEffects
),
258 DECL(alGenAuxiliaryEffectSlots
),
259 DECL(alDeleteAuxiliaryEffectSlots
),
260 DECL(alIsAuxiliaryEffectSlot
),
261 DECL(alAuxiliaryEffectSloti
),
262 DECL(alAuxiliaryEffectSlotiv
),
263 DECL(alAuxiliaryEffectSlotf
),
264 DECL(alAuxiliaryEffectSlotfv
),
265 DECL(alGetAuxiliaryEffectSloti
),
266 DECL(alGetAuxiliaryEffectSlotiv
),
267 DECL(alGetAuxiliaryEffectSlotf
),
268 DECL(alGetAuxiliaryEffectSlotfv
),
270 DECL(alBufferSubDataSOFT
),
272 DECL(alBufferSamplesSOFT
),
273 DECL(alBufferSubSamplesSOFT
),
274 DECL(alGetBufferSamplesSOFT
),
275 DECL(alIsBufferFormatSupportedSOFT
),
277 DECL(alDeferUpdatesSOFT
),
278 DECL(alProcessUpdatesSOFT
),
281 DECL(alSource3dSOFT
),
282 DECL(alSourcedvSOFT
),
283 DECL(alGetSourcedSOFT
),
284 DECL(alGetSource3dSOFT
),
285 DECL(alGetSourcedvSOFT
),
286 DECL(alSourcei64SOFT
),
287 DECL(alSource3i64SOFT
),
288 DECL(alSourcei64vSOFT
),
289 DECL(alGetSourcei64SOFT
),
290 DECL(alGetSource3i64SOFT
),
291 DECL(alGetSourcei64vSOFT
),
293 DECL(alGenSoundfontsSOFT
),
294 DECL(alDeleteSoundfontsSOFT
),
295 DECL(alIsSoundfontSOFT
),
296 DECL(alSoundfontSamplesSOFT
),
297 DECL(alGetSoundfontSamplesSOFT
),
298 DECL(alSoundfontMapSamplesSOFT
),
299 DECL(alSoundfontUnmapSamplesSOFT
),
300 DECL(alGetSoundfontivSOFT
),
301 DECL(alSoundfontPresetsSOFT
),
302 DECL(alGenPresetsSOFT
),
303 DECL(alDeletePresetsSOFT
),
304 DECL(alIsPresetSOFT
),
306 DECL(alPresetivSOFT
),
307 DECL(alGetPresetivSOFT
),
308 DECL(alPresetFontsoundsSOFT
),
309 DECL(alGenFontsoundsSOFT
),
310 DECL(alDeleteFontsoundsSOFT
),
311 DECL(alIsFontsoundSOFT
),
312 DECL(alFontsoundiSOFT
),
313 DECL(alFontsound2iSOFT
),
314 DECL(alFontsoundivSOFT
),
315 DECL(alGetFontsoundivSOFT
),
316 DECL(alFontsoundModulatoriSOFT
),
317 DECL(alGetFontsoundModulatorivSOFT
),
318 DECL(alMidiSoundfontSOFT
),
319 DECL(alMidiSoundfontvSOFT
),
320 DECL(alMidiEventSOFT
),
321 DECL(alMidiSysExSOFT
),
322 DECL(alMidiPlaySOFT
),
323 DECL(alMidiPauseSOFT
),
324 DECL(alMidiStopSOFT
),
325 DECL(alMidiResetSOFT
),
326 DECL(alMidiGainSOFT
),
327 DECL(alGetInteger64SOFT
),
328 DECL(alGetInteger64vSOFT
),
329 DECL(alLoadSoundfontSOFT
),
335 #define DECL(x) { #x, (x) }
336 static const ALCenums enumeration
[] = {
341 DECL(ALC_MAJOR_VERSION
),
342 DECL(ALC_MINOR_VERSION
),
343 DECL(ALC_ATTRIBUTES_SIZE
),
344 DECL(ALC_ALL_ATTRIBUTES
),
345 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
346 DECL(ALC_DEVICE_SPECIFIER
),
347 DECL(ALC_ALL_DEVICES_SPECIFIER
),
348 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
349 DECL(ALC_EXTENSIONS
),
353 DECL(ALC_MONO_SOURCES
),
354 DECL(ALC_STEREO_SOURCES
),
355 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
356 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
357 DECL(ALC_CAPTURE_SAMPLES
),
360 DECL(ALC_EFX_MAJOR_VERSION
),
361 DECL(ALC_EFX_MINOR_VERSION
),
362 DECL(ALC_MAX_AUXILIARY_SENDS
),
364 DECL(ALC_FORMAT_CHANNELS_SOFT
),
365 DECL(ALC_FORMAT_TYPE_SOFT
),
368 DECL(ALC_STEREO_SOFT
),
370 DECL(ALC_5POINT1_SOFT
),
371 DECL(ALC_6POINT1_SOFT
),
372 DECL(ALC_7POINT1_SOFT
),
375 DECL(ALC_UNSIGNED_BYTE_SOFT
),
376 DECL(ALC_SHORT_SOFT
),
377 DECL(ALC_UNSIGNED_SHORT_SOFT
),
379 DECL(ALC_UNSIGNED_INT_SOFT
),
380 DECL(ALC_FLOAT_SOFT
),
383 DECL(ALC_INVALID_DEVICE
),
384 DECL(ALC_INVALID_CONTEXT
),
385 DECL(ALC_INVALID_ENUM
),
386 DECL(ALC_INVALID_VALUE
),
387 DECL(ALC_OUT_OF_MEMORY
),
395 DECL(AL_SOURCE_RELATIVE
),
396 DECL(AL_CONE_INNER_ANGLE
),
397 DECL(AL_CONE_OUTER_ANGLE
),
407 DECL(AL_ORIENTATION
),
408 DECL(AL_REFERENCE_DISTANCE
),
409 DECL(AL_ROLLOFF_FACTOR
),
410 DECL(AL_CONE_OUTER_GAIN
),
411 DECL(AL_MAX_DISTANCE
),
413 DECL(AL_SAMPLE_OFFSET
),
414 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
415 DECL(AL_BYTE_OFFSET
),
416 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
417 DECL(AL_SOURCE_TYPE
),
420 DECL(AL_UNDETERMINED
),
421 DECL(AL_METERS_PER_UNIT
),
422 DECL(AL_DIRECT_CHANNELS_SOFT
),
424 DECL(AL_DIRECT_FILTER
),
425 DECL(AL_AUXILIARY_SEND_FILTER
),
426 DECL(AL_AIR_ABSORPTION_FACTOR
),
427 DECL(AL_ROOM_ROLLOFF_FACTOR
),
428 DECL(AL_CONE_OUTER_GAINHF
),
429 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
430 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
431 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
433 DECL(AL_SOURCE_STATE
),
439 DECL(AL_BUFFERS_QUEUED
),
440 DECL(AL_BUFFERS_PROCESSED
),
442 DECL(AL_FORMAT_MONO8
),
443 DECL(AL_FORMAT_MONO16
),
444 DECL(AL_FORMAT_MONO_FLOAT32
),
445 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
446 DECL(AL_FORMAT_STEREO8
),
447 DECL(AL_FORMAT_STEREO16
),
448 DECL(AL_FORMAT_STEREO_FLOAT32
),
449 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
450 DECL(AL_FORMAT_MONO_IMA4
),
451 DECL(AL_FORMAT_STEREO_IMA4
),
452 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
453 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
454 DECL(AL_FORMAT_QUAD8_LOKI
),
455 DECL(AL_FORMAT_QUAD16_LOKI
),
456 DECL(AL_FORMAT_QUAD8
),
457 DECL(AL_FORMAT_QUAD16
),
458 DECL(AL_FORMAT_QUAD32
),
459 DECL(AL_FORMAT_51CHN8
),
460 DECL(AL_FORMAT_51CHN16
),
461 DECL(AL_FORMAT_51CHN32
),
462 DECL(AL_FORMAT_61CHN8
),
463 DECL(AL_FORMAT_61CHN16
),
464 DECL(AL_FORMAT_61CHN32
),
465 DECL(AL_FORMAT_71CHN8
),
466 DECL(AL_FORMAT_71CHN16
),
467 DECL(AL_FORMAT_71CHN32
),
468 DECL(AL_FORMAT_REAR8
),
469 DECL(AL_FORMAT_REAR16
),
470 DECL(AL_FORMAT_REAR32
),
471 DECL(AL_FORMAT_MONO_MULAW
),
472 DECL(AL_FORMAT_MONO_MULAW_EXT
),
473 DECL(AL_FORMAT_STEREO_MULAW
),
474 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
475 DECL(AL_FORMAT_QUAD_MULAW
),
476 DECL(AL_FORMAT_51CHN_MULAW
),
477 DECL(AL_FORMAT_61CHN_MULAW
),
478 DECL(AL_FORMAT_71CHN_MULAW
),
479 DECL(AL_FORMAT_REAR_MULAW
),
480 DECL(AL_FORMAT_MONO_ALAW_EXT
),
481 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
484 DECL(AL_MONO16_SOFT
),
485 DECL(AL_MONO32F_SOFT
),
486 DECL(AL_STEREO8_SOFT
),
487 DECL(AL_STEREO16_SOFT
),
488 DECL(AL_STEREO32F_SOFT
),
490 DECL(AL_QUAD16_SOFT
),
491 DECL(AL_QUAD32F_SOFT
),
493 DECL(AL_REAR16_SOFT
),
494 DECL(AL_REAR32F_SOFT
),
495 DECL(AL_5POINT1_8_SOFT
),
496 DECL(AL_5POINT1_16_SOFT
),
497 DECL(AL_5POINT1_32F_SOFT
),
498 DECL(AL_6POINT1_8_SOFT
),
499 DECL(AL_6POINT1_16_SOFT
),
500 DECL(AL_6POINT1_32F_SOFT
),
501 DECL(AL_7POINT1_8_SOFT
),
502 DECL(AL_7POINT1_16_SOFT
),
503 DECL(AL_7POINT1_32F_SOFT
),
506 DECL(AL_STEREO_SOFT
),
509 DECL(AL_5POINT1_SOFT
),
510 DECL(AL_6POINT1_SOFT
),
511 DECL(AL_7POINT1_SOFT
),
514 DECL(AL_UNSIGNED_BYTE_SOFT
),
516 DECL(AL_UNSIGNED_SHORT_SOFT
),
518 DECL(AL_UNSIGNED_INT_SOFT
),
520 DECL(AL_DOUBLE_SOFT
),
522 DECL(AL_UNSIGNED_BYTE3_SOFT
),
528 DECL(AL_INTERNAL_FORMAT_SOFT
),
529 DECL(AL_BYTE_LENGTH_SOFT
),
530 DECL(AL_SAMPLE_LENGTH_SOFT
),
531 DECL(AL_SEC_LENGTH_SOFT
),
532 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
533 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
540 DECL(AL_INVALID_NAME
),
541 DECL(AL_INVALID_ENUM
),
542 DECL(AL_INVALID_VALUE
),
543 DECL(AL_INVALID_OPERATION
),
544 DECL(AL_OUT_OF_MEMORY
),
551 DECL(AL_DOPPLER_FACTOR
),
552 DECL(AL_DOPPLER_VELOCITY
),
553 DECL(AL_DISTANCE_MODEL
),
554 DECL(AL_SPEED_OF_SOUND
),
555 DECL(AL_SOURCE_DISTANCE_MODEL
),
556 DECL(AL_DEFERRED_UPDATES_SOFT
),
558 DECL(AL_INVERSE_DISTANCE
),
559 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
560 DECL(AL_LINEAR_DISTANCE
),
561 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
562 DECL(AL_EXPONENT_DISTANCE
),
563 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
565 DECL(AL_FILTER_TYPE
),
566 DECL(AL_FILTER_NULL
),
567 DECL(AL_FILTER_LOWPASS
),
569 DECL(AL_FILTER_HIGHPASS
),
570 DECL(AL_FILTER_BANDPASS
),
573 DECL(AL_LOWPASS_GAIN
),
574 DECL(AL_LOWPASS_GAINHF
),
576 DECL(AL_EFFECT_TYPE
),
577 DECL(AL_EFFECT_NULL
),
578 DECL(AL_EFFECT_REVERB
),
579 DECL(AL_EFFECT_EAXREVERB
),
580 DECL(AL_EFFECT_CHORUS
),
581 DECL(AL_EFFECT_DISTORTION
),
582 DECL(AL_EFFECT_ECHO
),
583 DECL(AL_EFFECT_FLANGER
),
585 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
586 DECL(AL_EFFECT_VOCAL_MORPHER
),
587 DECL(AL_EFFECT_PITCH_SHIFTER
),
589 DECL(AL_EFFECT_RING_MODULATOR
),
590 DECL(AL_EFFECT_AUTOWAH
),
591 DECL(AL_EFFECT_COMPRESSOR
),
592 DECL(AL_EFFECT_EQUALIZER
),
593 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
594 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
596 DECL(AL_EAXREVERB_DENSITY
),
597 DECL(AL_EAXREVERB_DIFFUSION
),
598 DECL(AL_EAXREVERB_GAIN
),
599 DECL(AL_EAXREVERB_GAINHF
),
600 DECL(AL_EAXREVERB_GAINLF
),
601 DECL(AL_EAXREVERB_DECAY_TIME
),
602 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
603 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
604 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
605 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
606 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
607 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
608 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
609 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
610 DECL(AL_EAXREVERB_ECHO_TIME
),
611 DECL(AL_EAXREVERB_ECHO_DEPTH
),
612 DECL(AL_EAXREVERB_MODULATION_TIME
),
613 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
614 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
615 DECL(AL_EAXREVERB_HFREFERENCE
),
616 DECL(AL_EAXREVERB_LFREFERENCE
),
617 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
618 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
620 DECL(AL_REVERB_DENSITY
),
621 DECL(AL_REVERB_DIFFUSION
),
622 DECL(AL_REVERB_GAIN
),
623 DECL(AL_REVERB_GAINHF
),
624 DECL(AL_REVERB_DECAY_TIME
),
625 DECL(AL_REVERB_DECAY_HFRATIO
),
626 DECL(AL_REVERB_REFLECTIONS_GAIN
),
627 DECL(AL_REVERB_REFLECTIONS_DELAY
),
628 DECL(AL_REVERB_LATE_REVERB_GAIN
),
629 DECL(AL_REVERB_LATE_REVERB_DELAY
),
630 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
631 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
632 DECL(AL_REVERB_DECAY_HFLIMIT
),
634 DECL(AL_CHORUS_WAVEFORM
),
635 DECL(AL_CHORUS_PHASE
),
636 DECL(AL_CHORUS_RATE
),
637 DECL(AL_CHORUS_DEPTH
),
638 DECL(AL_CHORUS_FEEDBACK
),
639 DECL(AL_CHORUS_DELAY
),
641 DECL(AL_DISTORTION_EDGE
),
642 DECL(AL_DISTORTION_GAIN
),
643 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
644 DECL(AL_DISTORTION_EQCENTER
),
645 DECL(AL_DISTORTION_EQBANDWIDTH
),
648 DECL(AL_ECHO_LRDELAY
),
649 DECL(AL_ECHO_DAMPING
),
650 DECL(AL_ECHO_FEEDBACK
),
651 DECL(AL_ECHO_SPREAD
),
653 DECL(AL_FLANGER_WAVEFORM
),
654 DECL(AL_FLANGER_PHASE
),
655 DECL(AL_FLANGER_RATE
),
656 DECL(AL_FLANGER_DEPTH
),
657 DECL(AL_FLANGER_FEEDBACK
),
658 DECL(AL_FLANGER_DELAY
),
660 DECL(AL_RING_MODULATOR_FREQUENCY
),
661 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
662 DECL(AL_RING_MODULATOR_WAVEFORM
),
664 DECL(AL_AUTOWAH_ATTACK_TIME
),
665 DECL(AL_AUTOWAH_PEAK_GAIN
),
666 DECL(AL_AUTOWAH_RELEASE_TIME
),
667 DECL(AL_AUTOWAH_RESONANCE
),
669 DECL(AL_COMPRESSOR_ONOFF
),
671 DECL(AL_EQUALIZER_LOW_GAIN
),
672 DECL(AL_EQUALIZER_LOW_CUTOFF
),
673 DECL(AL_EQUALIZER_MID1_GAIN
),
674 DECL(AL_EQUALIZER_MID1_CENTER
),
675 DECL(AL_EQUALIZER_MID1_WIDTH
),
676 DECL(AL_EQUALIZER_MID2_GAIN
),
677 DECL(AL_EQUALIZER_MID2_CENTER
),
678 DECL(AL_EQUALIZER_MID2_WIDTH
),
679 DECL(AL_EQUALIZER_HIGH_GAIN
),
680 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
682 DECL(AL_DEDICATED_GAIN
),
688 static const ALCchar alcNoError
[] = "No Error";
689 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
690 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
691 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
692 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
693 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
696 /************************************************
698 ************************************************/
700 /* Enumerated device names */
701 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
703 static al_string alcAllDevicesList
;
704 static al_string alcCaptureDeviceList
;
706 /* Default is always the first in the list */
707 static ALCchar
*alcDefaultAllDevicesSpecifier
;
708 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
710 /* Default context extensions */
711 static const ALchar alExtList
[] =
712 "AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 "
713 "AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW "
714 "AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model "
715 "AL_LOKI_quadriphonic AL_SOFTX_block_alignment AL_SOFT_buffer_samples "
716 "AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates AL_SOFT_direct_channels "
717 "AL_SOFT_loop_points AL_SOFTX_MSADPCM AL_SOFT_source_latency";
719 static volatile ALCenum LastNullDeviceError
= ALC_NO_ERROR
;
721 /* Thread-local current context */
722 static altss_t LocalContext
;
723 /* Process-wide current context */
724 static ALCcontext
*volatile GlobalContext
= NULL
;
726 /* Mixing thread piority level */
731 enum LogLevel LogLevel
= LogWarning
;
733 enum LogLevel LogLevel
= LogError
;
736 /* Flag to trap ALC device errors */
737 static ALCboolean TrapALCError
= ALC_FALSE
;
739 /* One-time configuration init control */
740 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
742 /* Default effect that applies to sources that don't have an effect on send 0 */
743 static ALeffect DefaultEffect
;
746 /************************************************
748 ************************************************/
749 static const ALCchar alcNoDeviceExtList
[] =
750 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
751 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
752 static const ALCchar alcExtensionList
[] =
753 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
754 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
755 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
756 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFTX_pause_device";
757 static const ALCint alcMajorVersion
= 1;
758 static const ALCint alcMinorVersion
= 1;
760 static const ALCint alcEFXMajorVersion
= 1;
761 static const ALCint alcEFXMinorVersion
= 0;
764 /************************************************
766 ************************************************/
767 static ALCdevice
*volatile DeviceList
= NULL
;
769 static almtx_t ListLock
;
770 static inline void LockLists(void)
772 int lockret
= almtx_lock(&ListLock
);
773 assert(lockret
== althrd_success
);
775 static inline void UnlockLists(void)
777 int unlockret
= almtx_unlock(&ListLock
);
778 assert(unlockret
== althrd_success
);
781 /************************************************
782 * Library initialization
783 ************************************************/
785 static void alc_init(void);
786 static void alc_deinit(void);
787 static void alc_deinit_safe(void);
789 #ifndef AL_LIBTYPE_STATIC
790 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
794 case DLL_PROCESS_ATTACH
:
795 /* Pin the DLL so we won't get unloaded until the process terminates */
796 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
797 (WCHAR
*)hModule
, &hModule
);
801 case DLL_THREAD_DETACH
:
804 case DLL_PROCESS_DETACH
:
813 #elif defined(_MSC_VER)
814 #pragma section(".CRT$XCU",read)
815 static void alc_constructor(void);
816 static void alc_destructor(void);
817 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
819 static void alc_constructor(void)
821 atexit(alc_destructor
);
825 static void alc_destructor(void)
829 #elif defined(HAVE_GCC_DESTRUCTOR)
830 static void alc_init(void) __attribute__((constructor
));
831 static void alc_deinit(void) __attribute__((destructor
));
833 #error "No static initialization available on this platform!"
836 #elif defined(HAVE_GCC_DESTRUCTOR)
838 static void alc_init(void) __attribute__((constructor
));
839 static void alc_deinit(void) __attribute__((destructor
));
842 #error "No global initialization available on this platform!"
845 static void ReleaseThreadCtx(void *ptr
);
846 static void alc_init(void)
853 AL_STRING_INIT(alcAllDevicesList
);
854 AL_STRING_INIT(alcCaptureDeviceList
);
856 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
857 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
860 str
= getenv("__ALSOFT_REVERSE_Z");
861 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
864 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
865 assert(ret
== althrd_success
);
867 ret
= almtx_init(&ListLock
, almtx_recursive
);
868 assert(ret
== althrd_success
);
873 static void alc_initconfig(void)
875 const char *devs
, *str
;
880 str
= getenv("ALSOFT_LOGLEVEL");
883 long lvl
= strtol(str
, NULL
, 0);
884 if(lvl
>= NoLog
&& lvl
<= LogRef
)
888 str
= getenv("ALSOFT_LOGFILE");
891 FILE *logfile
= al_fopen(str
, "wt");
892 if(logfile
) LogFile
= logfile
;
893 else ERR("Failed to open log file '%s'\n", str
);
898 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
899 for(i
= 1;BackendList
[i
].name
;i
++)
900 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
901 TRACE("Supported backends: %s\n", buf
);
907 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
910 capfilter
|= CPU_CAP_NEON
;
912 if(ConfigValueStr(NULL
, "disable-cpu-exts", &str
))
914 if(strcasecmp(str
, "all") == 0)
919 const char *next
= str
;
923 while(isspace(str
[0]))
925 next
= strchr(str
, ',');
927 if(!str
[0] || str
[0] == ',')
930 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
931 while(len
> 0 && isspace(str
[len
-1]))
933 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
934 capfilter
&= ~CPU_CAP_SSE
;
935 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
936 capfilter
&= ~CPU_CAP_SSE2
;
937 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
938 capfilter
&= ~CPU_CAP_NEON
;
940 WARN("Invalid CPU extension \"%s\"\n", str
);
944 FillCPUCaps(capfilter
);
951 ConfigValueInt(NULL
, "rt-prio", &RTPrioLevel
);
953 if(ConfigValueStr(NULL
, "resampler", &str
))
955 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
956 DefaultResampler
= PointResampler
;
957 else if(strcasecmp(str
, "linear") == 0)
958 DefaultResampler
= LinearResampler
;
959 else if(strcasecmp(str
, "cubic") == 0)
960 DefaultResampler
= CubicResampler
;
965 n
= strtol(str
, &end
, 0);
966 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== CubicResampler
))
967 DefaultResampler
= n
;
969 WARN("Invalid resampler: %s\n", str
);
973 str
= getenv("ALSOFT_TRAP_ERROR");
974 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
976 TrapALError
= AL_TRUE
;
977 TrapALCError
= AL_TRUE
;
981 str
= getenv("ALSOFT_TRAP_AL_ERROR");
982 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
983 TrapALError
= AL_TRUE
;
984 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
986 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
987 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
988 TrapALCError
= ALC_TRUE
;
989 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
992 if(ConfigValueFloat("reverb", "boost", &valf
))
993 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
995 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
997 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
998 ConfigValueStr(NULL
, "drivers", &devs
))
1002 const char *next
= devs
;
1003 int endlist
, delitem
;
1008 while(isspace(devs
[0]))
1010 next
= strchr(devs
, ',');
1012 delitem
= (devs
[0] == '-');
1013 if(devs
[0] == '-') devs
++;
1015 if(!devs
[0] || devs
[0] == ',')
1022 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1023 while(len
> 0 && isspace(devs
[len
-1]))
1025 for(n
= i
;BackendList
[n
].name
;n
++)
1027 if(len
== strlen(BackendList
[n
].name
) &&
1028 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1033 BackendList
[n
] = BackendList
[n
+1];
1035 } while(BackendList
[n
].name
);
1039 struct BackendInfo Bkp
= BackendList
[n
];
1042 BackendList
[n
] = BackendList
[n
-1];
1045 BackendList
[n
] = Bkp
;
1056 BackendList
[i
].name
= NULL
;
1057 BackendList
[i
].getFactory
= NULL
;
1058 BackendList
[i
].Init
= NULL
;
1059 BackendList
[i
].Deinit
= NULL
;
1060 BackendList
[i
].Probe
= NULL
;
1064 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1066 if(BackendList
[i
].getFactory
)
1068 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1069 if(!V0(factory
,init
)())
1071 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1075 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1076 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1078 PlaybackBackend
= BackendList
[i
];
1079 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1081 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1083 CaptureBackend
= BackendList
[i
];
1084 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1090 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1092 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1096 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1097 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1099 PlaybackBackend
= BackendList
[i
];
1100 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1102 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1104 CaptureBackend
= BackendList
[i
];
1105 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1109 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1113 if(ConfigValueStr(NULL
, "excludefx", &str
))
1116 const char *next
= str
;
1120 next
= strchr(str
, ',');
1122 if(!str
[0] || next
== str
)
1125 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1126 for(n
= 0;EffectList
[n
].name
;n
++)
1128 if(len
== strlen(EffectList
[n
].name
) &&
1129 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1130 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1135 InitEffectFactoryMap();
1137 InitEffect(&DefaultEffect
);
1138 str
= getenv("ALSOFT_DEFAULT_REVERB");
1139 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1140 LoadReverbPreset(str
, &DefaultEffect
);
1142 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1145 /************************************************
1146 * Library deinitialization
1147 ************************************************/
1148 static void alc_cleanup(void)
1152 AL_STRING_DEINIT(alcAllDevicesList
);
1153 AL_STRING_DEINIT(alcCaptureDeviceList
);
1155 free(alcDefaultAllDevicesSpecifier
);
1156 alcDefaultAllDevicesSpecifier
= NULL
;
1157 free(alcCaptureDefaultDeviceSpecifier
);
1158 alcCaptureDefaultDeviceSpecifier
= NULL
;
1160 if((dev
=ExchangePtr((XchgPtr
*)&DeviceList
, NULL
)) != NULL
)
1165 } while((dev
=dev
->next
) != NULL
);
1166 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1169 DeinitEffectFactoryMap();
1172 static void alc_deinit_safe(void)
1180 almtx_destroy(&ListLock
);
1181 altss_delete(LocalContext
);
1183 if(LogFile
!= stderr
)
1188 static void alc_deinit(void)
1194 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1195 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1197 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1199 if(!BackendList
[i
].getFactory
)
1200 BackendList
[i
].Deinit();
1203 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1204 V0(factory
,deinit
)();
1208 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1209 V0(factory
,deinit
)();
1216 /************************************************
1217 * Device enumeration
1218 ************************************************/
1219 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1224 al_string_clear(list
);
1226 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1228 if(!PlaybackBackend
.getFactory
)
1229 PlaybackBackend
.Probe(type
);
1232 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1233 V(factory
,probe
)(type
);
1236 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1238 if(!CaptureBackend
.getFactory
)
1239 CaptureBackend
.Probe(type
);
1242 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1243 V(factory
,probe
)(type
);
1248 static void ProbeAllDevicesList(void)
1249 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1250 static void ProbeCaptureDeviceList(void)
1251 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1253 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1255 size_t len
= strlen(name
);
1258 al_string_append_range(devnames
, name
, name
+len
);
1259 al_string_append_char(devnames
, '\0');
1262 void AppendAllDevicesList(const ALCchar
*name
)
1263 { AppendDevice(name
, &alcAllDevicesList
); }
1264 void AppendCaptureDeviceList(const ALCchar
*name
)
1265 { AppendDevice(name
, &alcCaptureDeviceList
); }
1268 /************************************************
1269 * Device format information
1270 ************************************************/
1271 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1275 case DevFmtByte
: return "Signed Byte";
1276 case DevFmtUByte
: return "Unsigned Byte";
1277 case DevFmtShort
: return "Signed Short";
1278 case DevFmtUShort
: return "Unsigned Short";
1279 case DevFmtInt
: return "Signed Int";
1280 case DevFmtUInt
: return "Unsigned Int";
1281 case DevFmtFloat
: return "Float";
1283 return "(unknown type)";
1285 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1289 case DevFmtMono
: return "Mono";
1290 case DevFmtStereo
: return "Stereo";
1291 case DevFmtQuad
: return "Quadraphonic";
1292 case DevFmtX51
: return "5.1 Surround";
1293 case DevFmtX51Side
: return "5.1 Side";
1294 case DevFmtX61
: return "6.1 Surround";
1295 case DevFmtX71
: return "7.1 Surround";
1297 return "(unknown channels)";
1300 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1301 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1305 case DevFmtByte
: return sizeof(ALbyte
);
1306 case DevFmtUByte
: return sizeof(ALubyte
);
1307 case DevFmtShort
: return sizeof(ALshort
);
1308 case DevFmtUShort
: return sizeof(ALushort
);
1309 case DevFmtInt
: return sizeof(ALint
);
1310 case DevFmtUInt
: return sizeof(ALuint
);
1311 case DevFmtFloat
: return sizeof(ALfloat
);
1315 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1319 case DevFmtMono
: return 1;
1320 case DevFmtStereo
: return 2;
1321 case DevFmtQuad
: return 4;
1322 case DevFmtX51
: return 6;
1323 case DevFmtX51Side
: return 6;
1324 case DevFmtX61
: return 7;
1325 case DevFmtX71
: return 8;
1330 static ALboolean
DecomposeDevFormat(ALenum format
, enum DevFmtChannels
*chans
,
1331 enum DevFmtType
*type
)
1333 static const struct {
1335 enum DevFmtChannels channels
;
1336 enum DevFmtType type
;
1338 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1339 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1340 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1342 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1343 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1344 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1346 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1347 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1348 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1350 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1351 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1352 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1354 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1355 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1356 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1358 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1359 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1360 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1364 for(i
= 0;i
< COUNTOF(list
);i
++)
1366 if(list
[i
].format
== format
)
1368 *chans
= list
[i
].channels
;
1369 *type
= list
[i
].type
;
1377 static ALCboolean
IsValidALCType(ALCenum type
)
1382 case ALC_UNSIGNED_BYTE_SOFT
:
1383 case ALC_SHORT_SOFT
:
1384 case ALC_UNSIGNED_SHORT_SOFT
:
1386 case ALC_UNSIGNED_INT_SOFT
:
1387 case ALC_FLOAT_SOFT
:
1393 static ALCboolean
IsValidALCChannels(ALCenum channels
)
1398 case ALC_STEREO_SOFT
:
1400 case ALC_5POINT1_SOFT
:
1401 case ALC_6POINT1_SOFT
:
1402 case ALC_7POINT1_SOFT
:
1409 /************************************************
1410 * Miscellaneous ALC helpers
1411 ************************************************/
1412 extern inline void LockContext(ALCcontext
*context
);
1413 extern inline void UnlockContext(ALCcontext
*context
);
1415 ALint64
ALCdevice_GetLatencyDefault(ALCdevice
*UNUSED(device
))
1420 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1422 return V0(device
->Backend
,getLatency
)();
1425 void ALCdevice_Lock(ALCdevice
*device
)
1427 V0(device
->Backend
,lock
)();
1430 void ALCdevice_Unlock(ALCdevice
*device
)
1432 V0(device
->Backend
,unlock
)();
1436 /* SetDefaultWFXChannelOrder
1438 * Sets the default channel order used by WaveFormatEx.
1440 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1444 for(i
= 0;i
< MaxChannels
;i
++)
1445 device
->ChannelOffsets
[i
] = INVALID_OFFSET
;
1447 switch(device
->FmtChans
)
1449 case DevFmtMono
: device
->ChannelOffsets
[FrontCenter
] = 0;
1451 case DevFmtStereo
: device
->ChannelOffsets
[FrontLeft
] = 0;
1452 device
->ChannelOffsets
[FrontRight
] = 1;
1454 case DevFmtQuad
: device
->ChannelOffsets
[FrontLeft
] = 0;
1455 device
->ChannelOffsets
[FrontRight
] = 1;
1456 device
->ChannelOffsets
[BackLeft
] = 2;
1457 device
->ChannelOffsets
[BackRight
] = 3;
1459 case DevFmtX51
: device
->ChannelOffsets
[FrontLeft
] = 0;
1460 device
->ChannelOffsets
[FrontRight
] = 1;
1461 device
->ChannelOffsets
[FrontCenter
] = 2;
1462 device
->ChannelOffsets
[LFE
] = 3;
1463 device
->ChannelOffsets
[BackLeft
] = 4;
1464 device
->ChannelOffsets
[BackRight
] = 5;
1466 case DevFmtX51Side
: device
->ChannelOffsets
[FrontLeft
] = 0;
1467 device
->ChannelOffsets
[FrontRight
] = 1;
1468 device
->ChannelOffsets
[FrontCenter
] = 2;
1469 device
->ChannelOffsets
[LFE
] = 3;
1470 device
->ChannelOffsets
[SideLeft
] = 4;
1471 device
->ChannelOffsets
[SideRight
] = 5;
1473 case DevFmtX61
: device
->ChannelOffsets
[FrontLeft
] = 0;
1474 device
->ChannelOffsets
[FrontRight
] = 1;
1475 device
->ChannelOffsets
[FrontCenter
] = 2;
1476 device
->ChannelOffsets
[LFE
] = 3;
1477 device
->ChannelOffsets
[BackCenter
] = 4;
1478 device
->ChannelOffsets
[SideLeft
] = 5;
1479 device
->ChannelOffsets
[SideRight
] = 6;
1481 case DevFmtX71
: device
->ChannelOffsets
[FrontLeft
] = 0;
1482 device
->ChannelOffsets
[FrontRight
] = 1;
1483 device
->ChannelOffsets
[FrontCenter
] = 2;
1484 device
->ChannelOffsets
[LFE
] = 3;
1485 device
->ChannelOffsets
[BackLeft
] = 4;
1486 device
->ChannelOffsets
[BackRight
] = 5;
1487 device
->ChannelOffsets
[SideLeft
] = 6;
1488 device
->ChannelOffsets
[SideRight
] = 7;
1493 /* SetDefaultChannelOrder
1495 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1497 void SetDefaultChannelOrder(ALCdevice
*device
)
1501 for(i
= 0;i
< MaxChannels
;i
++)
1502 device
->ChannelOffsets
[i
] = INVALID_OFFSET
;
1504 switch(device
->FmtChans
)
1506 case DevFmtX51
: device
->ChannelOffsets
[FrontLeft
] = 0;
1507 device
->ChannelOffsets
[FrontRight
] = 1;
1508 device
->ChannelOffsets
[BackLeft
] = 2;
1509 device
->ChannelOffsets
[BackRight
] = 3;
1510 device
->ChannelOffsets
[FrontCenter
] = 4;
1511 device
->ChannelOffsets
[LFE
] = 5;
1513 case DevFmtX71
: device
->ChannelOffsets
[FrontLeft
] = 0;
1514 device
->ChannelOffsets
[FrontRight
] = 1;
1515 device
->ChannelOffsets
[BackLeft
] = 2;
1516 device
->ChannelOffsets
[BackRight
] = 3;
1517 device
->ChannelOffsets
[FrontCenter
] = 4;
1518 device
->ChannelOffsets
[LFE
] = 5;
1519 device
->ChannelOffsets
[SideLeft
] = 6;
1520 device
->ChannelOffsets
[SideRight
] = 7;
1523 /* Same as WFX order */
1531 SetDefaultWFXChannelOrder(device
);
1537 * Stores the latest ALC device error
1539 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1544 /* DebugBreak() will cause an exception if there is no debugger */
1545 if(IsDebuggerPresent())
1547 #elif defined(SIGTRAP)
1553 device
->LastError
= errorCode
;
1555 LastNullDeviceError
= errorCode
;
1561 * Updates the device's base clock time with however many samples have been
1562 * done. This is used so frequency changes on the device don't cause the time
1563 * to jump forward or back.
1565 static inline void UpdateClockBase(ALCdevice
*device
)
1567 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1568 device
->SamplesDone
= 0;
1571 /* UpdateDeviceParams
1573 * Updates device parameters according to the attribute list (caller is
1574 * responsible for holding the list lock).
1576 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1578 ALCcontext
*context
;
1579 enum DevFmtChannels oldChans
;
1580 enum DevFmtType oldType
;
1584 // Check for attributes
1585 if(device
->Type
== Loopback
)
1591 GotAll
= GotFreq
|GotChans
|GotType
1593 ALCuint freq
, numMono
, numStereo
, numSends
;
1594 enum DevFmtChannels schans
;
1595 enum DevFmtType stype
;
1596 ALCuint attrIdx
= 0;
1601 WARN("Missing attributes for loopback device\n");
1602 return ALC_INVALID_VALUE
;
1605 numMono
= device
->NumMonoSources
;
1606 numStereo
= device
->NumStereoSources
;
1607 numSends
= device
->NumAuxSends
;
1608 schans
= device
->FmtChans
;
1609 stype
= device
->FmtType
;
1610 freq
= device
->Frequency
;
1612 while(attrList
[attrIdx
])
1614 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1616 ALCint val
= attrList
[attrIdx
+ 1];
1617 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1618 return ALC_INVALID_VALUE
;
1623 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1625 ALCint val
= attrList
[attrIdx
+ 1];
1626 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1627 return ALC_INVALID_VALUE
;
1632 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1634 freq
= attrList
[attrIdx
+ 1];
1635 if(freq
< MIN_OUTPUT_RATE
)
1636 return ALC_INVALID_VALUE
;
1640 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1642 numStereo
= attrList
[attrIdx
+ 1];
1643 if(numStereo
> device
->MaxNoOfSources
)
1644 numStereo
= device
->MaxNoOfSources
;
1646 numMono
= device
->MaxNoOfSources
- numStereo
;
1649 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1650 numSends
= attrList
[attrIdx
+ 1];
1652 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1654 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1655 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1657 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1663 if(gotFmt
!= GotAll
)
1665 WARN("Missing format for loopback device\n");
1666 return ALC_INVALID_VALUE
;
1669 ConfigValueUInt(NULL
, "sends", &numSends
);
1670 numSends
= minu(MAX_SENDS
, numSends
);
1672 if((device
->Flags
&DEVICE_RUNNING
))
1673 V0(device
->Backend
,stop
)();
1674 device
->Flags
&= ~DEVICE_RUNNING
;
1676 if(freq
!= device
->Frequency
)
1677 UpdateClockBase(device
);
1678 device
->Frequency
= freq
;
1679 device
->FmtChans
= schans
;
1680 device
->FmtType
= stype
;
1681 device
->NumMonoSources
= numMono
;
1682 device
->NumStereoSources
= numStereo
;
1683 device
->NumAuxSends
= numSends
;
1685 else if(attrList
&& attrList
[0])
1687 ALCuint freq
, numMono
, numStereo
, numSends
;
1688 ALCuint attrIdx
= 0;
1690 /* If a context is already running on the device, stop playback so the
1691 * device attributes can be updated. */
1692 if((device
->Flags
&DEVICE_RUNNING
))
1693 V0(device
->Backend
,stop
)();
1694 device
->Flags
&= ~DEVICE_RUNNING
;
1696 freq
= device
->Frequency
;
1697 numMono
= device
->NumMonoSources
;
1698 numStereo
= device
->NumStereoSources
;
1699 numSends
= device
->NumAuxSends
;
1701 while(attrList
[attrIdx
])
1703 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1705 freq
= attrList
[attrIdx
+ 1];
1706 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1709 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1711 numStereo
= attrList
[attrIdx
+ 1];
1712 if(numStereo
> device
->MaxNoOfSources
)
1713 numStereo
= device
->MaxNoOfSources
;
1715 numMono
= device
->MaxNoOfSources
- numStereo
;
1718 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1719 numSends
= attrList
[attrIdx
+ 1];
1721 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1723 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1724 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1726 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1732 ConfigValueUInt(NULL
, "frequency", &freq
);
1733 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1735 ConfigValueUInt(NULL
, "sends", &numSends
);
1736 numSends
= minu(MAX_SENDS
, numSends
);
1738 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1740 /* SSE and Neon do best with the update size being a multiple of 4 */
1741 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1742 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1744 if(freq
!= device
->Frequency
)
1745 UpdateClockBase(device
);
1746 device
->Frequency
= freq
;
1747 device
->NumMonoSources
= numMono
;
1748 device
->NumStereoSources
= numStereo
;
1749 device
->NumAuxSends
= numSends
;
1752 if((device
->Flags
&DEVICE_RUNNING
))
1753 return ALC_NO_ERROR
;
1755 UpdateClockBase(device
);
1757 oldFreq
= device
->Frequency
;
1758 oldChans
= device
->FmtChans
;
1759 oldType
= device
->FmtType
;
1761 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1762 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"",
1763 DevFmtChannelsString(device
->FmtChans
),
1764 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"",
1765 DevFmtTypeString(device
->FmtType
),
1766 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"",
1768 device
->UpdateSize
, device
->NumUpdates
);
1770 if(device
->Type
!= Loopback
)
1772 int nohrtf
= !(device
->Flags
&DEVICE_HRTF_REQUEST
);
1773 if(GetConfigValueBool(NULL
, "hrtf", !nohrtf
))
1774 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1776 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1778 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1780 enum DevFmtChannels chans
;
1782 if(FindHrtfFormat(device
, &chans
, &freq
))
1784 device
->Frequency
= freq
;
1785 device
->FmtChans
= chans
;
1786 device
->Flags
|= DEVICE_CHANNELS_REQUEST
|
1787 DEVICE_FREQUENCY_REQUEST
;
1791 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1792 return ALC_INVALID_DEVICE
;
1794 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1796 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1797 DevFmtChannelsString(device
->FmtChans
));
1798 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1800 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1802 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1803 DevFmtTypeString(device
->FmtType
));
1804 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1806 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1808 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1809 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1812 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1813 DevFmtChannelsString(device
->FmtChans
),
1814 DevFmtTypeString(device
->FmtType
), device
->Frequency
,
1815 device
->UpdateSize
, device
->NumUpdates
);
1817 aluInitPanning(device
);
1819 V(device
->Synth
,update
)(device
);
1821 device
->Hrtf
= NULL
;
1822 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1824 device
->Hrtf
= GetHrtf(device
);
1826 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1828 TRACE("HRTF %s\n", device
->Hrtf
?"enabled":"disabled");
1830 if(!device
->Hrtf
&& device
->Bs2bLevel
> 0 && device
->Bs2bLevel
<= 6)
1834 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
1835 bs2b_clear(device
->Bs2b
);
1837 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
1838 bs2b_set_level(device
->Bs2b
, device
->Bs2bLevel
);
1839 TRACE("BS2B level %d\n", device
->Bs2bLevel
);
1844 device
->Bs2b
= NULL
;
1845 TRACE("BS2B disabled\n");
1848 device
->Flags
&= ~DEVICE_WIDE_STEREO
;
1849 if(device
->Type
!= Loopback
&& !device
->Hrtf
&& GetConfigValueBool(NULL
, "wide-stereo", AL_FALSE
))
1850 device
->Flags
|= DEVICE_WIDE_STEREO
;
1852 if(!device
->Hrtf
&& (device
->UpdateSize
&3))
1854 if((CPUCapFlags
&CPU_CAP_SSE
))
1855 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1856 if((CPUCapFlags
&CPU_CAP_NEON
))
1857 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1860 SetMixerFPUMode(&oldMode
);
1861 ALCdevice_Lock(device
);
1862 context
= device
->ContextList
;
1867 context
->UpdateSources
= AL_FALSE
;
1868 LockUIntMapRead(&context
->EffectSlotMap
);
1869 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
1871 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
1873 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1875 UnlockUIntMapRead(&context
->EffectSlotMap
);
1876 ALCdevice_Unlock(device
);
1877 RestoreFPUMode(&oldMode
);
1878 return ALC_INVALID_DEVICE
;
1880 slot
->NeedsUpdate
= AL_FALSE
;
1881 V(slot
->EffectState
,update
)(device
, slot
);
1883 UnlockUIntMapRead(&context
->EffectSlotMap
);
1885 LockUIntMapRead(&context
->SourceMap
);
1886 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1888 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
1889 ALuint s
= device
->NumAuxSends
;
1890 while(s
< MAX_SENDS
)
1892 if(source
->Send
[s
].Slot
)
1893 DecrementRef(&source
->Send
[s
].Slot
->ref
);
1894 source
->Send
[s
].Slot
= NULL
;
1895 source
->Send
[s
].Gain
= 1.0f
;
1896 source
->Send
[s
].GainHF
= 1.0f
;
1899 source
->NeedsUpdate
= AL_TRUE
;
1901 UnlockUIntMapRead(&context
->SourceMap
);
1903 for(pos
= 0;pos
< context
->ActiveSourceCount
;pos
++)
1905 ALactivesource
*src
= context
->ActiveSources
[pos
];
1906 ALsource
*source
= src
->Source
;
1907 ALuint s
= device
->NumAuxSends
;
1908 while(s
< MAX_SENDS
)
1910 src
->Send
[s
].Moving
= AL_FALSE
;
1911 src
->Send
[s
].Counter
= 0;
1915 src
->Update(src
, context
);
1916 source
->NeedsUpdate
= AL_FALSE
;
1919 context
= context
->next
;
1921 if(device
->DefaultSlot
)
1923 ALeffectslot
*slot
= device
->DefaultSlot
;
1925 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1927 ALCdevice_Unlock(device
);
1928 RestoreFPUMode(&oldMode
);
1929 return ALC_INVALID_DEVICE
;
1931 slot
->NeedsUpdate
= AL_FALSE
;
1932 V(slot
->EffectState
,update
)(device
, slot
);
1934 ALCdevice_Unlock(device
);
1935 RestoreFPUMode(&oldMode
);
1937 if(!(device
->Flags
&DEVICE_PAUSED
))
1939 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
1940 return ALC_INVALID_DEVICE
;
1941 device
->Flags
|= DEVICE_RUNNING
;
1944 return ALC_NO_ERROR
;
1949 * Frees the device structure, and destroys any objects the app failed to
1950 * delete. Called once there's no more references on the device.
1952 static ALCvoid
FreeDevice(ALCdevice
*device
)
1954 TRACE("%p\n", device
);
1956 V0(device
->Backend
,close
)();
1957 DELETE_OBJ(device
->Backend
);
1958 device
->Backend
= NULL
;
1960 DELETE_OBJ(device
->Synth
);
1961 device
->Synth
= NULL
;
1963 if(device
->DefaultSlot
)
1965 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
1966 device
->DefaultSlot
= NULL
;
1970 if(device
->DefaultSfont
)
1971 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
1972 device
->DefaultSfont
= NULL
;
1974 if(device
->BufferMap
.size
> 0)
1976 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
1977 ReleaseALBuffers(device
);
1979 ResetUIntMap(&device
->BufferMap
);
1981 if(device
->EffectMap
.size
> 0)
1983 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
1984 ReleaseALEffects(device
);
1986 ResetUIntMap(&device
->EffectMap
);
1988 if(device
->FilterMap
.size
> 0)
1990 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
1991 ReleaseALFilters(device
);
1993 ResetUIntMap(&device
->FilterMap
);
1995 if(device
->SfontMap
.size
> 0)
1997 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
1998 ReleaseALSoundfonts(device
);
2000 ResetUIntMap(&device
->SfontMap
);
2002 if(device
->PresetMap
.size
> 0)
2004 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2005 ReleaseALPresets(device
);
2007 ResetUIntMap(&device
->PresetMap
);
2009 if(device
->FontsoundMap
.size
> 0)
2011 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2012 ReleaseALFontsounds(device
);
2014 ResetUIntMap(&device
->FontsoundMap
);
2017 device
->Bs2b
= NULL
;
2019 AL_STRING_DEINIT(device
->DeviceName
);
2025 void ALCdevice_IncRef(ALCdevice
*device
)
2028 ref
= IncrementRef(&device
->ref
);
2029 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2032 void ALCdevice_DecRef(ALCdevice
*device
)
2035 ref
= DecrementRef(&device
->ref
);
2036 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2037 if(ref
== 0) FreeDevice(device
);
2042 * Checks if the device handle is valid, and increments its ref count if so.
2044 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2046 ALCdevice
*tmpDevice
;
2052 tmpDevice
= DeviceList
;
2053 while(tmpDevice
&& tmpDevice
!= device
)
2054 tmpDevice
= tmpDevice
->next
;
2057 ALCdevice_IncRef(tmpDevice
);
2065 * Initializes context fields
2067 static ALvoid
InitContext(ALCcontext
*Context
)
2071 //Initialise listener
2072 Context
->Listener
->Gain
= 1.0f
;
2073 Context
->Listener
->MetersPerUnit
= 1.0f
;
2074 Context
->Listener
->Position
[0] = 0.0f
;
2075 Context
->Listener
->Position
[1] = 0.0f
;
2076 Context
->Listener
->Position
[2] = 0.0f
;
2077 Context
->Listener
->Velocity
[0] = 0.0f
;
2078 Context
->Listener
->Velocity
[1] = 0.0f
;
2079 Context
->Listener
->Velocity
[2] = 0.0f
;
2080 Context
->Listener
->Forward
[0] = 0.0f
;
2081 Context
->Listener
->Forward
[1] = 0.0f
;
2082 Context
->Listener
->Forward
[2] = -1.0f
;
2083 Context
->Listener
->Up
[0] = 0.0f
;
2084 Context
->Listener
->Up
[1] = 1.0f
;
2085 Context
->Listener
->Up
[2] = 0.0f
;
2086 for(i
= 0;i
< 4;i
++)
2088 for(j
= 0;j
< 4;j
++)
2089 Context
->Listener
->Params
.Matrix
[i
][j
] = ((i
==j
) ? 1.0f
: 0.0f
);
2091 for(i
= 0;i
< 3;i
++)
2092 Context
->Listener
->Params
.Velocity
[i
] = 0.0f
;
2095 Context
->LastError
= AL_NO_ERROR
;
2096 Context
->UpdateSources
= AL_FALSE
;
2097 Context
->ActiveSourceCount
= 0;
2098 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2099 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2102 Context
->DistanceModel
= DefaultDistanceModel
;
2103 Context
->SourceDistanceModel
= AL_FALSE
;
2104 Context
->DopplerFactor
= 1.0f
;
2105 Context
->DopplerVelocity
= 1.0f
;
2106 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2107 Context
->DeferUpdates
= AL_FALSE
;
2109 Context
->ExtensionList
= alExtList
;
2115 * Cleans up the context, and destroys any remaining objects the app failed to
2116 * delete. Called once there's no more references on the context.
2118 static ALCvoid
FreeContext(ALCcontext
*context
)
2122 TRACE("%p\n", context
);
2124 if(context
->SourceMap
.size
> 0)
2126 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2127 ReleaseALSources(context
);
2129 ResetUIntMap(&context
->SourceMap
);
2131 if(context
->EffectSlotMap
.size
> 0)
2133 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2134 ReleaseALAuxiliaryEffectSlots(context
);
2136 ResetUIntMap(&context
->EffectSlotMap
);
2138 for(i
= 0;i
< context
->MaxActiveSources
;i
++)
2140 al_free(context
->ActiveSources
[i
]);
2141 context
->ActiveSources
[i
] = NULL
;
2143 free(context
->ActiveSources
);
2144 context
->ActiveSources
= NULL
;
2145 context
->ActiveSourceCount
= 0;
2146 context
->MaxActiveSources
= 0;
2148 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2150 ALCdevice_DecRef(context
->Device
);
2151 context
->Device
= NULL
;
2153 //Invalidate context
2154 memset(context
, 0, sizeof(ALCcontext
));
2160 * Removes the context reference from the given device and removes it from
2161 * being current on the running thread or globally.
2163 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2165 ALCcontext
*volatile*tmp_ctx
;
2167 if(altss_get(LocalContext
) == context
)
2169 WARN("%p released while current on thread\n", context
);
2170 altss_set(LocalContext
, NULL
);
2171 ALCcontext_DecRef(context
);
2174 if(CompExchangePtr((XchgPtr
*)&GlobalContext
, context
, NULL
) == context
)
2175 ALCcontext_DecRef(context
);
2177 ALCdevice_Lock(device
);
2178 tmp_ctx
= &device
->ContextList
;
2181 if(CompExchangePtr((XchgPtr
*)tmp_ctx
, context
, context
->next
) == context
)
2183 tmp_ctx
= &(*tmp_ctx
)->next
;
2185 ALCdevice_Unlock(device
);
2187 ALCcontext_DecRef(context
);
2190 void ALCcontext_IncRef(ALCcontext
*context
)
2193 ref
= IncrementRef(&context
->ref
);
2194 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2197 void ALCcontext_DecRef(ALCcontext
*context
)
2200 ref
= DecrementRef(&context
->ref
);
2201 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2202 if(ref
== 0) FreeContext(context
);
2205 static void ReleaseThreadCtx(void *ptr
)
2207 WARN("%p current for thread being destroyed\n", ptr
);
2208 ALCcontext_DecRef(ptr
);
2213 * Checks that the given context is valid, and increments its reference count.
2215 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2223 ALCcontext
*tmp_ctx
= dev
->ContextList
;
2226 if(tmp_ctx
== context
)
2228 ALCcontext_IncRef(tmp_ctx
);
2232 tmp_ctx
= tmp_ctx
->next
;
2244 * Returns the currently active context for this thread, and adds a reference
2245 * without locking it.
2247 ALCcontext
*GetContextRef(void)
2249 ALCcontext
*context
;
2251 context
= altss_get(LocalContext
);
2253 ALCcontext_IncRef(context
);
2257 context
= GlobalContext
;
2259 ALCcontext_IncRef(context
);
2267 /************************************************
2268 * Standard ALC functions
2269 ************************************************/
2273 * Return last ALC generated error code for the given device
2275 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2279 if(VerifyDevice(device
))
2281 errorCode
= ExchangeInt(&device
->LastError
, ALC_NO_ERROR
);
2282 ALCdevice_DecRef(device
);
2285 errorCode
= ExchangeInt(&LastNullDeviceError
, ALC_NO_ERROR
);
2291 /* alcSuspendContext
2295 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*UNUSED(context
))
2299 /* alcProcessContext
2303 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*UNUSED(context
))
2310 * Returns information about the device, and error strings
2312 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2314 const ALCchar
*value
= NULL
;
2322 case ALC_INVALID_ENUM
:
2323 value
= alcErrInvalidEnum
;
2326 case ALC_INVALID_VALUE
:
2327 value
= alcErrInvalidValue
;
2330 case ALC_INVALID_DEVICE
:
2331 value
= alcErrInvalidDevice
;
2334 case ALC_INVALID_CONTEXT
:
2335 value
= alcErrInvalidContext
;
2338 case ALC_OUT_OF_MEMORY
:
2339 value
= alcErrOutOfMemory
;
2342 case ALC_DEVICE_SPECIFIER
:
2343 value
= alcDefaultName
;
2346 case ALC_ALL_DEVICES_SPECIFIER
:
2347 if(VerifyDevice(Device
))
2349 value
= al_string_get_cstr(Device
->DeviceName
);
2350 ALCdevice_DecRef(Device
);
2354 ProbeAllDevicesList();
2355 value
= al_string_get_cstr(alcAllDevicesList
);
2359 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2360 if(VerifyDevice(Device
))
2362 value
= al_string_get_cstr(Device
->DeviceName
);
2363 ALCdevice_DecRef(Device
);
2367 ProbeCaptureDeviceList();
2368 value
= al_string_get_cstr(alcCaptureDeviceList
);
2372 /* Default devices are always first in the list */
2373 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2374 value
= alcDefaultName
;
2377 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2378 if(al_string_empty(alcAllDevicesList
))
2379 ProbeAllDevicesList();
2381 Device
= VerifyDevice(Device
);
2383 free(alcDefaultAllDevicesSpecifier
);
2384 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2385 if(!alcDefaultAllDevicesSpecifier
)
2386 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2388 value
= alcDefaultAllDevicesSpecifier
;
2389 if(Device
) ALCdevice_DecRef(Device
);
2392 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2393 if(al_string_empty(alcCaptureDeviceList
))
2394 ProbeCaptureDeviceList();
2396 Device
= VerifyDevice(Device
);
2398 free(alcCaptureDefaultDeviceSpecifier
);
2399 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2400 if(!alcCaptureDefaultDeviceSpecifier
)
2401 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2403 value
= alcCaptureDefaultDeviceSpecifier
;
2404 if(Device
) ALCdevice_DecRef(Device
);
2407 case ALC_EXTENSIONS
:
2408 if(!VerifyDevice(Device
))
2409 value
= alcNoDeviceExtList
;
2412 value
= alcExtensionList
;
2413 ALCdevice_DecRef(Device
);
2418 Device
= VerifyDevice(Device
);
2419 alcSetError(Device
, ALC_INVALID_ENUM
);
2420 if(Device
) ALCdevice_DecRef(Device
);
2428 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2432 if(size
<= 0 || values
== NULL
)
2434 alcSetError(device
, ALC_INVALID_VALUE
);
2442 case ALC_MAJOR_VERSION
:
2443 values
[0] = alcMajorVersion
;
2445 case ALC_MINOR_VERSION
:
2446 values
[0] = alcMinorVersion
;
2449 case ALC_ATTRIBUTES_SIZE
:
2450 case ALC_ALL_ATTRIBUTES
:
2454 case ALC_MONO_SOURCES
:
2455 case ALC_STEREO_SOURCES
:
2456 case ALC_CAPTURE_SAMPLES
:
2457 case ALC_FORMAT_CHANNELS_SOFT
:
2458 case ALC_FORMAT_TYPE_SOFT
:
2459 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2463 alcSetError(NULL
, ALC_INVALID_ENUM
);
2469 if(device
->Type
== Capture
)
2473 case ALC_CAPTURE_SAMPLES
:
2474 ALCdevice_Lock(device
);
2475 values
[0] = V0(device
->Backend
,availableSamples
)();
2476 ALCdevice_Unlock(device
);
2480 values
[0] = device
->Connected
;
2484 alcSetError(device
, ALC_INVALID_ENUM
);
2493 case ALC_MAJOR_VERSION
:
2494 values
[0] = alcMajorVersion
;
2497 case ALC_MINOR_VERSION
:
2498 values
[0] = alcMinorVersion
;
2501 case ALC_EFX_MAJOR_VERSION
:
2502 values
[0] = alcEFXMajorVersion
;
2505 case ALC_EFX_MINOR_VERSION
:
2506 values
[0] = alcEFXMinorVersion
;
2509 case ALC_ATTRIBUTES_SIZE
:
2513 case ALC_ALL_ATTRIBUTES
:
2516 alcSetError(device
, ALC_INVALID_VALUE
);
2521 values
[i
++] = ALC_FREQUENCY
;
2522 values
[i
++] = device
->Frequency
;
2524 if(device
->Type
!= Loopback
)
2526 values
[i
++] = ALC_REFRESH
;
2527 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2529 values
[i
++] = ALC_SYNC
;
2530 values
[i
++] = ALC_FALSE
;
2534 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2535 values
[i
++] = device
->FmtChans
;
2537 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2538 values
[i
++] = device
->FmtType
;
2541 values
[i
++] = ALC_MONO_SOURCES
;
2542 values
[i
++] = device
->NumMonoSources
;
2544 values
[i
++] = ALC_STEREO_SOURCES
;
2545 values
[i
++] = device
->NumStereoSources
;
2547 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2548 values
[i
++] = device
->NumAuxSends
;
2550 values
[i
++] = ALC_HRTF_SOFT
;
2551 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2557 values
[0] = device
->Frequency
;
2561 if(device
->Type
== Loopback
)
2563 alcSetError(device
, ALC_INVALID_DEVICE
);
2566 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2570 if(device
->Type
== Loopback
)
2572 alcSetError(device
, ALC_INVALID_DEVICE
);
2575 values
[0] = ALC_FALSE
;
2578 case ALC_FORMAT_CHANNELS_SOFT
:
2579 if(device
->Type
!= Loopback
)
2581 alcSetError(device
, ALC_INVALID_DEVICE
);
2584 values
[0] = device
->FmtChans
;
2587 case ALC_FORMAT_TYPE_SOFT
:
2588 if(device
->Type
!= Loopback
)
2590 alcSetError(device
, ALC_INVALID_DEVICE
);
2593 values
[0] = device
->FmtType
;
2596 case ALC_MONO_SOURCES
:
2597 values
[0] = device
->NumMonoSources
;
2600 case ALC_STEREO_SOURCES
:
2601 values
[0] = device
->NumStereoSources
;
2604 case ALC_MAX_AUXILIARY_SENDS
:
2605 values
[0] = device
->NumAuxSends
;
2609 values
[0] = device
->Connected
;
2613 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2617 alcSetError(device
, ALC_INVALID_ENUM
);
2625 * Returns information about the device and the version of OpenAL
2627 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2629 device
= VerifyDevice(device
);
2630 if(size
<= 0 || values
== NULL
)
2631 alcSetError(device
, ALC_INVALID_VALUE
);
2633 GetIntegerv(device
, param
, size
, values
);
2634 if(device
) ALCdevice_DecRef(device
);
2637 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2642 device
= VerifyDevice(device
);
2643 if(size
<= 0 || values
== NULL
)
2644 alcSetError(device
, ALC_INVALID_VALUE
);
2645 else if(!device
|| device
->Type
== Capture
)
2647 ivals
= malloc(size
* sizeof(ALCint
));
2648 size
= GetIntegerv(device
, pname
, size
, ivals
);
2649 for(i
= 0;i
< size
;i
++)
2650 values
[i
] = ivals
[i
];
2653 else /* render device */
2657 case ALC_ATTRIBUTES_SIZE
:
2661 case ALC_ALL_ATTRIBUTES
:
2663 alcSetError(device
, ALC_INVALID_VALUE
);
2668 V0(device
->Backend
,lock
)();
2669 values
[i
++] = ALC_FREQUENCY
;
2670 values
[i
++] = device
->Frequency
;
2672 if(device
->Type
!= Loopback
)
2674 values
[i
++] = ALC_REFRESH
;
2675 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2677 values
[i
++] = ALC_SYNC
;
2678 values
[i
++] = ALC_FALSE
;
2682 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2683 values
[i
++] = device
->FmtChans
;
2685 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2686 values
[i
++] = device
->FmtType
;
2689 values
[i
++] = ALC_MONO_SOURCES
;
2690 values
[i
++] = device
->NumMonoSources
;
2692 values
[i
++] = ALC_STEREO_SOURCES
;
2693 values
[i
++] = device
->NumStereoSources
;
2695 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2696 values
[i
++] = device
->NumAuxSends
;
2698 values
[i
++] = ALC_HRTF_SOFT
;
2699 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2701 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2702 values
[i
++] = device
->ClockBase
+
2703 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2706 V0(device
->Backend
,unlock
)();
2710 case ALC_DEVICE_CLOCK_SOFT
:
2711 V0(device
->Backend
,lock
)();
2712 *values
= device
->ClockBase
+
2713 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2714 V0(device
->Backend
,unlock
)();
2718 ivals
= malloc(size
* sizeof(ALCint
));
2719 size
= GetIntegerv(device
, pname
, size
, ivals
);
2720 for(i
= 0;i
< size
;i
++)
2721 values
[i
] = ivals
[i
];
2727 ALCdevice_DecRef(device
);
2731 /* alcIsExtensionPresent
2733 * Determines if there is support for a particular extension
2735 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2737 ALCboolean bResult
= ALC_FALSE
;
2739 device
= VerifyDevice(device
);
2742 alcSetError(device
, ALC_INVALID_VALUE
);
2745 size_t len
= strlen(extName
);
2746 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2749 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2750 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2755 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2759 } while(isspace(*ptr
));
2764 ALCdevice_DecRef(device
);
2769 /* alcGetProcAddress
2771 * Retrieves the function address for a particular extension function
2773 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2775 ALCvoid
*ptr
= NULL
;
2779 device
= VerifyDevice(device
);
2780 alcSetError(device
, ALC_INVALID_VALUE
);
2781 if(device
) ALCdevice_DecRef(device
);
2786 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2788 ptr
= alcFunctions
[i
].address
;
2797 * Get the value for a particular ALC enumeration name
2799 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
2805 device
= VerifyDevice(device
);
2806 alcSetError(device
, ALC_INVALID_VALUE
);
2807 if(device
) ALCdevice_DecRef(device
);
2812 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
2814 val
= enumeration
[i
].value
;
2823 * Create and attach a context to the given device.
2825 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
2827 ALCcontext
*ALContext
;
2831 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
2834 alcSetError(device
, ALC_INVALID_DEVICE
);
2835 if(device
) ALCdevice_DecRef(device
);
2839 device
->LastError
= ALC_NO_ERROR
;
2841 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
2844 alcSetError(device
, err
);
2845 if(err
== ALC_INVALID_DEVICE
)
2847 ALCdevice_Lock(device
);
2848 aluHandleDisconnect(device
);
2849 ALCdevice_Unlock(device
);
2851 ALCdevice_DecRef(device
);
2855 ALContext
= calloc(1, sizeof(ALCcontext
)+sizeof(ALlistener
));
2859 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
2861 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
2863 ALContext
->MaxActiveSources
= 256;
2864 ALContext
->ActiveSources
= calloc(ALContext
->MaxActiveSources
,
2865 sizeof(ALContext
->ActiveSources
[0]));
2867 if(!ALContext
|| !ALContext
->ActiveSources
)
2869 if(!device
->ContextList
)
2871 V0(device
->Backend
,stop
)();
2872 device
->Flags
&= ~DEVICE_RUNNING
;
2878 free(ALContext
->ActiveSources
);
2879 ALContext
->ActiveSources
= NULL
;
2881 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
2887 alcSetError(device
, ALC_OUT_OF_MEMORY
);
2888 ALCdevice_DecRef(device
);
2892 ALContext
->Device
= device
;
2893 ALCdevice_IncRef(device
);
2894 InitContext(ALContext
);
2897 ALContext
->next
= device
->ContextList
;
2898 } while(CompExchangePtr((XchgPtr
*)&device
->ContextList
, ALContext
->next
, ALContext
) != ALContext
->next
);
2901 ALCdevice_DecRef(device
);
2903 TRACE("Created context %p\n", ALContext
);
2907 /* alcDestroyContext
2909 * Remove a context from its device
2911 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
2916 /* alcGetContextsDevice sets an error for invalid contexts */
2917 Device
= alcGetContextsDevice(context
);
2920 ReleaseContext(context
, Device
);
2921 if(!Device
->ContextList
)
2923 V0(Device
->Backend
,stop
)();
2924 Device
->Flags
&= ~DEVICE_RUNNING
;
2931 /* alcGetCurrentContext
2933 * Returns the currently active context on the calling thread
2935 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
2937 ALCcontext
*Context
;
2939 Context
= altss_get(LocalContext
);
2940 if(!Context
) Context
= GlobalContext
;
2945 /* alcGetThreadContext
2947 * Returns the currently active thread-local context
2949 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
2951 ALCcontext
*Context
;
2952 Context
= altss_get(LocalContext
);
2957 /* alcMakeContextCurrent
2959 * Makes the given context the active process-wide context, and removes the
2960 * thread-local context for the calling thread.
2962 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
2964 /* context must be valid or NULL */
2965 if(context
&& !(context
=VerifyContext(context
)))
2967 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2970 /* context's reference count is already incremented */
2971 context
= ExchangePtr((XchgPtr
*)&GlobalContext
, context
);
2972 if(context
) ALCcontext_DecRef(context
);
2974 if((context
=altss_get(LocalContext
)) != NULL
)
2976 altss_set(LocalContext
, NULL
);
2977 ALCcontext_DecRef(context
);
2983 /* alcSetThreadContext
2985 * Makes the given context the active context for the current thread
2987 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
2991 /* context must be valid or NULL */
2992 if(context
&& !(context
=VerifyContext(context
)))
2994 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2997 /* context's reference count is already incremented */
2998 old
= altss_get(LocalContext
);
2999 altss_set(LocalContext
, context
);
3000 if(old
) ALCcontext_DecRef(old
);
3006 /* alcGetContextsDevice
3008 * Returns the device that a particular context is attached to
3010 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3014 if(!(Context
=VerifyContext(Context
)))
3016 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3019 Device
= Context
->Device
;
3020 ALCcontext_DecRef(Context
);
3028 * Opens the named device.
3030 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3038 if(!PlaybackBackend
.name
)
3040 alcSetError(NULL
, ALC_INVALID_VALUE
);
3044 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3047 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3050 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3056 device
->Connected
= ALC_TRUE
;
3057 device
->Type
= Playback
;
3058 device
->LastError
= ALC_NO_ERROR
;
3061 device
->Bs2b
= NULL
;
3062 device
->Bs2bLevel
= 0;
3063 AL_STRING_INIT(device
->DeviceName
);
3065 device
->ContextList
= NULL
;
3067 device
->ClockBase
= 0;
3068 device
->SamplesDone
= 0;
3070 device
->MaxNoOfSources
= 256;
3071 device
->AuxiliaryEffectSlotMax
= 4;
3072 device
->NumAuxSends
= MAX_SENDS
;
3074 InitUIntMap(&device
->BufferMap
, ~0);
3075 InitUIntMap(&device
->EffectMap
, ~0);
3076 InitUIntMap(&device
->FilterMap
, ~0);
3077 InitUIntMap(&device
->SfontMap
, ~0);
3078 InitUIntMap(&device
->PresetMap
, ~0);
3079 InitUIntMap(&device
->FontsoundMap
, ~0);
3082 device
->FmtChans
= DevFmtChannelsDefault
;
3083 device
->FmtType
= DevFmtTypeDefault
;
3084 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3085 device
->NumUpdates
= 4;
3086 device
->UpdateSize
= 1024;
3088 if(!PlaybackBackend
.getFactory
)
3089 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3090 ALCbackend_Playback
);
3093 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3094 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3096 if(!device
->Backend
)
3099 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3104 if(ConfigValueStr(NULL
, "channels", &fmt
))
3106 static const struct {
3107 const char name
[16];
3108 enum DevFmtChannels chans
;
3110 { "mono", DevFmtMono
},
3111 { "stereo", DevFmtStereo
},
3112 { "quad", DevFmtQuad
},
3113 { "surround51", DevFmtX51
},
3114 { "surround61", DevFmtX61
},
3115 { "surround71", DevFmtX71
},
3119 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3121 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3123 device
->FmtChans
= chanlist
[i
].chans
;
3124 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3128 if(i
== COUNTOF(chanlist
))
3129 ERR("Unsupported channels: %s\n", fmt
);
3131 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3133 static const struct {
3134 const char name
[16];
3135 enum DevFmtType type
;
3137 { "int8", DevFmtByte
},
3138 { "uint8", DevFmtUByte
},
3139 { "int16", DevFmtShort
},
3140 { "uint16", DevFmtUShort
},
3141 { "int32", DevFmtInt
},
3142 { "uint32", DevFmtUInt
},
3143 { "float32", DevFmtFloat
},
3147 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3149 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3151 device
->FmtType
= typelist
[i
].type
;
3152 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3156 if(i
== COUNTOF(typelist
))
3157 ERR("Unsupported sample-type: %s\n", fmt
);
3159 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3160 if((device
->Flags
&DEVICE_FORMAT_REQUEST
) != DEVICE_FORMAT_REQUEST
&&
3161 ConfigValueStr(NULL
, "format", &fmt
))
3163 static const struct {
3164 const char name
[32];
3165 enum DevFmtChannels channels
;
3166 enum DevFmtType type
;
3168 { "AL_FORMAT_MONO32", DevFmtMono
, DevFmtFloat
},
3169 { "AL_FORMAT_STEREO32", DevFmtStereo
, DevFmtFloat
},
3170 { "AL_FORMAT_QUAD32", DevFmtQuad
, DevFmtFloat
},
3171 { "AL_FORMAT_51CHN32", DevFmtX51
, DevFmtFloat
},
3172 { "AL_FORMAT_61CHN32", DevFmtX61
, DevFmtFloat
},
3173 { "AL_FORMAT_71CHN32", DevFmtX71
, DevFmtFloat
},
3175 { "AL_FORMAT_MONO16", DevFmtMono
, DevFmtShort
},
3176 { "AL_FORMAT_STEREO16", DevFmtStereo
, DevFmtShort
},
3177 { "AL_FORMAT_QUAD16", DevFmtQuad
, DevFmtShort
},
3178 { "AL_FORMAT_51CHN16", DevFmtX51
, DevFmtShort
},
3179 { "AL_FORMAT_61CHN16", DevFmtX61
, DevFmtShort
},
3180 { "AL_FORMAT_71CHN16", DevFmtX71
, DevFmtShort
},
3182 { "AL_FORMAT_MONO8", DevFmtMono
, DevFmtByte
},
3183 { "AL_FORMAT_STEREO8", DevFmtStereo
, DevFmtByte
},
3184 { "AL_FORMAT_QUAD8", DevFmtQuad
, DevFmtByte
},
3185 { "AL_FORMAT_51CHN8", DevFmtX51
, DevFmtByte
},
3186 { "AL_FORMAT_61CHN8", DevFmtX61
, DevFmtByte
},
3187 { "AL_FORMAT_71CHN8", DevFmtX71
, DevFmtByte
}
3191 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3192 for(i
= 0;i
< COUNTOF(formats
);i
++)
3194 if(strcasecmp(fmt
, formats
[i
].name
) == 0)
3196 if(!(device
->Flags
&DEVICE_CHANNELS_REQUEST
))
3197 device
->FmtChans
= formats
[i
].channels
;
3198 if(!(device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
3199 device
->FmtType
= formats
[i
].type
;
3200 device
->Flags
|= DEVICE_FORMAT_REQUEST
;
3204 if(i
== COUNTOF(formats
))
3205 ERR("Unsupported format: %s\n", fmt
);
3207 #undef DEVICE_FORMAT_REQUEST
3209 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3211 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3212 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3213 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3214 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3217 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3218 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3220 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3221 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3222 if((CPUCapFlags
&CPU_CAP_SSE
))
3223 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3225 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3226 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3228 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3229 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3231 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3232 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3234 ConfigValueInt(NULL
, "cf_level", &device
->Bs2bLevel
);
3236 device
->NumStereoSources
= 1;
3237 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3239 device
->Synth
= SynthCreate(device
);
3242 DELETE_OBJ(device
->Backend
);
3244 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3248 // Find a playback device to open
3249 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3251 DELETE_OBJ(device
->Synth
);
3252 DELETE_OBJ(device
->Backend
);
3254 alcSetError(NULL
, err
);
3258 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3260 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3261 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3263 device
->DefaultSlot
= NULL
;
3264 ERR("Failed to initialize the default effect slot\n");
3266 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3268 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3269 device
->DefaultSlot
= NULL
;
3271 ERR("Failed to initialize the default effect\n");
3276 device
->next
= DeviceList
;
3277 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3279 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3285 * Closes the given device.
3287 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*Device
)
3289 ALCdevice
*volatile*list
;
3294 while(*list
&& *list
!= Device
)
3295 list
= &(*list
)->next
;
3297 if(!*list
|| (*list
)->Type
== Capture
)
3299 alcSetError(*list
, ALC_INVALID_DEVICE
);
3304 *list
= (*list
)->next
;
3307 while((ctx
=Device
->ContextList
) != NULL
)
3309 WARN("Releasing context %p\n", ctx
);
3310 ReleaseContext(ctx
, Device
);
3312 if((Device
->Flags
&DEVICE_RUNNING
))
3313 V0(Device
->Backend
,stop
)();
3314 Device
->Flags
&= ~DEVICE_RUNNING
;
3316 ALCdevice_DecRef(Device
);
3322 /************************************************
3323 * ALC capture functions
3324 ************************************************/
3325 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3327 ALCdevice
*device
= NULL
;
3332 if(!CaptureBackend
.name
)
3334 alcSetError(NULL
, ALC_INVALID_VALUE
);
3340 alcSetError(NULL
, ALC_INVALID_VALUE
);
3344 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3347 device
= al_calloc(16, sizeof(ALCdevice
));
3350 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3356 device
->Connected
= ALC_TRUE
;
3357 device
->Type
= Capture
;
3359 AL_STRING_INIT(device
->DeviceName
);
3361 InitUIntMap(&device
->BufferMap
, ~0);
3362 InitUIntMap(&device
->EffectMap
, ~0);
3363 InitUIntMap(&device
->FilterMap
, ~0);
3364 InitUIntMap(&device
->SfontMap
, ~0);
3365 InitUIntMap(&device
->PresetMap
, ~0);
3366 InitUIntMap(&device
->FontsoundMap
, ~0);
3368 if(!CaptureBackend
.getFactory
)
3369 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3370 ALCbackend_Capture
);
3373 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3374 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3376 if(!device
->Backend
)
3379 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3383 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3384 device
->Frequency
= frequency
;
3386 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3387 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3390 alcSetError(NULL
, ALC_INVALID_ENUM
);
3394 device
->UpdateSize
= samples
;
3395 device
->NumUpdates
= 1;
3397 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3400 alcSetError(NULL
, err
);
3405 device
->next
= DeviceList
;
3406 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3408 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3412 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*Device
)
3414 ALCdevice
*volatile*list
;
3418 while(*list
&& *list
!= Device
)
3419 list
= &(*list
)->next
;
3421 if(!*list
|| (*list
)->Type
!= Capture
)
3423 alcSetError(*list
, ALC_INVALID_DEVICE
);
3428 *list
= (*list
)->next
;
3431 ALCdevice_DecRef(Device
);
3436 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3438 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3439 alcSetError(device
, ALC_INVALID_DEVICE
);
3442 ALCdevice_Lock(device
);
3443 if(device
->Connected
)
3445 if(!(device
->Flags
&DEVICE_RUNNING
))
3446 V0(device
->Backend
,start
)();
3447 device
->Flags
|= DEVICE_RUNNING
;
3449 ALCdevice_Unlock(device
);
3452 if(device
) ALCdevice_DecRef(device
);
3455 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3457 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3458 alcSetError(device
, ALC_INVALID_DEVICE
);
3461 ALCdevice_Lock(device
);
3462 if((device
->Flags
&DEVICE_RUNNING
))
3463 V0(device
->Backend
,stop
)();
3464 device
->Flags
&= ~DEVICE_RUNNING
;
3465 ALCdevice_Unlock(device
);
3468 if(device
) ALCdevice_DecRef(device
);
3471 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3473 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3474 alcSetError(device
, ALC_INVALID_DEVICE
);
3477 ALCenum err
= ALC_INVALID_VALUE
;
3479 ALCdevice_Lock(device
);
3480 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3481 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3482 ALCdevice_Unlock(device
);
3484 if(err
!= ALC_NO_ERROR
)
3485 alcSetError(device
, err
);
3487 if(device
) ALCdevice_DecRef(device
);
3491 /************************************************
3492 * ALC loopback functions
3493 ************************************************/
3495 /* alcLoopbackOpenDeviceSOFT
3497 * Open a loopback device, for manual rendering.
3499 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3501 ALCbackendFactory
*factory
;
3506 /* Make sure the device name, if specified, is us. */
3507 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3509 alcSetError(NULL
, ALC_INVALID_VALUE
);
3513 device
= al_calloc(16, sizeof(ALCdevice
));
3516 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3522 device
->Connected
= ALC_TRUE
;
3523 device
->Type
= Loopback
;
3524 device
->LastError
= ALC_NO_ERROR
;
3527 device
->Bs2b
= NULL
;
3528 device
->Bs2bLevel
= 0;
3529 AL_STRING_INIT(device
->DeviceName
);
3531 device
->ContextList
= NULL
;
3533 device
->ClockBase
= 0;
3534 device
->SamplesDone
= 0;
3536 device
->MaxNoOfSources
= 256;
3537 device
->AuxiliaryEffectSlotMax
= 4;
3538 device
->NumAuxSends
= MAX_SENDS
;
3540 InitUIntMap(&device
->BufferMap
, ~0);
3541 InitUIntMap(&device
->EffectMap
, ~0);
3542 InitUIntMap(&device
->FilterMap
, ~0);
3543 InitUIntMap(&device
->SfontMap
, ~0);
3544 InitUIntMap(&device
->PresetMap
, ~0);
3545 InitUIntMap(&device
->FontsoundMap
, ~0);
3547 factory
= ALCloopbackFactory_getFactory();
3548 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3549 if(!device
->Backend
)
3552 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3557 device
->NumUpdates
= 0;
3558 device
->UpdateSize
= 0;
3560 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3561 device
->FmtChans
= DevFmtChannelsDefault
;
3562 device
->FmtType
= DevFmtTypeDefault
;
3564 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3565 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3567 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3568 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3570 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3571 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3573 device
->NumStereoSources
= 1;
3574 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3576 device
->Synth
= SynthCreate(device
);
3579 DELETE_OBJ(device
->Backend
);
3581 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3585 // Open the "backend"
3586 V(device
->Backend
,open
)("Loopback");
3588 device
->next
= DeviceList
;
3589 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3591 TRACE("Created device %p\n", device
);
3595 /* alcIsRenderFormatSupportedSOFT
3597 * Determines if the loopback device supports the given format for rendering.
3599 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3601 ALCboolean ret
= ALC_FALSE
;
3603 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3604 alcSetError(device
, ALC_INVALID_DEVICE
);
3606 alcSetError(device
, ALC_INVALID_VALUE
);
3609 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3610 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3611 freq
>= MIN_OUTPUT_RATE
)
3614 if(device
) ALCdevice_DecRef(device
);
3619 /* alcRenderSamplesSOFT
3621 * Renders some samples into a buffer, using the format last set by the
3622 * attributes given to alcCreateContext.
3624 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3626 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3627 alcSetError(device
, ALC_INVALID_DEVICE
);
3628 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3629 alcSetError(device
, ALC_INVALID_VALUE
);
3631 aluMixData(device
, buffer
, samples
);
3632 if(device
) ALCdevice_DecRef(device
);
3636 /************************************************
3637 * ALC DSP pause/resume functions
3638 ************************************************/
3640 /* alcDevicePauseSOFT
3642 * Pause the DSP to stop audio processing.
3644 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3646 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3647 alcSetError(device
, ALC_INVALID_DEVICE
);
3651 if((device
->Flags
&DEVICE_RUNNING
))
3652 V0(device
->Backend
,stop
)();
3653 device
->Flags
&= ~DEVICE_RUNNING
;
3654 device
->Flags
|= DEVICE_PAUSED
;
3657 if(device
) ALCdevice_DecRef(device
);
3660 /* alcDeviceResumeSOFT
3662 * Resume the DSP to restart audio processing.
3664 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3666 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3667 alcSetError(device
, ALC_INVALID_DEVICE
);
3671 if((device
->Flags
&DEVICE_PAUSED
))
3673 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3675 device
->Flags
|= DEVICE_RUNNING
;
3676 device
->Flags
&= ~DEVICE_PAUSED
;
3680 alcSetError(device
, ALC_INVALID_DEVICE
);
3681 ALCdevice_Lock(device
);
3682 aluHandleDisconnect(device
);
3683 ALCdevice_Unlock(device
);
3688 if(device
) ALCdevice_DecRef(device
);