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
),
568 DECL(AL_FILTER_HIGHPASS
),
569 DECL(AL_FILTER_BANDPASS
),
571 DECL(AL_LOWPASS_GAIN
),
572 DECL(AL_LOWPASS_GAINHF
),
574 DECL(AL_HIGHPASS_GAIN
),
575 DECL(AL_HIGHPASS_GAINLF
),
577 DECL(AL_BANDPASS_GAIN
),
578 DECL(AL_BANDPASS_GAINHF
),
579 DECL(AL_BANDPASS_GAINLF
),
581 DECL(AL_EFFECT_TYPE
),
582 DECL(AL_EFFECT_NULL
),
583 DECL(AL_EFFECT_REVERB
),
584 DECL(AL_EFFECT_EAXREVERB
),
585 DECL(AL_EFFECT_CHORUS
),
586 DECL(AL_EFFECT_DISTORTION
),
587 DECL(AL_EFFECT_ECHO
),
588 DECL(AL_EFFECT_FLANGER
),
590 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
591 DECL(AL_EFFECT_VOCAL_MORPHER
),
592 DECL(AL_EFFECT_PITCH_SHIFTER
),
594 DECL(AL_EFFECT_RING_MODULATOR
),
595 DECL(AL_EFFECT_AUTOWAH
),
596 DECL(AL_EFFECT_COMPRESSOR
),
597 DECL(AL_EFFECT_EQUALIZER
),
598 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
599 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
601 DECL(AL_EAXREVERB_DENSITY
),
602 DECL(AL_EAXREVERB_DIFFUSION
),
603 DECL(AL_EAXREVERB_GAIN
),
604 DECL(AL_EAXREVERB_GAINHF
),
605 DECL(AL_EAXREVERB_GAINLF
),
606 DECL(AL_EAXREVERB_DECAY_TIME
),
607 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
608 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
609 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
610 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
611 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
612 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
613 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
614 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
615 DECL(AL_EAXREVERB_ECHO_TIME
),
616 DECL(AL_EAXREVERB_ECHO_DEPTH
),
617 DECL(AL_EAXREVERB_MODULATION_TIME
),
618 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
619 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
620 DECL(AL_EAXREVERB_HFREFERENCE
),
621 DECL(AL_EAXREVERB_LFREFERENCE
),
622 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
623 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
625 DECL(AL_REVERB_DENSITY
),
626 DECL(AL_REVERB_DIFFUSION
),
627 DECL(AL_REVERB_GAIN
),
628 DECL(AL_REVERB_GAINHF
),
629 DECL(AL_REVERB_DECAY_TIME
),
630 DECL(AL_REVERB_DECAY_HFRATIO
),
631 DECL(AL_REVERB_REFLECTIONS_GAIN
),
632 DECL(AL_REVERB_REFLECTIONS_DELAY
),
633 DECL(AL_REVERB_LATE_REVERB_GAIN
),
634 DECL(AL_REVERB_LATE_REVERB_DELAY
),
635 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
636 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
637 DECL(AL_REVERB_DECAY_HFLIMIT
),
639 DECL(AL_CHORUS_WAVEFORM
),
640 DECL(AL_CHORUS_PHASE
),
641 DECL(AL_CHORUS_RATE
),
642 DECL(AL_CHORUS_DEPTH
),
643 DECL(AL_CHORUS_FEEDBACK
),
644 DECL(AL_CHORUS_DELAY
),
646 DECL(AL_DISTORTION_EDGE
),
647 DECL(AL_DISTORTION_GAIN
),
648 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
649 DECL(AL_DISTORTION_EQCENTER
),
650 DECL(AL_DISTORTION_EQBANDWIDTH
),
653 DECL(AL_ECHO_LRDELAY
),
654 DECL(AL_ECHO_DAMPING
),
655 DECL(AL_ECHO_FEEDBACK
),
656 DECL(AL_ECHO_SPREAD
),
658 DECL(AL_FLANGER_WAVEFORM
),
659 DECL(AL_FLANGER_PHASE
),
660 DECL(AL_FLANGER_RATE
),
661 DECL(AL_FLANGER_DEPTH
),
662 DECL(AL_FLANGER_FEEDBACK
),
663 DECL(AL_FLANGER_DELAY
),
665 DECL(AL_RING_MODULATOR_FREQUENCY
),
666 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
667 DECL(AL_RING_MODULATOR_WAVEFORM
),
669 DECL(AL_AUTOWAH_ATTACK_TIME
),
670 DECL(AL_AUTOWAH_PEAK_GAIN
),
671 DECL(AL_AUTOWAH_RELEASE_TIME
),
672 DECL(AL_AUTOWAH_RESONANCE
),
674 DECL(AL_COMPRESSOR_ONOFF
),
676 DECL(AL_EQUALIZER_LOW_GAIN
),
677 DECL(AL_EQUALIZER_LOW_CUTOFF
),
678 DECL(AL_EQUALIZER_MID1_GAIN
),
679 DECL(AL_EQUALIZER_MID1_CENTER
),
680 DECL(AL_EQUALIZER_MID1_WIDTH
),
681 DECL(AL_EQUALIZER_MID2_GAIN
),
682 DECL(AL_EQUALIZER_MID2_CENTER
),
683 DECL(AL_EQUALIZER_MID2_WIDTH
),
684 DECL(AL_EQUALIZER_HIGH_GAIN
),
685 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
687 DECL(AL_DEDICATED_GAIN
),
693 static const ALCchar alcNoError
[] = "No Error";
694 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
695 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
696 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
697 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
698 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
701 /************************************************
703 ************************************************/
705 /* Enumerated device names */
706 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
708 static al_string alcAllDevicesList
;
709 static al_string alcCaptureDeviceList
;
711 /* Default is always the first in the list */
712 static ALCchar
*alcDefaultAllDevicesSpecifier
;
713 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
715 /* Default context extensions */
716 static const ALchar alExtList
[] =
717 "AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 "
718 "AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW "
719 "AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model "
720 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_buffer_samples "
721 "AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates AL_SOFT_direct_channels "
722 "AL_SOFT_loop_points AL_SOFTX_MSADPCM AL_SOFT_source_latency "
723 "AL_SOFTX_source_length";
725 static volatile ALCenum LastNullDeviceError
= ALC_NO_ERROR
;
727 /* Thread-local current context */
728 static altss_t LocalContext
;
729 /* Process-wide current context */
730 static ALCcontext
*volatile GlobalContext
= NULL
;
732 /* Mixing thread piority level */
737 enum LogLevel LogLevel
= LogWarning
;
739 enum LogLevel LogLevel
= LogError
;
742 /* Flag to trap ALC device errors */
743 static ALCboolean TrapALCError
= ALC_FALSE
;
745 /* One-time configuration init control */
746 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
748 /* Default effect that applies to sources that don't have an effect on send 0 */
749 static ALeffect DefaultEffect
;
752 /************************************************
754 ************************************************/
755 static const ALCchar alcNoDeviceExtList
[] =
756 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
757 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
758 static const ALCchar alcExtensionList
[] =
759 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
760 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
761 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
762 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFTX_pause_device";
763 static const ALCint alcMajorVersion
= 1;
764 static const ALCint alcMinorVersion
= 1;
766 static const ALCint alcEFXMajorVersion
= 1;
767 static const ALCint alcEFXMinorVersion
= 0;
770 /************************************************
772 ************************************************/
773 static ALCdevice
*volatile DeviceList
= NULL
;
775 static almtx_t ListLock
;
776 static inline void LockLists(void)
778 int lockret
= almtx_lock(&ListLock
);
779 assert(lockret
== althrd_success
);
781 static inline void UnlockLists(void)
783 int unlockret
= almtx_unlock(&ListLock
);
784 assert(unlockret
== althrd_success
);
787 /************************************************
788 * Library initialization
789 ************************************************/
791 static void alc_init(void);
792 static void alc_deinit(void);
793 static void alc_deinit_safe(void);
795 #ifndef AL_LIBTYPE_STATIC
796 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
800 case DLL_PROCESS_ATTACH
:
801 /* Pin the DLL so we won't get unloaded until the process terminates */
802 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
803 (WCHAR
*)hModule
, &hModule
);
807 case DLL_THREAD_DETACH
:
810 case DLL_PROCESS_DETACH
:
819 #elif defined(_MSC_VER)
820 #pragma section(".CRT$XCU",read)
821 static void alc_constructor(void);
822 static void alc_destructor(void);
823 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
825 static void alc_constructor(void)
827 atexit(alc_destructor
);
831 static void alc_destructor(void)
835 #elif defined(HAVE_GCC_DESTRUCTOR)
836 static void alc_init(void) __attribute__((constructor
));
837 static void alc_deinit(void) __attribute__((destructor
));
839 #error "No static initialization available on this platform!"
842 #elif defined(HAVE_GCC_DESTRUCTOR)
844 static void alc_init(void) __attribute__((constructor
));
845 static void alc_deinit(void) __attribute__((destructor
));
848 #error "No global initialization available on this platform!"
851 static void ReleaseThreadCtx(void *ptr
);
852 static void alc_init(void)
859 AL_STRING_INIT(alcAllDevicesList
);
860 AL_STRING_INIT(alcCaptureDeviceList
);
862 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
863 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
866 str
= getenv("__ALSOFT_REVERSE_Z");
867 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
870 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
871 assert(ret
== althrd_success
);
873 ret
= almtx_init(&ListLock
, almtx_recursive
);
874 assert(ret
== althrd_success
);
879 static void alc_initconfig(void)
881 const char *devs
, *str
;
886 str
= getenv("ALSOFT_LOGLEVEL");
889 long lvl
= strtol(str
, NULL
, 0);
890 if(lvl
>= NoLog
&& lvl
<= LogRef
)
894 str
= getenv("ALSOFT_LOGFILE");
897 FILE *logfile
= al_fopen(str
, "wt");
898 if(logfile
) LogFile
= logfile
;
899 else ERR("Failed to open log file '%s'\n", str
);
904 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
905 for(i
= 1;BackendList
[i
].name
;i
++)
906 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
907 TRACE("Supported backends: %s\n", buf
);
913 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
916 capfilter
|= CPU_CAP_NEON
;
918 if(ConfigValueStr(NULL
, "disable-cpu-exts", &str
))
920 if(strcasecmp(str
, "all") == 0)
925 const char *next
= str
;
929 while(isspace(str
[0]))
931 next
= strchr(str
, ',');
933 if(!str
[0] || str
[0] == ',')
936 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
937 while(len
> 0 && isspace(str
[len
-1]))
939 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
940 capfilter
&= ~CPU_CAP_SSE
;
941 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
942 capfilter
&= ~CPU_CAP_SSE2
;
943 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
944 capfilter
&= ~CPU_CAP_NEON
;
946 WARN("Invalid CPU extension \"%s\"\n", str
);
950 FillCPUCaps(capfilter
);
957 ConfigValueInt(NULL
, "rt-prio", &RTPrioLevel
);
959 if(ConfigValueStr(NULL
, "resampler", &str
))
961 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
962 DefaultResampler
= PointResampler
;
963 else if(strcasecmp(str
, "linear") == 0)
964 DefaultResampler
= LinearResampler
;
965 else if(strcasecmp(str
, "cubic") == 0)
966 DefaultResampler
= CubicResampler
;
971 n
= strtol(str
, &end
, 0);
972 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== CubicResampler
))
973 DefaultResampler
= n
;
975 WARN("Invalid resampler: %s\n", str
);
979 str
= getenv("ALSOFT_TRAP_ERROR");
980 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
982 TrapALError
= AL_TRUE
;
983 TrapALCError
= AL_TRUE
;
987 str
= getenv("ALSOFT_TRAP_AL_ERROR");
988 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
989 TrapALError
= AL_TRUE
;
990 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
992 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
993 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
994 TrapALCError
= ALC_TRUE
;
995 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
998 if(ConfigValueFloat("reverb", "boost", &valf
))
999 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1001 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
1003 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1004 ConfigValueStr(NULL
, "drivers", &devs
))
1008 const char *next
= devs
;
1009 int endlist
, delitem
;
1014 while(isspace(devs
[0]))
1016 next
= strchr(devs
, ',');
1018 delitem
= (devs
[0] == '-');
1019 if(devs
[0] == '-') devs
++;
1021 if(!devs
[0] || devs
[0] == ',')
1028 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1029 while(len
> 0 && isspace(devs
[len
-1]))
1031 for(n
= i
;BackendList
[n
].name
;n
++)
1033 if(len
== strlen(BackendList
[n
].name
) &&
1034 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1039 BackendList
[n
] = BackendList
[n
+1];
1041 } while(BackendList
[n
].name
);
1045 struct BackendInfo Bkp
= BackendList
[n
];
1048 BackendList
[n
] = BackendList
[n
-1];
1051 BackendList
[n
] = Bkp
;
1062 BackendList
[i
].name
= NULL
;
1063 BackendList
[i
].getFactory
= NULL
;
1064 BackendList
[i
].Init
= NULL
;
1065 BackendList
[i
].Deinit
= NULL
;
1066 BackendList
[i
].Probe
= NULL
;
1070 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1072 if(BackendList
[i
].getFactory
)
1074 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1075 if(!V0(factory
,init
)())
1077 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1081 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1082 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1084 PlaybackBackend
= BackendList
[i
];
1085 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1087 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1089 CaptureBackend
= BackendList
[i
];
1090 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1096 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1098 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1102 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1103 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1105 PlaybackBackend
= BackendList
[i
];
1106 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1108 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1110 CaptureBackend
= BackendList
[i
];
1111 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1115 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1119 if(ConfigValueStr(NULL
, "excludefx", &str
))
1122 const char *next
= str
;
1126 next
= strchr(str
, ',');
1128 if(!str
[0] || next
== str
)
1131 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1132 for(n
= 0;EffectList
[n
].name
;n
++)
1134 if(len
== strlen(EffectList
[n
].name
) &&
1135 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1136 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1141 InitEffectFactoryMap();
1143 InitEffect(&DefaultEffect
);
1144 str
= getenv("ALSOFT_DEFAULT_REVERB");
1145 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1146 LoadReverbPreset(str
, &DefaultEffect
);
1148 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1151 /************************************************
1152 * Library deinitialization
1153 ************************************************/
1154 static void alc_cleanup(void)
1158 AL_STRING_DEINIT(alcAllDevicesList
);
1159 AL_STRING_DEINIT(alcCaptureDeviceList
);
1161 free(alcDefaultAllDevicesSpecifier
);
1162 alcDefaultAllDevicesSpecifier
= NULL
;
1163 free(alcCaptureDefaultDeviceSpecifier
);
1164 alcCaptureDefaultDeviceSpecifier
= NULL
;
1166 if((dev
=ExchangePtr((XchgPtr
*)&DeviceList
, NULL
)) != NULL
)
1171 } while((dev
=dev
->next
) != NULL
);
1172 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1175 DeinitEffectFactoryMap();
1178 static void alc_deinit_safe(void)
1186 almtx_destroy(&ListLock
);
1187 altss_delete(LocalContext
);
1189 if(LogFile
!= stderr
)
1194 static void alc_deinit(void)
1200 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1201 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1203 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1205 if(!BackendList
[i
].getFactory
)
1206 BackendList
[i
].Deinit();
1209 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1210 V0(factory
,deinit
)();
1214 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1215 V0(factory
,deinit
)();
1222 /************************************************
1223 * Device enumeration
1224 ************************************************/
1225 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1230 al_string_clear(list
);
1232 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1234 if(!PlaybackBackend
.getFactory
)
1235 PlaybackBackend
.Probe(type
);
1238 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1239 V(factory
,probe
)(type
);
1242 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1244 if(!CaptureBackend
.getFactory
)
1245 CaptureBackend
.Probe(type
);
1248 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1249 V(factory
,probe
)(type
);
1254 static void ProbeAllDevicesList(void)
1255 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1256 static void ProbeCaptureDeviceList(void)
1257 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1259 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1261 size_t len
= strlen(name
);
1264 al_string_append_range(devnames
, name
, name
+len
);
1265 al_string_append_char(devnames
, '\0');
1268 void AppendAllDevicesList(const ALCchar
*name
)
1269 { AppendDevice(name
, &alcAllDevicesList
); }
1270 void AppendCaptureDeviceList(const ALCchar
*name
)
1271 { AppendDevice(name
, &alcCaptureDeviceList
); }
1274 /************************************************
1275 * Device format information
1276 ************************************************/
1277 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1281 case DevFmtByte
: return "Signed Byte";
1282 case DevFmtUByte
: return "Unsigned Byte";
1283 case DevFmtShort
: return "Signed Short";
1284 case DevFmtUShort
: return "Unsigned Short";
1285 case DevFmtInt
: return "Signed Int";
1286 case DevFmtUInt
: return "Unsigned Int";
1287 case DevFmtFloat
: return "Float";
1289 return "(unknown type)";
1291 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1295 case DevFmtMono
: return "Mono";
1296 case DevFmtStereo
: return "Stereo";
1297 case DevFmtQuad
: return "Quadraphonic";
1298 case DevFmtX51
: return "5.1 Surround";
1299 case DevFmtX51Side
: return "5.1 Side";
1300 case DevFmtX61
: return "6.1 Surround";
1301 case DevFmtX71
: return "7.1 Surround";
1303 return "(unknown channels)";
1306 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1307 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1311 case DevFmtByte
: return sizeof(ALbyte
);
1312 case DevFmtUByte
: return sizeof(ALubyte
);
1313 case DevFmtShort
: return sizeof(ALshort
);
1314 case DevFmtUShort
: return sizeof(ALushort
);
1315 case DevFmtInt
: return sizeof(ALint
);
1316 case DevFmtUInt
: return sizeof(ALuint
);
1317 case DevFmtFloat
: return sizeof(ALfloat
);
1321 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1325 case DevFmtMono
: return 1;
1326 case DevFmtStereo
: return 2;
1327 case DevFmtQuad
: return 4;
1328 case DevFmtX51
: return 6;
1329 case DevFmtX51Side
: return 6;
1330 case DevFmtX61
: return 7;
1331 case DevFmtX71
: return 8;
1336 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1337 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1339 static const struct {
1341 enum DevFmtChannels channels
;
1342 enum DevFmtType type
;
1344 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1345 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1346 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1348 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1349 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1350 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1352 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1353 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1354 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1356 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1357 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1358 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1360 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1361 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1362 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1364 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1365 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1366 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1370 for(i
= 0;i
< COUNTOF(list
);i
++)
1372 if(list
[i
].format
== format
)
1374 *chans
= list
[i
].channels
;
1375 *type
= list
[i
].type
;
1383 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1388 case ALC_UNSIGNED_BYTE_SOFT
:
1389 case ALC_SHORT_SOFT
:
1390 case ALC_UNSIGNED_SHORT_SOFT
:
1392 case ALC_UNSIGNED_INT_SOFT
:
1393 case ALC_FLOAT_SOFT
:
1399 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1404 case ALC_STEREO_SOFT
:
1406 case ALC_5POINT1_SOFT
:
1407 case ALC_6POINT1_SOFT
:
1408 case ALC_7POINT1_SOFT
:
1415 /************************************************
1416 * Miscellaneous ALC helpers
1417 ************************************************/
1418 extern inline void LockContext(ALCcontext
*context
);
1419 extern inline void UnlockContext(ALCcontext
*context
);
1421 ALint64
ALCdevice_GetLatencyDefault(ALCdevice
*UNUSED(device
))
1426 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1428 return V0(device
->Backend
,getLatency
)();
1431 void ALCdevice_Lock(ALCdevice
*device
)
1433 V0(device
->Backend
,lock
)();
1436 void ALCdevice_Unlock(ALCdevice
*device
)
1438 V0(device
->Backend
,unlock
)();
1442 /* SetDefaultWFXChannelOrder
1444 * Sets the default channel order used by WaveFormatEx.
1446 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1450 for(i
= 0;i
< MaxChannels
;i
++)
1451 device
->ChannelOffsets
[i
] = INVALID_OFFSET
;
1453 switch(device
->FmtChans
)
1455 case DevFmtMono
: device
->ChannelOffsets
[FrontCenter
] = 0;
1457 case DevFmtStereo
: device
->ChannelOffsets
[FrontLeft
] = 0;
1458 device
->ChannelOffsets
[FrontRight
] = 1;
1460 case DevFmtQuad
: device
->ChannelOffsets
[FrontLeft
] = 0;
1461 device
->ChannelOffsets
[FrontRight
] = 1;
1462 device
->ChannelOffsets
[BackLeft
] = 2;
1463 device
->ChannelOffsets
[BackRight
] = 3;
1465 case DevFmtX51
: device
->ChannelOffsets
[FrontLeft
] = 0;
1466 device
->ChannelOffsets
[FrontRight
] = 1;
1467 device
->ChannelOffsets
[FrontCenter
] = 2;
1468 device
->ChannelOffsets
[LFE
] = 3;
1469 device
->ChannelOffsets
[BackLeft
] = 4;
1470 device
->ChannelOffsets
[BackRight
] = 5;
1472 case DevFmtX51Side
: device
->ChannelOffsets
[FrontLeft
] = 0;
1473 device
->ChannelOffsets
[FrontRight
] = 1;
1474 device
->ChannelOffsets
[FrontCenter
] = 2;
1475 device
->ChannelOffsets
[LFE
] = 3;
1476 device
->ChannelOffsets
[SideLeft
] = 4;
1477 device
->ChannelOffsets
[SideRight
] = 5;
1479 case DevFmtX61
: device
->ChannelOffsets
[FrontLeft
] = 0;
1480 device
->ChannelOffsets
[FrontRight
] = 1;
1481 device
->ChannelOffsets
[FrontCenter
] = 2;
1482 device
->ChannelOffsets
[LFE
] = 3;
1483 device
->ChannelOffsets
[BackCenter
] = 4;
1484 device
->ChannelOffsets
[SideLeft
] = 5;
1485 device
->ChannelOffsets
[SideRight
] = 6;
1487 case DevFmtX71
: device
->ChannelOffsets
[FrontLeft
] = 0;
1488 device
->ChannelOffsets
[FrontRight
] = 1;
1489 device
->ChannelOffsets
[FrontCenter
] = 2;
1490 device
->ChannelOffsets
[LFE
] = 3;
1491 device
->ChannelOffsets
[BackLeft
] = 4;
1492 device
->ChannelOffsets
[BackRight
] = 5;
1493 device
->ChannelOffsets
[SideLeft
] = 6;
1494 device
->ChannelOffsets
[SideRight
] = 7;
1499 /* SetDefaultChannelOrder
1501 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1503 void SetDefaultChannelOrder(ALCdevice
*device
)
1507 for(i
= 0;i
< MaxChannels
;i
++)
1508 device
->ChannelOffsets
[i
] = INVALID_OFFSET
;
1510 switch(device
->FmtChans
)
1512 case DevFmtX51
: device
->ChannelOffsets
[FrontLeft
] = 0;
1513 device
->ChannelOffsets
[FrontRight
] = 1;
1514 device
->ChannelOffsets
[BackLeft
] = 2;
1515 device
->ChannelOffsets
[BackRight
] = 3;
1516 device
->ChannelOffsets
[FrontCenter
] = 4;
1517 device
->ChannelOffsets
[LFE
] = 5;
1519 case DevFmtX71
: device
->ChannelOffsets
[FrontLeft
] = 0;
1520 device
->ChannelOffsets
[FrontRight
] = 1;
1521 device
->ChannelOffsets
[BackLeft
] = 2;
1522 device
->ChannelOffsets
[BackRight
] = 3;
1523 device
->ChannelOffsets
[FrontCenter
] = 4;
1524 device
->ChannelOffsets
[LFE
] = 5;
1525 device
->ChannelOffsets
[SideLeft
] = 6;
1526 device
->ChannelOffsets
[SideRight
] = 7;
1529 /* Same as WFX order */
1537 SetDefaultWFXChannelOrder(device
);
1543 * Stores the latest ALC device error
1545 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1550 /* DebugBreak() will cause an exception if there is no debugger */
1551 if(IsDebuggerPresent())
1553 #elif defined(SIGTRAP)
1559 device
->LastError
= errorCode
;
1561 LastNullDeviceError
= errorCode
;
1567 * Updates the device's base clock time with however many samples have been
1568 * done. This is used so frequency changes on the device don't cause the time
1569 * to jump forward or back.
1571 static inline void UpdateClockBase(ALCdevice
*device
)
1573 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1574 device
->SamplesDone
= 0;
1577 /* UpdateDeviceParams
1579 * Updates device parameters according to the attribute list (caller is
1580 * responsible for holding the list lock).
1582 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1584 ALCcontext
*context
;
1585 enum DevFmtChannels oldChans
;
1586 enum DevFmtType oldType
;
1590 // Check for attributes
1591 if(device
->Type
== Loopback
)
1597 GotAll
= GotFreq
|GotChans
|GotType
1599 ALCuint freq
, numMono
, numStereo
, numSends
;
1600 enum DevFmtChannels schans
;
1601 enum DevFmtType stype
;
1602 ALCuint attrIdx
= 0;
1607 WARN("Missing attributes for loopback device\n");
1608 return ALC_INVALID_VALUE
;
1611 numMono
= device
->NumMonoSources
;
1612 numStereo
= device
->NumStereoSources
;
1613 numSends
= device
->NumAuxSends
;
1614 schans
= device
->FmtChans
;
1615 stype
= device
->FmtType
;
1616 freq
= device
->Frequency
;
1618 while(attrList
[attrIdx
])
1620 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1622 ALCint val
= attrList
[attrIdx
+ 1];
1623 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1624 return ALC_INVALID_VALUE
;
1629 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1631 ALCint val
= attrList
[attrIdx
+ 1];
1632 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1633 return ALC_INVALID_VALUE
;
1638 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1640 freq
= attrList
[attrIdx
+ 1];
1641 if(freq
< MIN_OUTPUT_RATE
)
1642 return ALC_INVALID_VALUE
;
1646 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1648 numStereo
= attrList
[attrIdx
+ 1];
1649 if(numStereo
> device
->MaxNoOfSources
)
1650 numStereo
= device
->MaxNoOfSources
;
1652 numMono
= device
->MaxNoOfSources
- numStereo
;
1655 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1656 numSends
= attrList
[attrIdx
+ 1];
1658 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1660 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1661 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1663 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1669 if(gotFmt
!= GotAll
)
1671 WARN("Missing format for loopback device\n");
1672 return ALC_INVALID_VALUE
;
1675 ConfigValueUInt(NULL
, "sends", &numSends
);
1676 numSends
= minu(MAX_SENDS
, numSends
);
1678 if((device
->Flags
&DEVICE_RUNNING
))
1679 V0(device
->Backend
,stop
)();
1680 device
->Flags
&= ~DEVICE_RUNNING
;
1682 if(freq
!= device
->Frequency
)
1683 UpdateClockBase(device
);
1684 device
->Frequency
= freq
;
1685 device
->FmtChans
= schans
;
1686 device
->FmtType
= stype
;
1687 device
->NumMonoSources
= numMono
;
1688 device
->NumStereoSources
= numStereo
;
1689 device
->NumAuxSends
= numSends
;
1691 else if(attrList
&& attrList
[0])
1693 ALCuint freq
, numMono
, numStereo
, numSends
;
1694 ALCuint attrIdx
= 0;
1696 /* If a context is already running on the device, stop playback so the
1697 * device attributes can be updated. */
1698 if((device
->Flags
&DEVICE_RUNNING
))
1699 V0(device
->Backend
,stop
)();
1700 device
->Flags
&= ~DEVICE_RUNNING
;
1702 freq
= device
->Frequency
;
1703 numMono
= device
->NumMonoSources
;
1704 numStereo
= device
->NumStereoSources
;
1705 numSends
= device
->NumAuxSends
;
1707 while(attrList
[attrIdx
])
1709 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1711 freq
= attrList
[attrIdx
+ 1];
1712 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1715 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1717 numStereo
= attrList
[attrIdx
+ 1];
1718 if(numStereo
> device
->MaxNoOfSources
)
1719 numStereo
= device
->MaxNoOfSources
;
1721 numMono
= device
->MaxNoOfSources
- numStereo
;
1724 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1725 numSends
= attrList
[attrIdx
+ 1];
1727 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1729 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1730 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1732 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1738 ConfigValueUInt(NULL
, "frequency", &freq
);
1739 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1741 ConfigValueUInt(NULL
, "sends", &numSends
);
1742 numSends
= minu(MAX_SENDS
, numSends
);
1744 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1746 /* SSE and Neon do best with the update size being a multiple of 4 */
1747 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1748 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1750 if(freq
!= device
->Frequency
)
1751 UpdateClockBase(device
);
1752 device
->Frequency
= freq
;
1753 device
->NumMonoSources
= numMono
;
1754 device
->NumStereoSources
= numStereo
;
1755 device
->NumAuxSends
= numSends
;
1758 if((device
->Flags
&DEVICE_RUNNING
))
1759 return ALC_NO_ERROR
;
1761 UpdateClockBase(device
);
1763 oldFreq
= device
->Frequency
;
1764 oldChans
= device
->FmtChans
;
1765 oldType
= device
->FmtType
;
1767 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1768 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"",
1769 DevFmtChannelsString(device
->FmtChans
),
1770 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"",
1771 DevFmtTypeString(device
->FmtType
),
1772 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"",
1774 device
->UpdateSize
, device
->NumUpdates
);
1776 if(device
->Type
!= Loopback
)
1778 int nohrtf
= !(device
->Flags
&DEVICE_HRTF_REQUEST
);
1779 if(GetConfigValueBool(NULL
, "hrtf", !nohrtf
))
1780 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1782 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1784 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1786 enum DevFmtChannels chans
;
1788 if(FindHrtfFormat(device
, &chans
, &freq
))
1790 device
->Frequency
= freq
;
1791 device
->FmtChans
= chans
;
1792 device
->Flags
|= DEVICE_CHANNELS_REQUEST
|
1793 DEVICE_FREQUENCY_REQUEST
;
1797 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1798 return ALC_INVALID_DEVICE
;
1800 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1802 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1803 DevFmtChannelsString(device
->FmtChans
));
1804 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1806 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1808 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1809 DevFmtTypeString(device
->FmtType
));
1810 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1812 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1814 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1815 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1818 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1819 DevFmtChannelsString(device
->FmtChans
),
1820 DevFmtTypeString(device
->FmtType
), device
->Frequency
,
1821 device
->UpdateSize
, device
->NumUpdates
);
1823 aluInitPanning(device
);
1825 V(device
->Synth
,update
)(device
);
1827 device
->Hrtf
= NULL
;
1828 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1830 device
->Hrtf
= GetHrtf(device
);
1832 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1834 TRACE("HRTF %s\n", device
->Hrtf
?"enabled":"disabled");
1836 if(!device
->Hrtf
&& device
->Bs2bLevel
> 0 && device
->Bs2bLevel
<= 6)
1840 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
1841 bs2b_clear(device
->Bs2b
);
1843 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
1844 bs2b_set_level(device
->Bs2b
, device
->Bs2bLevel
);
1845 TRACE("BS2B level %d\n", device
->Bs2bLevel
);
1850 device
->Bs2b
= NULL
;
1851 TRACE("BS2B disabled\n");
1854 device
->Flags
&= ~DEVICE_WIDE_STEREO
;
1855 if(device
->Type
!= Loopback
&& !device
->Hrtf
&& GetConfigValueBool(NULL
, "wide-stereo", AL_FALSE
))
1856 device
->Flags
|= DEVICE_WIDE_STEREO
;
1858 if(!device
->Hrtf
&& (device
->UpdateSize
&3))
1860 if((CPUCapFlags
&CPU_CAP_SSE
))
1861 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1862 if((CPUCapFlags
&CPU_CAP_NEON
))
1863 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1866 SetMixerFPUMode(&oldMode
);
1867 ALCdevice_Lock(device
);
1868 context
= device
->ContextList
;
1873 context
->UpdateSources
= AL_FALSE
;
1874 LockUIntMapRead(&context
->EffectSlotMap
);
1875 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
1877 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
1879 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1881 UnlockUIntMapRead(&context
->EffectSlotMap
);
1882 ALCdevice_Unlock(device
);
1883 RestoreFPUMode(&oldMode
);
1884 return ALC_INVALID_DEVICE
;
1886 slot
->NeedsUpdate
= AL_FALSE
;
1887 V(slot
->EffectState
,update
)(device
, slot
);
1889 UnlockUIntMapRead(&context
->EffectSlotMap
);
1891 LockUIntMapRead(&context
->SourceMap
);
1892 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1894 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
1895 ALuint s
= device
->NumAuxSends
;
1896 while(s
< MAX_SENDS
)
1898 if(source
->Send
[s
].Slot
)
1899 DecrementRef(&source
->Send
[s
].Slot
->ref
);
1900 source
->Send
[s
].Slot
= NULL
;
1901 source
->Send
[s
].Gain
= 1.0f
;
1902 source
->Send
[s
].GainHF
= 1.0f
;
1905 source
->NeedsUpdate
= AL_TRUE
;
1907 UnlockUIntMapRead(&context
->SourceMap
);
1909 for(pos
= 0;pos
< context
->ActiveSourceCount
;pos
++)
1911 ALactivesource
*src
= context
->ActiveSources
[pos
];
1912 ALsource
*source
= src
->Source
;
1913 ALuint s
= device
->NumAuxSends
;
1914 while(s
< MAX_SENDS
)
1916 src
->Send
[s
].Moving
= AL_FALSE
;
1917 src
->Send
[s
].Counter
= 0;
1921 src
->Update(src
, context
);
1922 source
->NeedsUpdate
= AL_FALSE
;
1925 context
= context
->next
;
1927 if(device
->DefaultSlot
)
1929 ALeffectslot
*slot
= device
->DefaultSlot
;
1931 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1933 ALCdevice_Unlock(device
);
1934 RestoreFPUMode(&oldMode
);
1935 return ALC_INVALID_DEVICE
;
1937 slot
->NeedsUpdate
= AL_FALSE
;
1938 V(slot
->EffectState
,update
)(device
, slot
);
1940 ALCdevice_Unlock(device
);
1941 RestoreFPUMode(&oldMode
);
1943 if(!(device
->Flags
&DEVICE_PAUSED
))
1945 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
1946 return ALC_INVALID_DEVICE
;
1947 device
->Flags
|= DEVICE_RUNNING
;
1950 return ALC_NO_ERROR
;
1955 * Frees the device structure, and destroys any objects the app failed to
1956 * delete. Called once there's no more references on the device.
1958 static ALCvoid
FreeDevice(ALCdevice
*device
)
1960 TRACE("%p\n", device
);
1962 V0(device
->Backend
,close
)();
1963 DELETE_OBJ(device
->Backend
);
1964 device
->Backend
= NULL
;
1966 DELETE_OBJ(device
->Synth
);
1967 device
->Synth
= NULL
;
1969 if(device
->DefaultSlot
)
1971 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
1972 device
->DefaultSlot
= NULL
;
1976 if(device
->DefaultSfont
)
1977 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
1978 device
->DefaultSfont
= NULL
;
1980 if(device
->BufferMap
.size
> 0)
1982 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
1983 ReleaseALBuffers(device
);
1985 ResetUIntMap(&device
->BufferMap
);
1987 if(device
->EffectMap
.size
> 0)
1989 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
1990 ReleaseALEffects(device
);
1992 ResetUIntMap(&device
->EffectMap
);
1994 if(device
->FilterMap
.size
> 0)
1996 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
1997 ReleaseALFilters(device
);
1999 ResetUIntMap(&device
->FilterMap
);
2001 if(device
->SfontMap
.size
> 0)
2003 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2004 ReleaseALSoundfonts(device
);
2006 ResetUIntMap(&device
->SfontMap
);
2008 if(device
->PresetMap
.size
> 0)
2010 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2011 ReleaseALPresets(device
);
2013 ResetUIntMap(&device
->PresetMap
);
2015 if(device
->FontsoundMap
.size
> 0)
2017 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2018 ReleaseALFontsounds(device
);
2020 ResetUIntMap(&device
->FontsoundMap
);
2023 device
->Bs2b
= NULL
;
2025 AL_STRING_DEINIT(device
->DeviceName
);
2031 void ALCdevice_IncRef(ALCdevice
*device
)
2034 ref
= IncrementRef(&device
->ref
);
2035 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2038 void ALCdevice_DecRef(ALCdevice
*device
)
2041 ref
= DecrementRef(&device
->ref
);
2042 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2043 if(ref
== 0) FreeDevice(device
);
2048 * Checks if the device handle is valid, and increments its ref count if so.
2050 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2052 ALCdevice
*tmpDevice
;
2058 tmpDevice
= DeviceList
;
2059 while(tmpDevice
&& tmpDevice
!= device
)
2060 tmpDevice
= tmpDevice
->next
;
2063 ALCdevice_IncRef(tmpDevice
);
2071 * Initializes context fields
2073 static ALvoid
InitContext(ALCcontext
*Context
)
2077 //Initialise listener
2078 Context
->Listener
->Gain
= 1.0f
;
2079 Context
->Listener
->MetersPerUnit
= 1.0f
;
2080 Context
->Listener
->Position
[0] = 0.0f
;
2081 Context
->Listener
->Position
[1] = 0.0f
;
2082 Context
->Listener
->Position
[2] = 0.0f
;
2083 Context
->Listener
->Velocity
[0] = 0.0f
;
2084 Context
->Listener
->Velocity
[1] = 0.0f
;
2085 Context
->Listener
->Velocity
[2] = 0.0f
;
2086 Context
->Listener
->Forward
[0] = 0.0f
;
2087 Context
->Listener
->Forward
[1] = 0.0f
;
2088 Context
->Listener
->Forward
[2] = -1.0f
;
2089 Context
->Listener
->Up
[0] = 0.0f
;
2090 Context
->Listener
->Up
[1] = 1.0f
;
2091 Context
->Listener
->Up
[2] = 0.0f
;
2092 for(i
= 0;i
< 4;i
++)
2094 for(j
= 0;j
< 4;j
++)
2095 Context
->Listener
->Params
.Matrix
[i
][j
] = ((i
==j
) ? 1.0f
: 0.0f
);
2097 for(i
= 0;i
< 3;i
++)
2098 Context
->Listener
->Params
.Velocity
[i
] = 0.0f
;
2101 Context
->LastError
= AL_NO_ERROR
;
2102 Context
->UpdateSources
= AL_FALSE
;
2103 Context
->ActiveSourceCount
= 0;
2104 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2105 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2108 Context
->DistanceModel
= DefaultDistanceModel
;
2109 Context
->SourceDistanceModel
= AL_FALSE
;
2110 Context
->DopplerFactor
= 1.0f
;
2111 Context
->DopplerVelocity
= 1.0f
;
2112 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2113 Context
->DeferUpdates
= AL_FALSE
;
2115 Context
->ExtensionList
= alExtList
;
2121 * Cleans up the context, and destroys any remaining objects the app failed to
2122 * delete. Called once there's no more references on the context.
2124 static ALCvoid
FreeContext(ALCcontext
*context
)
2128 TRACE("%p\n", context
);
2130 if(context
->SourceMap
.size
> 0)
2132 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2133 ReleaseALSources(context
);
2135 ResetUIntMap(&context
->SourceMap
);
2137 if(context
->EffectSlotMap
.size
> 0)
2139 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2140 ReleaseALAuxiliaryEffectSlots(context
);
2142 ResetUIntMap(&context
->EffectSlotMap
);
2144 for(i
= 0;i
< context
->MaxActiveSources
;i
++)
2146 al_free(context
->ActiveSources
[i
]);
2147 context
->ActiveSources
[i
] = NULL
;
2149 free(context
->ActiveSources
);
2150 context
->ActiveSources
= NULL
;
2151 context
->ActiveSourceCount
= 0;
2152 context
->MaxActiveSources
= 0;
2154 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2156 ALCdevice_DecRef(context
->Device
);
2157 context
->Device
= NULL
;
2159 //Invalidate context
2160 memset(context
, 0, sizeof(ALCcontext
));
2166 * Removes the context reference from the given device and removes it from
2167 * being current on the running thread or globally.
2169 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2171 ALCcontext
*volatile*tmp_ctx
;
2173 if(altss_get(LocalContext
) == context
)
2175 WARN("%p released while current on thread\n", context
);
2176 altss_set(LocalContext
, NULL
);
2177 ALCcontext_DecRef(context
);
2180 if(CompExchangePtr((XchgPtr
*)&GlobalContext
, context
, NULL
) == context
)
2181 ALCcontext_DecRef(context
);
2183 ALCdevice_Lock(device
);
2184 tmp_ctx
= &device
->ContextList
;
2187 if(CompExchangePtr((XchgPtr
*)tmp_ctx
, context
, context
->next
) == context
)
2189 tmp_ctx
= &(*tmp_ctx
)->next
;
2191 ALCdevice_Unlock(device
);
2193 ALCcontext_DecRef(context
);
2196 void ALCcontext_IncRef(ALCcontext
*context
)
2199 ref
= IncrementRef(&context
->ref
);
2200 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2203 void ALCcontext_DecRef(ALCcontext
*context
)
2206 ref
= DecrementRef(&context
->ref
);
2207 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2208 if(ref
== 0) FreeContext(context
);
2211 static void ReleaseThreadCtx(void *ptr
)
2213 WARN("%p current for thread being destroyed\n", ptr
);
2214 ALCcontext_DecRef(ptr
);
2219 * Checks that the given context is valid, and increments its reference count.
2221 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2229 ALCcontext
*tmp_ctx
= dev
->ContextList
;
2232 if(tmp_ctx
== context
)
2234 ALCcontext_IncRef(tmp_ctx
);
2238 tmp_ctx
= tmp_ctx
->next
;
2250 * Returns the currently active context for this thread, and adds a reference
2251 * without locking it.
2253 ALCcontext
*GetContextRef(void)
2255 ALCcontext
*context
;
2257 context
= altss_get(LocalContext
);
2259 ALCcontext_IncRef(context
);
2263 context
= GlobalContext
;
2265 ALCcontext_IncRef(context
);
2273 /************************************************
2274 * Standard ALC functions
2275 ************************************************/
2279 * Return last ALC generated error code for the given device
2281 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2285 if(VerifyDevice(device
))
2287 errorCode
= ExchangeInt(&device
->LastError
, ALC_NO_ERROR
);
2288 ALCdevice_DecRef(device
);
2291 errorCode
= ExchangeInt(&LastNullDeviceError
, ALC_NO_ERROR
);
2297 /* alcSuspendContext
2301 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*UNUSED(context
))
2305 /* alcProcessContext
2309 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*UNUSED(context
))
2316 * Returns information about the device, and error strings
2318 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2320 const ALCchar
*value
= NULL
;
2328 case ALC_INVALID_ENUM
:
2329 value
= alcErrInvalidEnum
;
2332 case ALC_INVALID_VALUE
:
2333 value
= alcErrInvalidValue
;
2336 case ALC_INVALID_DEVICE
:
2337 value
= alcErrInvalidDevice
;
2340 case ALC_INVALID_CONTEXT
:
2341 value
= alcErrInvalidContext
;
2344 case ALC_OUT_OF_MEMORY
:
2345 value
= alcErrOutOfMemory
;
2348 case ALC_DEVICE_SPECIFIER
:
2349 value
= alcDefaultName
;
2352 case ALC_ALL_DEVICES_SPECIFIER
:
2353 if(VerifyDevice(Device
))
2355 value
= al_string_get_cstr(Device
->DeviceName
);
2356 ALCdevice_DecRef(Device
);
2360 ProbeAllDevicesList();
2361 value
= al_string_get_cstr(alcAllDevicesList
);
2365 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2366 if(VerifyDevice(Device
))
2368 value
= al_string_get_cstr(Device
->DeviceName
);
2369 ALCdevice_DecRef(Device
);
2373 ProbeCaptureDeviceList();
2374 value
= al_string_get_cstr(alcCaptureDeviceList
);
2378 /* Default devices are always first in the list */
2379 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2380 value
= alcDefaultName
;
2383 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2384 if(al_string_empty(alcAllDevicesList
))
2385 ProbeAllDevicesList();
2387 Device
= VerifyDevice(Device
);
2389 free(alcDefaultAllDevicesSpecifier
);
2390 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2391 if(!alcDefaultAllDevicesSpecifier
)
2392 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2394 value
= alcDefaultAllDevicesSpecifier
;
2395 if(Device
) ALCdevice_DecRef(Device
);
2398 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2399 if(al_string_empty(alcCaptureDeviceList
))
2400 ProbeCaptureDeviceList();
2402 Device
= VerifyDevice(Device
);
2404 free(alcCaptureDefaultDeviceSpecifier
);
2405 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2406 if(!alcCaptureDefaultDeviceSpecifier
)
2407 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2409 value
= alcCaptureDefaultDeviceSpecifier
;
2410 if(Device
) ALCdevice_DecRef(Device
);
2413 case ALC_EXTENSIONS
:
2414 if(!VerifyDevice(Device
))
2415 value
= alcNoDeviceExtList
;
2418 value
= alcExtensionList
;
2419 ALCdevice_DecRef(Device
);
2424 Device
= VerifyDevice(Device
);
2425 alcSetError(Device
, ALC_INVALID_ENUM
);
2426 if(Device
) ALCdevice_DecRef(Device
);
2434 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2438 if(size
<= 0 || values
== NULL
)
2440 alcSetError(device
, ALC_INVALID_VALUE
);
2448 case ALC_MAJOR_VERSION
:
2449 values
[0] = alcMajorVersion
;
2451 case ALC_MINOR_VERSION
:
2452 values
[0] = alcMinorVersion
;
2455 case ALC_ATTRIBUTES_SIZE
:
2456 case ALC_ALL_ATTRIBUTES
:
2460 case ALC_MONO_SOURCES
:
2461 case ALC_STEREO_SOURCES
:
2462 case ALC_CAPTURE_SAMPLES
:
2463 case ALC_FORMAT_CHANNELS_SOFT
:
2464 case ALC_FORMAT_TYPE_SOFT
:
2465 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2469 alcSetError(NULL
, ALC_INVALID_ENUM
);
2475 if(device
->Type
== Capture
)
2479 case ALC_CAPTURE_SAMPLES
:
2480 ALCdevice_Lock(device
);
2481 values
[0] = V0(device
->Backend
,availableSamples
)();
2482 ALCdevice_Unlock(device
);
2486 values
[0] = device
->Connected
;
2490 alcSetError(device
, ALC_INVALID_ENUM
);
2499 case ALC_MAJOR_VERSION
:
2500 values
[0] = alcMajorVersion
;
2503 case ALC_MINOR_VERSION
:
2504 values
[0] = alcMinorVersion
;
2507 case ALC_EFX_MAJOR_VERSION
:
2508 values
[0] = alcEFXMajorVersion
;
2511 case ALC_EFX_MINOR_VERSION
:
2512 values
[0] = alcEFXMinorVersion
;
2515 case ALC_ATTRIBUTES_SIZE
:
2519 case ALC_ALL_ATTRIBUTES
:
2522 alcSetError(device
, ALC_INVALID_VALUE
);
2527 values
[i
++] = ALC_FREQUENCY
;
2528 values
[i
++] = device
->Frequency
;
2530 if(device
->Type
!= Loopback
)
2532 values
[i
++] = ALC_REFRESH
;
2533 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2535 values
[i
++] = ALC_SYNC
;
2536 values
[i
++] = ALC_FALSE
;
2540 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2541 values
[i
++] = device
->FmtChans
;
2543 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2544 values
[i
++] = device
->FmtType
;
2547 values
[i
++] = ALC_MONO_SOURCES
;
2548 values
[i
++] = device
->NumMonoSources
;
2550 values
[i
++] = ALC_STEREO_SOURCES
;
2551 values
[i
++] = device
->NumStereoSources
;
2553 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2554 values
[i
++] = device
->NumAuxSends
;
2556 values
[i
++] = ALC_HRTF_SOFT
;
2557 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2563 values
[0] = device
->Frequency
;
2567 if(device
->Type
== Loopback
)
2569 alcSetError(device
, ALC_INVALID_DEVICE
);
2572 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2576 if(device
->Type
== Loopback
)
2578 alcSetError(device
, ALC_INVALID_DEVICE
);
2581 values
[0] = ALC_FALSE
;
2584 case ALC_FORMAT_CHANNELS_SOFT
:
2585 if(device
->Type
!= Loopback
)
2587 alcSetError(device
, ALC_INVALID_DEVICE
);
2590 values
[0] = device
->FmtChans
;
2593 case ALC_FORMAT_TYPE_SOFT
:
2594 if(device
->Type
!= Loopback
)
2596 alcSetError(device
, ALC_INVALID_DEVICE
);
2599 values
[0] = device
->FmtType
;
2602 case ALC_MONO_SOURCES
:
2603 values
[0] = device
->NumMonoSources
;
2606 case ALC_STEREO_SOURCES
:
2607 values
[0] = device
->NumStereoSources
;
2610 case ALC_MAX_AUXILIARY_SENDS
:
2611 values
[0] = device
->NumAuxSends
;
2615 values
[0] = device
->Connected
;
2619 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2623 alcSetError(device
, ALC_INVALID_ENUM
);
2631 * Returns information about the device and the version of OpenAL
2633 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2635 device
= VerifyDevice(device
);
2636 if(size
<= 0 || values
== NULL
)
2637 alcSetError(device
, ALC_INVALID_VALUE
);
2639 GetIntegerv(device
, param
, size
, values
);
2640 if(device
) ALCdevice_DecRef(device
);
2643 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2648 device
= VerifyDevice(device
);
2649 if(size
<= 0 || values
== NULL
)
2650 alcSetError(device
, ALC_INVALID_VALUE
);
2651 else if(!device
|| device
->Type
== Capture
)
2653 ivals
= malloc(size
* sizeof(ALCint
));
2654 size
= GetIntegerv(device
, pname
, size
, ivals
);
2655 for(i
= 0;i
< size
;i
++)
2656 values
[i
] = ivals
[i
];
2659 else /* render device */
2663 case ALC_ATTRIBUTES_SIZE
:
2667 case ALC_ALL_ATTRIBUTES
:
2669 alcSetError(device
, ALC_INVALID_VALUE
);
2674 V0(device
->Backend
,lock
)();
2675 values
[i
++] = ALC_FREQUENCY
;
2676 values
[i
++] = device
->Frequency
;
2678 if(device
->Type
!= Loopback
)
2680 values
[i
++] = ALC_REFRESH
;
2681 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2683 values
[i
++] = ALC_SYNC
;
2684 values
[i
++] = ALC_FALSE
;
2688 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2689 values
[i
++] = device
->FmtChans
;
2691 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2692 values
[i
++] = device
->FmtType
;
2695 values
[i
++] = ALC_MONO_SOURCES
;
2696 values
[i
++] = device
->NumMonoSources
;
2698 values
[i
++] = ALC_STEREO_SOURCES
;
2699 values
[i
++] = device
->NumStereoSources
;
2701 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2702 values
[i
++] = device
->NumAuxSends
;
2704 values
[i
++] = ALC_HRTF_SOFT
;
2705 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2707 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2708 values
[i
++] = device
->ClockBase
+
2709 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2712 V0(device
->Backend
,unlock
)();
2716 case ALC_DEVICE_CLOCK_SOFT
:
2717 V0(device
->Backend
,lock
)();
2718 *values
= device
->ClockBase
+
2719 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2720 V0(device
->Backend
,unlock
)();
2724 ivals
= malloc(size
* sizeof(ALCint
));
2725 size
= GetIntegerv(device
, pname
, size
, ivals
);
2726 for(i
= 0;i
< size
;i
++)
2727 values
[i
] = ivals
[i
];
2733 ALCdevice_DecRef(device
);
2737 /* alcIsExtensionPresent
2739 * Determines if there is support for a particular extension
2741 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2743 ALCboolean bResult
= ALC_FALSE
;
2745 device
= VerifyDevice(device
);
2748 alcSetError(device
, ALC_INVALID_VALUE
);
2751 size_t len
= strlen(extName
);
2752 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2755 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2756 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2761 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2765 } while(isspace(*ptr
));
2770 ALCdevice_DecRef(device
);
2775 /* alcGetProcAddress
2777 * Retrieves the function address for a particular extension function
2779 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2781 ALCvoid
*ptr
= NULL
;
2785 device
= VerifyDevice(device
);
2786 alcSetError(device
, ALC_INVALID_VALUE
);
2787 if(device
) ALCdevice_DecRef(device
);
2792 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2794 ptr
= alcFunctions
[i
].address
;
2803 * Get the value for a particular ALC enumeration name
2805 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
2811 device
= VerifyDevice(device
);
2812 alcSetError(device
, ALC_INVALID_VALUE
);
2813 if(device
) ALCdevice_DecRef(device
);
2818 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
2820 val
= enumeration
[i
].value
;
2829 * Create and attach a context to the given device.
2831 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
2833 ALCcontext
*ALContext
;
2837 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
2840 alcSetError(device
, ALC_INVALID_DEVICE
);
2841 if(device
) ALCdevice_DecRef(device
);
2845 device
->LastError
= ALC_NO_ERROR
;
2847 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
2850 alcSetError(device
, err
);
2851 if(err
== ALC_INVALID_DEVICE
)
2853 ALCdevice_Lock(device
);
2854 aluHandleDisconnect(device
);
2855 ALCdevice_Unlock(device
);
2857 ALCdevice_DecRef(device
);
2861 ALContext
= calloc(1, sizeof(ALCcontext
)+sizeof(ALlistener
));
2864 InitRef(&ALContext
->ref
, 1);
2865 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
2867 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
2869 ALContext
->MaxActiveSources
= 256;
2870 ALContext
->ActiveSources
= calloc(ALContext
->MaxActiveSources
,
2871 sizeof(ALContext
->ActiveSources
[0]));
2873 if(!ALContext
|| !ALContext
->ActiveSources
)
2875 if(!device
->ContextList
)
2877 V0(device
->Backend
,stop
)();
2878 device
->Flags
&= ~DEVICE_RUNNING
;
2884 free(ALContext
->ActiveSources
);
2885 ALContext
->ActiveSources
= NULL
;
2887 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
2893 alcSetError(device
, ALC_OUT_OF_MEMORY
);
2894 ALCdevice_DecRef(device
);
2898 ALContext
->Device
= device
;
2899 ALCdevice_IncRef(device
);
2900 InitContext(ALContext
);
2903 ALContext
->next
= device
->ContextList
;
2904 } while(CompExchangePtr((XchgPtr
*)&device
->ContextList
, ALContext
->next
, ALContext
) != ALContext
->next
);
2907 ALCdevice_DecRef(device
);
2909 TRACE("Created context %p\n", ALContext
);
2913 /* alcDestroyContext
2915 * Remove a context from its device
2917 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
2922 /* alcGetContextsDevice sets an error for invalid contexts */
2923 Device
= alcGetContextsDevice(context
);
2926 ReleaseContext(context
, Device
);
2927 if(!Device
->ContextList
)
2929 V0(Device
->Backend
,stop
)();
2930 Device
->Flags
&= ~DEVICE_RUNNING
;
2937 /* alcGetCurrentContext
2939 * Returns the currently active context on the calling thread
2941 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
2943 ALCcontext
*Context
;
2945 Context
= altss_get(LocalContext
);
2946 if(!Context
) Context
= GlobalContext
;
2951 /* alcGetThreadContext
2953 * Returns the currently active thread-local context
2955 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
2957 ALCcontext
*Context
;
2958 Context
= altss_get(LocalContext
);
2963 /* alcMakeContextCurrent
2965 * Makes the given context the active process-wide context, and removes the
2966 * thread-local context for the calling thread.
2968 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
2970 /* context must be valid or NULL */
2971 if(context
&& !(context
=VerifyContext(context
)))
2973 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2976 /* context's reference count is already incremented */
2977 context
= ExchangePtr((XchgPtr
*)&GlobalContext
, context
);
2978 if(context
) ALCcontext_DecRef(context
);
2980 if((context
=altss_get(LocalContext
)) != NULL
)
2982 altss_set(LocalContext
, NULL
);
2983 ALCcontext_DecRef(context
);
2989 /* alcSetThreadContext
2991 * Makes the given context the active context for the current thread
2993 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
2997 /* context must be valid or NULL */
2998 if(context
&& !(context
=VerifyContext(context
)))
3000 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3003 /* context's reference count is already incremented */
3004 old
= altss_get(LocalContext
);
3005 altss_set(LocalContext
, context
);
3006 if(old
) ALCcontext_DecRef(old
);
3012 /* alcGetContextsDevice
3014 * Returns the device that a particular context is attached to
3016 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3020 if(!(Context
=VerifyContext(Context
)))
3022 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3025 Device
= Context
->Device
;
3026 ALCcontext_DecRef(Context
);
3034 * Opens the named device.
3036 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3044 if(!PlaybackBackend
.name
)
3046 alcSetError(NULL
, ALC_INVALID_VALUE
);
3050 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3053 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3056 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3061 InitRef(&device
->ref
, 1);
3062 device
->Connected
= ALC_TRUE
;
3063 device
->Type
= Playback
;
3064 device
->LastError
= ALC_NO_ERROR
;
3067 device
->Bs2b
= NULL
;
3068 device
->Bs2bLevel
= 0;
3069 AL_STRING_INIT(device
->DeviceName
);
3071 device
->ContextList
= NULL
;
3073 device
->ClockBase
= 0;
3074 device
->SamplesDone
= 0;
3076 device
->MaxNoOfSources
= 256;
3077 device
->AuxiliaryEffectSlotMax
= 4;
3078 device
->NumAuxSends
= MAX_SENDS
;
3080 InitUIntMap(&device
->BufferMap
, ~0);
3081 InitUIntMap(&device
->EffectMap
, ~0);
3082 InitUIntMap(&device
->FilterMap
, ~0);
3083 InitUIntMap(&device
->SfontMap
, ~0);
3084 InitUIntMap(&device
->PresetMap
, ~0);
3085 InitUIntMap(&device
->FontsoundMap
, ~0);
3088 device
->FmtChans
= DevFmtChannelsDefault
;
3089 device
->FmtType
= DevFmtTypeDefault
;
3090 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3091 device
->NumUpdates
= 4;
3092 device
->UpdateSize
= 1024;
3094 if(!PlaybackBackend
.getFactory
)
3095 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3096 ALCbackend_Playback
);
3099 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3100 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3102 if(!device
->Backend
)
3105 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3110 if(ConfigValueStr(NULL
, "channels", &fmt
))
3112 static const struct {
3113 const char name
[16];
3114 enum DevFmtChannels chans
;
3116 { "mono", DevFmtMono
},
3117 { "stereo", DevFmtStereo
},
3118 { "quad", DevFmtQuad
},
3119 { "surround51", DevFmtX51
},
3120 { "surround61", DevFmtX61
},
3121 { "surround71", DevFmtX71
},
3125 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3127 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3129 device
->FmtChans
= chanlist
[i
].chans
;
3130 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3134 if(i
== COUNTOF(chanlist
))
3135 ERR("Unsupported channels: %s\n", fmt
);
3137 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3139 static const struct {
3140 const char name
[16];
3141 enum DevFmtType type
;
3143 { "int8", DevFmtByte
},
3144 { "uint8", DevFmtUByte
},
3145 { "int16", DevFmtShort
},
3146 { "uint16", DevFmtUShort
},
3147 { "int32", DevFmtInt
},
3148 { "uint32", DevFmtUInt
},
3149 { "float32", DevFmtFloat
},
3153 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3155 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3157 device
->FmtType
= typelist
[i
].type
;
3158 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3162 if(i
== COUNTOF(typelist
))
3163 ERR("Unsupported sample-type: %s\n", fmt
);
3165 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3166 if((device
->Flags
&DEVICE_FORMAT_REQUEST
) != DEVICE_FORMAT_REQUEST
&&
3167 ConfigValueStr(NULL
, "format", &fmt
))
3169 static const struct {
3170 const char name
[32];
3171 enum DevFmtChannels channels
;
3172 enum DevFmtType type
;
3174 { "AL_FORMAT_MONO32", DevFmtMono
, DevFmtFloat
},
3175 { "AL_FORMAT_STEREO32", DevFmtStereo
, DevFmtFloat
},
3176 { "AL_FORMAT_QUAD32", DevFmtQuad
, DevFmtFloat
},
3177 { "AL_FORMAT_51CHN32", DevFmtX51
, DevFmtFloat
},
3178 { "AL_FORMAT_61CHN32", DevFmtX61
, DevFmtFloat
},
3179 { "AL_FORMAT_71CHN32", DevFmtX71
, DevFmtFloat
},
3181 { "AL_FORMAT_MONO16", DevFmtMono
, DevFmtShort
},
3182 { "AL_FORMAT_STEREO16", DevFmtStereo
, DevFmtShort
},
3183 { "AL_FORMAT_QUAD16", DevFmtQuad
, DevFmtShort
},
3184 { "AL_FORMAT_51CHN16", DevFmtX51
, DevFmtShort
},
3185 { "AL_FORMAT_61CHN16", DevFmtX61
, DevFmtShort
},
3186 { "AL_FORMAT_71CHN16", DevFmtX71
, DevFmtShort
},
3188 { "AL_FORMAT_MONO8", DevFmtMono
, DevFmtByte
},
3189 { "AL_FORMAT_STEREO8", DevFmtStereo
, DevFmtByte
},
3190 { "AL_FORMAT_QUAD8", DevFmtQuad
, DevFmtByte
},
3191 { "AL_FORMAT_51CHN8", DevFmtX51
, DevFmtByte
},
3192 { "AL_FORMAT_61CHN8", DevFmtX61
, DevFmtByte
},
3193 { "AL_FORMAT_71CHN8", DevFmtX71
, DevFmtByte
}
3197 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3198 for(i
= 0;i
< COUNTOF(formats
);i
++)
3200 if(strcasecmp(fmt
, formats
[i
].name
) == 0)
3202 if(!(device
->Flags
&DEVICE_CHANNELS_REQUEST
))
3203 device
->FmtChans
= formats
[i
].channels
;
3204 if(!(device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
3205 device
->FmtType
= formats
[i
].type
;
3206 device
->Flags
|= DEVICE_FORMAT_REQUEST
;
3210 if(i
== COUNTOF(formats
))
3211 ERR("Unsupported format: %s\n", fmt
);
3213 #undef DEVICE_FORMAT_REQUEST
3215 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3217 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3218 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3219 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3220 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3223 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3224 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3226 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3227 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3228 if((CPUCapFlags
&CPU_CAP_SSE
))
3229 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3231 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3232 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3234 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3235 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3237 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3238 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3240 ConfigValueInt(NULL
, "cf_level", &device
->Bs2bLevel
);
3242 device
->NumStereoSources
= 1;
3243 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3245 device
->Synth
= SynthCreate(device
);
3248 DELETE_OBJ(device
->Backend
);
3250 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3254 // Find a playback device to open
3255 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3257 DELETE_OBJ(device
->Synth
);
3258 DELETE_OBJ(device
->Backend
);
3260 alcSetError(NULL
, err
);
3264 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3266 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3267 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3269 device
->DefaultSlot
= NULL
;
3270 ERR("Failed to initialize the default effect slot\n");
3272 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3274 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3275 device
->DefaultSlot
= NULL
;
3277 ERR("Failed to initialize the default effect\n");
3282 device
->next
= DeviceList
;
3283 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3285 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3291 * Closes the given device.
3293 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*Device
)
3295 ALCdevice
*volatile*list
;
3300 while(*list
&& *list
!= Device
)
3301 list
= &(*list
)->next
;
3303 if(!*list
|| (*list
)->Type
== Capture
)
3305 alcSetError(*list
, ALC_INVALID_DEVICE
);
3310 *list
= (*list
)->next
;
3313 while((ctx
=Device
->ContextList
) != NULL
)
3315 WARN("Releasing context %p\n", ctx
);
3316 ReleaseContext(ctx
, Device
);
3318 if((Device
->Flags
&DEVICE_RUNNING
))
3319 V0(Device
->Backend
,stop
)();
3320 Device
->Flags
&= ~DEVICE_RUNNING
;
3322 ALCdevice_DecRef(Device
);
3328 /************************************************
3329 * ALC capture functions
3330 ************************************************/
3331 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3333 ALCdevice
*device
= NULL
;
3338 if(!CaptureBackend
.name
)
3340 alcSetError(NULL
, ALC_INVALID_VALUE
);
3346 alcSetError(NULL
, ALC_INVALID_VALUE
);
3350 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3353 device
= al_calloc(16, sizeof(ALCdevice
));
3356 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3361 InitRef(&device
->ref
, 1);
3362 device
->Connected
= ALC_TRUE
;
3363 device
->Type
= Capture
;
3365 AL_STRING_INIT(device
->DeviceName
);
3367 InitUIntMap(&device
->BufferMap
, ~0);
3368 InitUIntMap(&device
->EffectMap
, ~0);
3369 InitUIntMap(&device
->FilterMap
, ~0);
3370 InitUIntMap(&device
->SfontMap
, ~0);
3371 InitUIntMap(&device
->PresetMap
, ~0);
3372 InitUIntMap(&device
->FontsoundMap
, ~0);
3374 if(!CaptureBackend
.getFactory
)
3375 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3376 ALCbackend_Capture
);
3379 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3380 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3382 if(!device
->Backend
)
3385 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3389 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3390 device
->Frequency
= frequency
;
3392 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3393 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3396 alcSetError(NULL
, ALC_INVALID_ENUM
);
3400 device
->UpdateSize
= samples
;
3401 device
->NumUpdates
= 1;
3403 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3406 alcSetError(NULL
, err
);
3411 device
->next
= DeviceList
;
3412 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3414 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3418 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*Device
)
3420 ALCdevice
*volatile*list
;
3424 while(*list
&& *list
!= Device
)
3425 list
= &(*list
)->next
;
3427 if(!*list
|| (*list
)->Type
!= Capture
)
3429 alcSetError(*list
, ALC_INVALID_DEVICE
);
3434 *list
= (*list
)->next
;
3437 ALCdevice_DecRef(Device
);
3442 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3444 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3445 alcSetError(device
, ALC_INVALID_DEVICE
);
3448 ALCdevice_Lock(device
);
3449 if(device
->Connected
)
3451 if(!(device
->Flags
&DEVICE_RUNNING
))
3452 V0(device
->Backend
,start
)();
3453 device
->Flags
|= DEVICE_RUNNING
;
3455 ALCdevice_Unlock(device
);
3458 if(device
) ALCdevice_DecRef(device
);
3461 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3463 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3464 alcSetError(device
, ALC_INVALID_DEVICE
);
3467 ALCdevice_Lock(device
);
3468 if((device
->Flags
&DEVICE_RUNNING
))
3469 V0(device
->Backend
,stop
)();
3470 device
->Flags
&= ~DEVICE_RUNNING
;
3471 ALCdevice_Unlock(device
);
3474 if(device
) ALCdevice_DecRef(device
);
3477 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3479 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3480 alcSetError(device
, ALC_INVALID_DEVICE
);
3483 ALCenum err
= ALC_INVALID_VALUE
;
3485 ALCdevice_Lock(device
);
3486 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3487 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3488 ALCdevice_Unlock(device
);
3490 if(err
!= ALC_NO_ERROR
)
3491 alcSetError(device
, err
);
3493 if(device
) ALCdevice_DecRef(device
);
3497 /************************************************
3498 * ALC loopback functions
3499 ************************************************/
3501 /* alcLoopbackOpenDeviceSOFT
3503 * Open a loopback device, for manual rendering.
3505 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3507 ALCbackendFactory
*factory
;
3512 /* Make sure the device name, if specified, is us. */
3513 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3515 alcSetError(NULL
, ALC_INVALID_VALUE
);
3519 device
= al_calloc(16, sizeof(ALCdevice
));
3522 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3527 InitRef(&device
->ref
, 1);
3528 device
->Connected
= ALC_TRUE
;
3529 device
->Type
= Loopback
;
3530 device
->LastError
= ALC_NO_ERROR
;
3533 device
->Bs2b
= NULL
;
3534 device
->Bs2bLevel
= 0;
3535 AL_STRING_INIT(device
->DeviceName
);
3537 device
->ContextList
= NULL
;
3539 device
->ClockBase
= 0;
3540 device
->SamplesDone
= 0;
3542 device
->MaxNoOfSources
= 256;
3543 device
->AuxiliaryEffectSlotMax
= 4;
3544 device
->NumAuxSends
= MAX_SENDS
;
3546 InitUIntMap(&device
->BufferMap
, ~0);
3547 InitUIntMap(&device
->EffectMap
, ~0);
3548 InitUIntMap(&device
->FilterMap
, ~0);
3549 InitUIntMap(&device
->SfontMap
, ~0);
3550 InitUIntMap(&device
->PresetMap
, ~0);
3551 InitUIntMap(&device
->FontsoundMap
, ~0);
3553 factory
= ALCloopbackFactory_getFactory();
3554 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3555 if(!device
->Backend
)
3558 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3563 device
->NumUpdates
= 0;
3564 device
->UpdateSize
= 0;
3566 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3567 device
->FmtChans
= DevFmtChannelsDefault
;
3568 device
->FmtType
= DevFmtTypeDefault
;
3570 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3571 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3573 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3574 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3576 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3577 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3579 device
->NumStereoSources
= 1;
3580 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3582 device
->Synth
= SynthCreate(device
);
3585 DELETE_OBJ(device
->Backend
);
3587 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3591 // Open the "backend"
3592 V(device
->Backend
,open
)("Loopback");
3594 device
->next
= DeviceList
;
3595 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3597 TRACE("Created device %p\n", device
);
3601 /* alcIsRenderFormatSupportedSOFT
3603 * Determines if the loopback device supports the given format for rendering.
3605 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3607 ALCboolean ret
= ALC_FALSE
;
3609 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3610 alcSetError(device
, ALC_INVALID_DEVICE
);
3612 alcSetError(device
, ALC_INVALID_VALUE
);
3615 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3616 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3617 freq
>= MIN_OUTPUT_RATE
)
3620 if(device
) ALCdevice_DecRef(device
);
3625 /* alcRenderSamplesSOFT
3627 * Renders some samples into a buffer, using the format last set by the
3628 * attributes given to alcCreateContext.
3630 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3632 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3633 alcSetError(device
, ALC_INVALID_DEVICE
);
3634 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3635 alcSetError(device
, ALC_INVALID_VALUE
);
3637 aluMixData(device
, buffer
, samples
);
3638 if(device
) ALCdevice_DecRef(device
);
3642 /************************************************
3643 * ALC DSP pause/resume functions
3644 ************************************************/
3646 /* alcDevicePauseSOFT
3648 * Pause the DSP to stop audio processing.
3650 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3652 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3653 alcSetError(device
, ALC_INVALID_DEVICE
);
3657 if((device
->Flags
&DEVICE_RUNNING
))
3658 V0(device
->Backend
,stop
)();
3659 device
->Flags
&= ~DEVICE_RUNNING
;
3660 device
->Flags
|= DEVICE_PAUSED
;
3663 if(device
) ALCdevice_DecRef(device
);
3666 /* alcDeviceResumeSOFT
3668 * Resume the DSP to restart audio processing.
3670 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3672 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3673 alcSetError(device
, ALC_INVALID_DEVICE
);
3677 if((device
->Flags
&DEVICE_PAUSED
))
3679 device
->Flags
&= ~DEVICE_PAUSED
;
3680 if(device
->ContextList
!= NULL
)
3682 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3683 device
->Flags
|= DEVICE_RUNNING
;
3686 alcSetError(device
, ALC_INVALID_DEVICE
);
3687 ALCdevice_Lock(device
);
3688 aluHandleDisconnect(device
);
3689 ALCdevice_Unlock(device
);
3695 if(device
) ALCdevice_DecRef(device
);