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_SOFTX_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";
724 static volatile ALCenum LastNullDeviceError
= ALC_NO_ERROR
;
726 /* Thread-local current context */
727 static altss_t LocalContext
;
728 /* Process-wide current context */
729 static ALCcontext
*volatile GlobalContext
= NULL
;
731 /* Mixing thread piority level */
736 enum LogLevel LogLevel
= LogWarning
;
738 enum LogLevel LogLevel
= LogError
;
741 /* Flag to trap ALC device errors */
742 static ALCboolean TrapALCError
= ALC_FALSE
;
744 /* One-time configuration init control */
745 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
747 /* Default effect that applies to sources that don't have an effect on send 0 */
748 static ALeffect DefaultEffect
;
751 /************************************************
753 ************************************************/
754 static const ALCchar alcNoDeviceExtList
[] =
755 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
756 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
757 static const ALCchar alcExtensionList
[] =
758 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
759 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
760 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
761 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFTX_pause_device";
762 static const ALCint alcMajorVersion
= 1;
763 static const ALCint alcMinorVersion
= 1;
765 static const ALCint alcEFXMajorVersion
= 1;
766 static const ALCint alcEFXMinorVersion
= 0;
769 /************************************************
771 ************************************************/
772 static ALCdevice
*volatile DeviceList
= NULL
;
774 static almtx_t ListLock
;
775 static inline void LockLists(void)
777 int lockret
= almtx_lock(&ListLock
);
778 assert(lockret
== althrd_success
);
780 static inline void UnlockLists(void)
782 int unlockret
= almtx_unlock(&ListLock
);
783 assert(unlockret
== althrd_success
);
786 /************************************************
787 * Library initialization
788 ************************************************/
790 static void alc_init(void);
791 static void alc_deinit(void);
792 static void alc_deinit_safe(void);
794 #ifndef AL_LIBTYPE_STATIC
795 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
799 case DLL_PROCESS_ATTACH
:
800 /* Pin the DLL so we won't get unloaded until the process terminates */
801 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
802 (WCHAR
*)hModule
, &hModule
);
806 case DLL_THREAD_DETACH
:
809 case DLL_PROCESS_DETACH
:
818 #elif defined(_MSC_VER)
819 #pragma section(".CRT$XCU",read)
820 static void alc_constructor(void);
821 static void alc_destructor(void);
822 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
824 static void alc_constructor(void)
826 atexit(alc_destructor
);
830 static void alc_destructor(void)
834 #elif defined(HAVE_GCC_DESTRUCTOR)
835 static void alc_init(void) __attribute__((constructor
));
836 static void alc_deinit(void) __attribute__((destructor
));
838 #error "No static initialization available on this platform!"
841 #elif defined(HAVE_GCC_DESTRUCTOR)
843 static void alc_init(void) __attribute__((constructor
));
844 static void alc_deinit(void) __attribute__((destructor
));
847 #error "No global initialization available on this platform!"
850 static void ReleaseThreadCtx(void *ptr
);
851 static void alc_init(void)
858 AL_STRING_INIT(alcAllDevicesList
);
859 AL_STRING_INIT(alcCaptureDeviceList
);
861 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
862 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
865 str
= getenv("__ALSOFT_REVERSE_Z");
866 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
869 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
870 assert(ret
== althrd_success
);
872 ret
= almtx_init(&ListLock
, almtx_recursive
);
873 assert(ret
== althrd_success
);
878 static void alc_initconfig(void)
880 const char *devs
, *str
;
885 str
= getenv("ALSOFT_LOGLEVEL");
888 long lvl
= strtol(str
, NULL
, 0);
889 if(lvl
>= NoLog
&& lvl
<= LogRef
)
893 str
= getenv("ALSOFT_LOGFILE");
896 FILE *logfile
= al_fopen(str
, "wt");
897 if(logfile
) LogFile
= logfile
;
898 else ERR("Failed to open log file '%s'\n", str
);
903 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
904 for(i
= 1;BackendList
[i
].name
;i
++)
905 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
906 TRACE("Supported backends: %s\n", buf
);
912 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
915 capfilter
|= CPU_CAP_NEON
;
917 if(ConfigValueStr(NULL
, "disable-cpu-exts", &str
))
919 if(strcasecmp(str
, "all") == 0)
924 const char *next
= str
;
928 while(isspace(str
[0]))
930 next
= strchr(str
, ',');
932 if(!str
[0] || str
[0] == ',')
935 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
936 while(len
> 0 && isspace(str
[len
-1]))
938 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
939 capfilter
&= ~CPU_CAP_SSE
;
940 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
941 capfilter
&= ~CPU_CAP_SSE2
;
942 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
943 capfilter
&= ~CPU_CAP_NEON
;
945 WARN("Invalid CPU extension \"%s\"\n", str
);
949 FillCPUCaps(capfilter
);
956 ConfigValueInt(NULL
, "rt-prio", &RTPrioLevel
);
958 if(ConfigValueStr(NULL
, "resampler", &str
))
960 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
961 DefaultResampler
= PointResampler
;
962 else if(strcasecmp(str
, "linear") == 0)
963 DefaultResampler
= LinearResampler
;
964 else if(strcasecmp(str
, "cubic") == 0)
965 DefaultResampler
= CubicResampler
;
970 n
= strtol(str
, &end
, 0);
971 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== CubicResampler
))
972 DefaultResampler
= n
;
974 WARN("Invalid resampler: %s\n", str
);
978 str
= getenv("ALSOFT_TRAP_ERROR");
979 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
981 TrapALError
= AL_TRUE
;
982 TrapALCError
= AL_TRUE
;
986 str
= getenv("ALSOFT_TRAP_AL_ERROR");
987 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
988 TrapALError
= AL_TRUE
;
989 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
991 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
992 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
993 TrapALCError
= ALC_TRUE
;
994 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
997 if(ConfigValueFloat("reverb", "boost", &valf
))
998 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1000 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
1002 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1003 ConfigValueStr(NULL
, "drivers", &devs
))
1007 const char *next
= devs
;
1008 int endlist
, delitem
;
1013 while(isspace(devs
[0]))
1015 next
= strchr(devs
, ',');
1017 delitem
= (devs
[0] == '-');
1018 if(devs
[0] == '-') devs
++;
1020 if(!devs
[0] || devs
[0] == ',')
1027 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1028 while(len
> 0 && isspace(devs
[len
-1]))
1030 for(n
= i
;BackendList
[n
].name
;n
++)
1032 if(len
== strlen(BackendList
[n
].name
) &&
1033 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1038 BackendList
[n
] = BackendList
[n
+1];
1040 } while(BackendList
[n
].name
);
1044 struct BackendInfo Bkp
= BackendList
[n
];
1047 BackendList
[n
] = BackendList
[n
-1];
1050 BackendList
[n
] = Bkp
;
1061 BackendList
[i
].name
= NULL
;
1062 BackendList
[i
].getFactory
= NULL
;
1063 BackendList
[i
].Init
= NULL
;
1064 BackendList
[i
].Deinit
= NULL
;
1065 BackendList
[i
].Probe
= NULL
;
1069 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1071 if(BackendList
[i
].getFactory
)
1073 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1074 if(!V0(factory
,init
)())
1076 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1080 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1081 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1083 PlaybackBackend
= BackendList
[i
];
1084 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1086 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1088 CaptureBackend
= BackendList
[i
];
1089 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1095 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1097 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1101 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1102 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1104 PlaybackBackend
= BackendList
[i
];
1105 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1107 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1109 CaptureBackend
= BackendList
[i
];
1110 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1114 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1118 if(ConfigValueStr(NULL
, "excludefx", &str
))
1121 const char *next
= str
;
1125 next
= strchr(str
, ',');
1127 if(!str
[0] || next
== str
)
1130 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1131 for(n
= 0;EffectList
[n
].name
;n
++)
1133 if(len
== strlen(EffectList
[n
].name
) &&
1134 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1135 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1140 InitEffectFactoryMap();
1142 InitEffect(&DefaultEffect
);
1143 str
= getenv("ALSOFT_DEFAULT_REVERB");
1144 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1145 LoadReverbPreset(str
, &DefaultEffect
);
1147 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1150 /************************************************
1151 * Library deinitialization
1152 ************************************************/
1153 static void alc_cleanup(void)
1157 AL_STRING_DEINIT(alcAllDevicesList
);
1158 AL_STRING_DEINIT(alcCaptureDeviceList
);
1160 free(alcDefaultAllDevicesSpecifier
);
1161 alcDefaultAllDevicesSpecifier
= NULL
;
1162 free(alcCaptureDefaultDeviceSpecifier
);
1163 alcCaptureDefaultDeviceSpecifier
= NULL
;
1165 if((dev
=ExchangePtr((XchgPtr
*)&DeviceList
, NULL
)) != NULL
)
1170 } while((dev
=dev
->next
) != NULL
);
1171 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1174 DeinitEffectFactoryMap();
1177 static void alc_deinit_safe(void)
1185 almtx_destroy(&ListLock
);
1186 altss_delete(LocalContext
);
1188 if(LogFile
!= stderr
)
1193 static void alc_deinit(void)
1199 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1200 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1202 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1204 if(!BackendList
[i
].getFactory
)
1205 BackendList
[i
].Deinit();
1208 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1209 V0(factory
,deinit
)();
1213 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1214 V0(factory
,deinit
)();
1221 /************************************************
1222 * Device enumeration
1223 ************************************************/
1224 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1229 al_string_clear(list
);
1231 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1233 if(!PlaybackBackend
.getFactory
)
1234 PlaybackBackend
.Probe(type
);
1237 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1238 V(factory
,probe
)(type
);
1241 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1243 if(!CaptureBackend
.getFactory
)
1244 CaptureBackend
.Probe(type
);
1247 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1248 V(factory
,probe
)(type
);
1253 static void ProbeAllDevicesList(void)
1254 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1255 static void ProbeCaptureDeviceList(void)
1256 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1258 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1260 size_t len
= strlen(name
);
1263 al_string_append_range(devnames
, name
, name
+len
);
1264 al_string_append_char(devnames
, '\0');
1267 void AppendAllDevicesList(const ALCchar
*name
)
1268 { AppendDevice(name
, &alcAllDevicesList
); }
1269 void AppendCaptureDeviceList(const ALCchar
*name
)
1270 { AppendDevice(name
, &alcCaptureDeviceList
); }
1273 /************************************************
1274 * Device format information
1275 ************************************************/
1276 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1280 case DevFmtByte
: return "Signed Byte";
1281 case DevFmtUByte
: return "Unsigned Byte";
1282 case DevFmtShort
: return "Signed Short";
1283 case DevFmtUShort
: return "Unsigned Short";
1284 case DevFmtInt
: return "Signed Int";
1285 case DevFmtUInt
: return "Unsigned Int";
1286 case DevFmtFloat
: return "Float";
1288 return "(unknown type)";
1290 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1294 case DevFmtMono
: return "Mono";
1295 case DevFmtStereo
: return "Stereo";
1296 case DevFmtQuad
: return "Quadraphonic";
1297 case DevFmtX51
: return "5.1 Surround";
1298 case DevFmtX51Side
: return "5.1 Side";
1299 case DevFmtX61
: return "6.1 Surround";
1300 case DevFmtX71
: return "7.1 Surround";
1302 return "(unknown channels)";
1305 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1306 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1310 case DevFmtByte
: return sizeof(ALbyte
);
1311 case DevFmtUByte
: return sizeof(ALubyte
);
1312 case DevFmtShort
: return sizeof(ALshort
);
1313 case DevFmtUShort
: return sizeof(ALushort
);
1314 case DevFmtInt
: return sizeof(ALint
);
1315 case DevFmtUInt
: return sizeof(ALuint
);
1316 case DevFmtFloat
: return sizeof(ALfloat
);
1320 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1324 case DevFmtMono
: return 1;
1325 case DevFmtStereo
: return 2;
1326 case DevFmtQuad
: return 4;
1327 case DevFmtX51
: return 6;
1328 case DevFmtX51Side
: return 6;
1329 case DevFmtX61
: return 7;
1330 case DevFmtX71
: return 8;
1335 static ALboolean
DecomposeDevFormat(ALenum format
, enum DevFmtChannels
*chans
,
1336 enum DevFmtType
*type
)
1338 static const struct {
1340 enum DevFmtChannels channels
;
1341 enum DevFmtType type
;
1343 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1344 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1345 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1347 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1348 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1349 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1351 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1352 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1353 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1355 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1356 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1357 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1359 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1360 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1361 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1363 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1364 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1365 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1369 for(i
= 0;i
< COUNTOF(list
);i
++)
1371 if(list
[i
].format
== format
)
1373 *chans
= list
[i
].channels
;
1374 *type
= list
[i
].type
;
1382 static ALCboolean
IsValidALCType(ALCenum type
)
1387 case ALC_UNSIGNED_BYTE_SOFT
:
1388 case ALC_SHORT_SOFT
:
1389 case ALC_UNSIGNED_SHORT_SOFT
:
1391 case ALC_UNSIGNED_INT_SOFT
:
1392 case ALC_FLOAT_SOFT
:
1398 static ALCboolean
IsValidALCChannels(ALCenum channels
)
1403 case ALC_STEREO_SOFT
:
1405 case ALC_5POINT1_SOFT
:
1406 case ALC_6POINT1_SOFT
:
1407 case ALC_7POINT1_SOFT
:
1414 /************************************************
1415 * Miscellaneous ALC helpers
1416 ************************************************/
1417 extern inline void LockContext(ALCcontext
*context
);
1418 extern inline void UnlockContext(ALCcontext
*context
);
1420 ALint64
ALCdevice_GetLatencyDefault(ALCdevice
*UNUSED(device
))
1425 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1427 return V0(device
->Backend
,getLatency
)();
1430 void ALCdevice_Lock(ALCdevice
*device
)
1432 V0(device
->Backend
,lock
)();
1435 void ALCdevice_Unlock(ALCdevice
*device
)
1437 V0(device
->Backend
,unlock
)();
1441 /* SetDefaultWFXChannelOrder
1443 * Sets the default channel order used by WaveFormatEx.
1445 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1449 for(i
= 0;i
< MaxChannels
;i
++)
1450 device
->ChannelOffsets
[i
] = INVALID_OFFSET
;
1452 switch(device
->FmtChans
)
1454 case DevFmtMono
: device
->ChannelOffsets
[FrontCenter
] = 0;
1456 case DevFmtStereo
: device
->ChannelOffsets
[FrontLeft
] = 0;
1457 device
->ChannelOffsets
[FrontRight
] = 1;
1459 case DevFmtQuad
: device
->ChannelOffsets
[FrontLeft
] = 0;
1460 device
->ChannelOffsets
[FrontRight
] = 1;
1461 device
->ChannelOffsets
[BackLeft
] = 2;
1462 device
->ChannelOffsets
[BackRight
] = 3;
1464 case DevFmtX51
: device
->ChannelOffsets
[FrontLeft
] = 0;
1465 device
->ChannelOffsets
[FrontRight
] = 1;
1466 device
->ChannelOffsets
[FrontCenter
] = 2;
1467 device
->ChannelOffsets
[LFE
] = 3;
1468 device
->ChannelOffsets
[BackLeft
] = 4;
1469 device
->ChannelOffsets
[BackRight
] = 5;
1471 case DevFmtX51Side
: device
->ChannelOffsets
[FrontLeft
] = 0;
1472 device
->ChannelOffsets
[FrontRight
] = 1;
1473 device
->ChannelOffsets
[FrontCenter
] = 2;
1474 device
->ChannelOffsets
[LFE
] = 3;
1475 device
->ChannelOffsets
[SideLeft
] = 4;
1476 device
->ChannelOffsets
[SideRight
] = 5;
1478 case DevFmtX61
: device
->ChannelOffsets
[FrontLeft
] = 0;
1479 device
->ChannelOffsets
[FrontRight
] = 1;
1480 device
->ChannelOffsets
[FrontCenter
] = 2;
1481 device
->ChannelOffsets
[LFE
] = 3;
1482 device
->ChannelOffsets
[BackCenter
] = 4;
1483 device
->ChannelOffsets
[SideLeft
] = 5;
1484 device
->ChannelOffsets
[SideRight
] = 6;
1486 case DevFmtX71
: device
->ChannelOffsets
[FrontLeft
] = 0;
1487 device
->ChannelOffsets
[FrontRight
] = 1;
1488 device
->ChannelOffsets
[FrontCenter
] = 2;
1489 device
->ChannelOffsets
[LFE
] = 3;
1490 device
->ChannelOffsets
[BackLeft
] = 4;
1491 device
->ChannelOffsets
[BackRight
] = 5;
1492 device
->ChannelOffsets
[SideLeft
] = 6;
1493 device
->ChannelOffsets
[SideRight
] = 7;
1498 /* SetDefaultChannelOrder
1500 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1502 void SetDefaultChannelOrder(ALCdevice
*device
)
1506 for(i
= 0;i
< MaxChannels
;i
++)
1507 device
->ChannelOffsets
[i
] = INVALID_OFFSET
;
1509 switch(device
->FmtChans
)
1511 case DevFmtX51
: device
->ChannelOffsets
[FrontLeft
] = 0;
1512 device
->ChannelOffsets
[FrontRight
] = 1;
1513 device
->ChannelOffsets
[BackLeft
] = 2;
1514 device
->ChannelOffsets
[BackRight
] = 3;
1515 device
->ChannelOffsets
[FrontCenter
] = 4;
1516 device
->ChannelOffsets
[LFE
] = 5;
1518 case DevFmtX71
: device
->ChannelOffsets
[FrontLeft
] = 0;
1519 device
->ChannelOffsets
[FrontRight
] = 1;
1520 device
->ChannelOffsets
[BackLeft
] = 2;
1521 device
->ChannelOffsets
[BackRight
] = 3;
1522 device
->ChannelOffsets
[FrontCenter
] = 4;
1523 device
->ChannelOffsets
[LFE
] = 5;
1524 device
->ChannelOffsets
[SideLeft
] = 6;
1525 device
->ChannelOffsets
[SideRight
] = 7;
1528 /* Same as WFX order */
1536 SetDefaultWFXChannelOrder(device
);
1542 * Stores the latest ALC device error
1544 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1549 /* DebugBreak() will cause an exception if there is no debugger */
1550 if(IsDebuggerPresent())
1552 #elif defined(SIGTRAP)
1558 device
->LastError
= errorCode
;
1560 LastNullDeviceError
= errorCode
;
1566 * Updates the device's base clock time with however many samples have been
1567 * done. This is used so frequency changes on the device don't cause the time
1568 * to jump forward or back.
1570 static inline void UpdateClockBase(ALCdevice
*device
)
1572 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1573 device
->SamplesDone
= 0;
1576 /* UpdateDeviceParams
1578 * Updates device parameters according to the attribute list (caller is
1579 * responsible for holding the list lock).
1581 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1583 ALCcontext
*context
;
1584 enum DevFmtChannels oldChans
;
1585 enum DevFmtType oldType
;
1589 // Check for attributes
1590 if(device
->Type
== Loopback
)
1596 GotAll
= GotFreq
|GotChans
|GotType
1598 ALCuint freq
, numMono
, numStereo
, numSends
;
1599 enum DevFmtChannels schans
;
1600 enum DevFmtType stype
;
1601 ALCuint attrIdx
= 0;
1606 WARN("Missing attributes for loopback device\n");
1607 return ALC_INVALID_VALUE
;
1610 numMono
= device
->NumMonoSources
;
1611 numStereo
= device
->NumStereoSources
;
1612 numSends
= device
->NumAuxSends
;
1613 schans
= device
->FmtChans
;
1614 stype
= device
->FmtType
;
1615 freq
= device
->Frequency
;
1617 while(attrList
[attrIdx
])
1619 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1621 ALCint val
= attrList
[attrIdx
+ 1];
1622 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1623 return ALC_INVALID_VALUE
;
1628 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1630 ALCint val
= attrList
[attrIdx
+ 1];
1631 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1632 return ALC_INVALID_VALUE
;
1637 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1639 freq
= attrList
[attrIdx
+ 1];
1640 if(freq
< MIN_OUTPUT_RATE
)
1641 return ALC_INVALID_VALUE
;
1645 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1647 numStereo
= attrList
[attrIdx
+ 1];
1648 if(numStereo
> device
->MaxNoOfSources
)
1649 numStereo
= device
->MaxNoOfSources
;
1651 numMono
= device
->MaxNoOfSources
- numStereo
;
1654 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1655 numSends
= attrList
[attrIdx
+ 1];
1657 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1659 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1660 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1662 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1668 if(gotFmt
!= GotAll
)
1670 WARN("Missing format for loopback device\n");
1671 return ALC_INVALID_VALUE
;
1674 ConfigValueUInt(NULL
, "sends", &numSends
);
1675 numSends
= minu(MAX_SENDS
, numSends
);
1677 if((device
->Flags
&DEVICE_RUNNING
))
1678 V0(device
->Backend
,stop
)();
1679 device
->Flags
&= ~DEVICE_RUNNING
;
1681 if(freq
!= device
->Frequency
)
1682 UpdateClockBase(device
);
1683 device
->Frequency
= freq
;
1684 device
->FmtChans
= schans
;
1685 device
->FmtType
= stype
;
1686 device
->NumMonoSources
= numMono
;
1687 device
->NumStereoSources
= numStereo
;
1688 device
->NumAuxSends
= numSends
;
1690 else if(attrList
&& attrList
[0])
1692 ALCuint freq
, numMono
, numStereo
, numSends
;
1693 ALCuint attrIdx
= 0;
1695 /* If a context is already running on the device, stop playback so the
1696 * device attributes can be updated. */
1697 if((device
->Flags
&DEVICE_RUNNING
))
1698 V0(device
->Backend
,stop
)();
1699 device
->Flags
&= ~DEVICE_RUNNING
;
1701 freq
= device
->Frequency
;
1702 numMono
= device
->NumMonoSources
;
1703 numStereo
= device
->NumStereoSources
;
1704 numSends
= device
->NumAuxSends
;
1706 while(attrList
[attrIdx
])
1708 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1710 freq
= attrList
[attrIdx
+ 1];
1711 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1714 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1716 numStereo
= attrList
[attrIdx
+ 1];
1717 if(numStereo
> device
->MaxNoOfSources
)
1718 numStereo
= device
->MaxNoOfSources
;
1720 numMono
= device
->MaxNoOfSources
- numStereo
;
1723 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1724 numSends
= attrList
[attrIdx
+ 1];
1726 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1728 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1729 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1731 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1737 ConfigValueUInt(NULL
, "frequency", &freq
);
1738 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1740 ConfigValueUInt(NULL
, "sends", &numSends
);
1741 numSends
= minu(MAX_SENDS
, numSends
);
1743 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1745 /* SSE and Neon do best with the update size being a multiple of 4 */
1746 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1747 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1749 if(freq
!= device
->Frequency
)
1750 UpdateClockBase(device
);
1751 device
->Frequency
= freq
;
1752 device
->NumMonoSources
= numMono
;
1753 device
->NumStereoSources
= numStereo
;
1754 device
->NumAuxSends
= numSends
;
1757 if((device
->Flags
&DEVICE_RUNNING
))
1758 return ALC_NO_ERROR
;
1760 UpdateClockBase(device
);
1762 oldFreq
= device
->Frequency
;
1763 oldChans
= device
->FmtChans
;
1764 oldType
= device
->FmtType
;
1766 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1767 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"",
1768 DevFmtChannelsString(device
->FmtChans
),
1769 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"",
1770 DevFmtTypeString(device
->FmtType
),
1771 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"",
1773 device
->UpdateSize
, device
->NumUpdates
);
1775 if(device
->Type
!= Loopback
)
1777 int nohrtf
= !(device
->Flags
&DEVICE_HRTF_REQUEST
);
1778 if(GetConfigValueBool(NULL
, "hrtf", !nohrtf
))
1779 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1781 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1783 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1785 enum DevFmtChannels chans
;
1787 if(FindHrtfFormat(device
, &chans
, &freq
))
1789 device
->Frequency
= freq
;
1790 device
->FmtChans
= chans
;
1791 device
->Flags
|= DEVICE_CHANNELS_REQUEST
|
1792 DEVICE_FREQUENCY_REQUEST
;
1796 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1797 return ALC_INVALID_DEVICE
;
1799 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1801 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1802 DevFmtChannelsString(device
->FmtChans
));
1803 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1805 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1807 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1808 DevFmtTypeString(device
->FmtType
));
1809 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1811 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1813 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1814 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1817 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1818 DevFmtChannelsString(device
->FmtChans
),
1819 DevFmtTypeString(device
->FmtType
), device
->Frequency
,
1820 device
->UpdateSize
, device
->NumUpdates
);
1822 aluInitPanning(device
);
1824 V(device
->Synth
,update
)(device
);
1826 device
->Hrtf
= NULL
;
1827 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1829 device
->Hrtf
= GetHrtf(device
);
1831 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1833 TRACE("HRTF %s\n", device
->Hrtf
?"enabled":"disabled");
1835 if(!device
->Hrtf
&& device
->Bs2bLevel
> 0 && device
->Bs2bLevel
<= 6)
1839 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
1840 bs2b_clear(device
->Bs2b
);
1842 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
1843 bs2b_set_level(device
->Bs2b
, device
->Bs2bLevel
);
1844 TRACE("BS2B level %d\n", device
->Bs2bLevel
);
1849 device
->Bs2b
= NULL
;
1850 TRACE("BS2B disabled\n");
1853 device
->Flags
&= ~DEVICE_WIDE_STEREO
;
1854 if(device
->Type
!= Loopback
&& !device
->Hrtf
&& GetConfigValueBool(NULL
, "wide-stereo", AL_FALSE
))
1855 device
->Flags
|= DEVICE_WIDE_STEREO
;
1857 if(!device
->Hrtf
&& (device
->UpdateSize
&3))
1859 if((CPUCapFlags
&CPU_CAP_SSE
))
1860 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1861 if((CPUCapFlags
&CPU_CAP_NEON
))
1862 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1865 SetMixerFPUMode(&oldMode
);
1866 ALCdevice_Lock(device
);
1867 context
= device
->ContextList
;
1872 context
->UpdateSources
= AL_FALSE
;
1873 LockUIntMapRead(&context
->EffectSlotMap
);
1874 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
1876 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
1878 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1880 UnlockUIntMapRead(&context
->EffectSlotMap
);
1881 ALCdevice_Unlock(device
);
1882 RestoreFPUMode(&oldMode
);
1883 return ALC_INVALID_DEVICE
;
1885 slot
->NeedsUpdate
= AL_FALSE
;
1886 V(slot
->EffectState
,update
)(device
, slot
);
1888 UnlockUIntMapRead(&context
->EffectSlotMap
);
1890 LockUIntMapRead(&context
->SourceMap
);
1891 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1893 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
1894 ALuint s
= device
->NumAuxSends
;
1895 while(s
< MAX_SENDS
)
1897 if(source
->Send
[s
].Slot
)
1898 DecrementRef(&source
->Send
[s
].Slot
->ref
);
1899 source
->Send
[s
].Slot
= NULL
;
1900 source
->Send
[s
].Gain
= 1.0f
;
1901 source
->Send
[s
].GainHF
= 1.0f
;
1904 source
->NeedsUpdate
= AL_TRUE
;
1906 UnlockUIntMapRead(&context
->SourceMap
);
1908 for(pos
= 0;pos
< context
->ActiveSourceCount
;pos
++)
1910 ALactivesource
*src
= context
->ActiveSources
[pos
];
1911 ALsource
*source
= src
->Source
;
1912 ALuint s
= device
->NumAuxSends
;
1913 while(s
< MAX_SENDS
)
1915 src
->Send
[s
].Moving
= AL_FALSE
;
1916 src
->Send
[s
].Counter
= 0;
1920 src
->Update(src
, context
);
1921 source
->NeedsUpdate
= AL_FALSE
;
1924 context
= context
->next
;
1926 if(device
->DefaultSlot
)
1928 ALeffectslot
*slot
= device
->DefaultSlot
;
1930 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1932 ALCdevice_Unlock(device
);
1933 RestoreFPUMode(&oldMode
);
1934 return ALC_INVALID_DEVICE
;
1936 slot
->NeedsUpdate
= AL_FALSE
;
1937 V(slot
->EffectState
,update
)(device
, slot
);
1939 ALCdevice_Unlock(device
);
1940 RestoreFPUMode(&oldMode
);
1942 if(!(device
->Flags
&DEVICE_PAUSED
))
1944 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
1945 return ALC_INVALID_DEVICE
;
1946 device
->Flags
|= DEVICE_RUNNING
;
1949 return ALC_NO_ERROR
;
1954 * Frees the device structure, and destroys any objects the app failed to
1955 * delete. Called once there's no more references on the device.
1957 static ALCvoid
FreeDevice(ALCdevice
*device
)
1959 TRACE("%p\n", device
);
1961 V0(device
->Backend
,close
)();
1962 DELETE_OBJ(device
->Backend
);
1963 device
->Backend
= NULL
;
1965 DELETE_OBJ(device
->Synth
);
1966 device
->Synth
= NULL
;
1968 if(device
->DefaultSlot
)
1970 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
1971 device
->DefaultSlot
= NULL
;
1975 if(device
->DefaultSfont
)
1976 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
1977 device
->DefaultSfont
= NULL
;
1979 if(device
->BufferMap
.size
> 0)
1981 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
1982 ReleaseALBuffers(device
);
1984 ResetUIntMap(&device
->BufferMap
);
1986 if(device
->EffectMap
.size
> 0)
1988 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
1989 ReleaseALEffects(device
);
1991 ResetUIntMap(&device
->EffectMap
);
1993 if(device
->FilterMap
.size
> 0)
1995 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
1996 ReleaseALFilters(device
);
1998 ResetUIntMap(&device
->FilterMap
);
2000 if(device
->SfontMap
.size
> 0)
2002 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2003 ReleaseALSoundfonts(device
);
2005 ResetUIntMap(&device
->SfontMap
);
2007 if(device
->PresetMap
.size
> 0)
2009 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2010 ReleaseALPresets(device
);
2012 ResetUIntMap(&device
->PresetMap
);
2014 if(device
->FontsoundMap
.size
> 0)
2016 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2017 ReleaseALFontsounds(device
);
2019 ResetUIntMap(&device
->FontsoundMap
);
2022 device
->Bs2b
= NULL
;
2024 AL_STRING_DEINIT(device
->DeviceName
);
2030 void ALCdevice_IncRef(ALCdevice
*device
)
2033 ref
= IncrementRef(&device
->ref
);
2034 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2037 void ALCdevice_DecRef(ALCdevice
*device
)
2040 ref
= DecrementRef(&device
->ref
);
2041 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2042 if(ref
== 0) FreeDevice(device
);
2047 * Checks if the device handle is valid, and increments its ref count if so.
2049 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2051 ALCdevice
*tmpDevice
;
2057 tmpDevice
= DeviceList
;
2058 while(tmpDevice
&& tmpDevice
!= device
)
2059 tmpDevice
= tmpDevice
->next
;
2062 ALCdevice_IncRef(tmpDevice
);
2070 * Initializes context fields
2072 static ALvoid
InitContext(ALCcontext
*Context
)
2076 //Initialise listener
2077 Context
->Listener
->Gain
= 1.0f
;
2078 Context
->Listener
->MetersPerUnit
= 1.0f
;
2079 Context
->Listener
->Position
[0] = 0.0f
;
2080 Context
->Listener
->Position
[1] = 0.0f
;
2081 Context
->Listener
->Position
[2] = 0.0f
;
2082 Context
->Listener
->Velocity
[0] = 0.0f
;
2083 Context
->Listener
->Velocity
[1] = 0.0f
;
2084 Context
->Listener
->Velocity
[2] = 0.0f
;
2085 Context
->Listener
->Forward
[0] = 0.0f
;
2086 Context
->Listener
->Forward
[1] = 0.0f
;
2087 Context
->Listener
->Forward
[2] = -1.0f
;
2088 Context
->Listener
->Up
[0] = 0.0f
;
2089 Context
->Listener
->Up
[1] = 1.0f
;
2090 Context
->Listener
->Up
[2] = 0.0f
;
2091 for(i
= 0;i
< 4;i
++)
2093 for(j
= 0;j
< 4;j
++)
2094 Context
->Listener
->Params
.Matrix
[i
][j
] = ((i
==j
) ? 1.0f
: 0.0f
);
2096 for(i
= 0;i
< 3;i
++)
2097 Context
->Listener
->Params
.Velocity
[i
] = 0.0f
;
2100 Context
->LastError
= AL_NO_ERROR
;
2101 Context
->UpdateSources
= AL_FALSE
;
2102 Context
->ActiveSourceCount
= 0;
2103 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2104 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2107 Context
->DistanceModel
= DefaultDistanceModel
;
2108 Context
->SourceDistanceModel
= AL_FALSE
;
2109 Context
->DopplerFactor
= 1.0f
;
2110 Context
->DopplerVelocity
= 1.0f
;
2111 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2112 Context
->DeferUpdates
= AL_FALSE
;
2114 Context
->ExtensionList
= alExtList
;
2120 * Cleans up the context, and destroys any remaining objects the app failed to
2121 * delete. Called once there's no more references on the context.
2123 static ALCvoid
FreeContext(ALCcontext
*context
)
2127 TRACE("%p\n", context
);
2129 if(context
->SourceMap
.size
> 0)
2131 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2132 ReleaseALSources(context
);
2134 ResetUIntMap(&context
->SourceMap
);
2136 if(context
->EffectSlotMap
.size
> 0)
2138 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2139 ReleaseALAuxiliaryEffectSlots(context
);
2141 ResetUIntMap(&context
->EffectSlotMap
);
2143 for(i
= 0;i
< context
->MaxActiveSources
;i
++)
2145 al_free(context
->ActiveSources
[i
]);
2146 context
->ActiveSources
[i
] = NULL
;
2148 free(context
->ActiveSources
);
2149 context
->ActiveSources
= NULL
;
2150 context
->ActiveSourceCount
= 0;
2151 context
->MaxActiveSources
= 0;
2153 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2155 ALCdevice_DecRef(context
->Device
);
2156 context
->Device
= NULL
;
2158 //Invalidate context
2159 memset(context
, 0, sizeof(ALCcontext
));
2165 * Removes the context reference from the given device and removes it from
2166 * being current on the running thread or globally.
2168 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2170 ALCcontext
*volatile*tmp_ctx
;
2172 if(altss_get(LocalContext
) == context
)
2174 WARN("%p released while current on thread\n", context
);
2175 altss_set(LocalContext
, NULL
);
2176 ALCcontext_DecRef(context
);
2179 if(CompExchangePtr((XchgPtr
*)&GlobalContext
, context
, NULL
) == context
)
2180 ALCcontext_DecRef(context
);
2182 ALCdevice_Lock(device
);
2183 tmp_ctx
= &device
->ContextList
;
2186 if(CompExchangePtr((XchgPtr
*)tmp_ctx
, context
, context
->next
) == context
)
2188 tmp_ctx
= &(*tmp_ctx
)->next
;
2190 ALCdevice_Unlock(device
);
2192 ALCcontext_DecRef(context
);
2195 void ALCcontext_IncRef(ALCcontext
*context
)
2198 ref
= IncrementRef(&context
->ref
);
2199 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2202 void ALCcontext_DecRef(ALCcontext
*context
)
2205 ref
= DecrementRef(&context
->ref
);
2206 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2207 if(ref
== 0) FreeContext(context
);
2210 static void ReleaseThreadCtx(void *ptr
)
2212 WARN("%p current for thread being destroyed\n", ptr
);
2213 ALCcontext_DecRef(ptr
);
2218 * Checks that the given context is valid, and increments its reference count.
2220 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2228 ALCcontext
*tmp_ctx
= dev
->ContextList
;
2231 if(tmp_ctx
== context
)
2233 ALCcontext_IncRef(tmp_ctx
);
2237 tmp_ctx
= tmp_ctx
->next
;
2249 * Returns the currently active context for this thread, and adds a reference
2250 * without locking it.
2252 ALCcontext
*GetContextRef(void)
2254 ALCcontext
*context
;
2256 context
= altss_get(LocalContext
);
2258 ALCcontext_IncRef(context
);
2262 context
= GlobalContext
;
2264 ALCcontext_IncRef(context
);
2272 /************************************************
2273 * Standard ALC functions
2274 ************************************************/
2278 * Return last ALC generated error code for the given device
2280 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2284 if(VerifyDevice(device
))
2286 errorCode
= ExchangeInt(&device
->LastError
, ALC_NO_ERROR
);
2287 ALCdevice_DecRef(device
);
2290 errorCode
= ExchangeInt(&LastNullDeviceError
, ALC_NO_ERROR
);
2296 /* alcSuspendContext
2300 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*UNUSED(context
))
2304 /* alcProcessContext
2308 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*UNUSED(context
))
2315 * Returns information about the device, and error strings
2317 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2319 const ALCchar
*value
= NULL
;
2327 case ALC_INVALID_ENUM
:
2328 value
= alcErrInvalidEnum
;
2331 case ALC_INVALID_VALUE
:
2332 value
= alcErrInvalidValue
;
2335 case ALC_INVALID_DEVICE
:
2336 value
= alcErrInvalidDevice
;
2339 case ALC_INVALID_CONTEXT
:
2340 value
= alcErrInvalidContext
;
2343 case ALC_OUT_OF_MEMORY
:
2344 value
= alcErrOutOfMemory
;
2347 case ALC_DEVICE_SPECIFIER
:
2348 value
= alcDefaultName
;
2351 case ALC_ALL_DEVICES_SPECIFIER
:
2352 if(VerifyDevice(Device
))
2354 value
= al_string_get_cstr(Device
->DeviceName
);
2355 ALCdevice_DecRef(Device
);
2359 ProbeAllDevicesList();
2360 value
= al_string_get_cstr(alcAllDevicesList
);
2364 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2365 if(VerifyDevice(Device
))
2367 value
= al_string_get_cstr(Device
->DeviceName
);
2368 ALCdevice_DecRef(Device
);
2372 ProbeCaptureDeviceList();
2373 value
= al_string_get_cstr(alcCaptureDeviceList
);
2377 /* Default devices are always first in the list */
2378 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2379 value
= alcDefaultName
;
2382 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2383 if(al_string_empty(alcAllDevicesList
))
2384 ProbeAllDevicesList();
2386 Device
= VerifyDevice(Device
);
2388 free(alcDefaultAllDevicesSpecifier
);
2389 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2390 if(!alcDefaultAllDevicesSpecifier
)
2391 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2393 value
= alcDefaultAllDevicesSpecifier
;
2394 if(Device
) ALCdevice_DecRef(Device
);
2397 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2398 if(al_string_empty(alcCaptureDeviceList
))
2399 ProbeCaptureDeviceList();
2401 Device
= VerifyDevice(Device
);
2403 free(alcCaptureDefaultDeviceSpecifier
);
2404 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2405 if(!alcCaptureDefaultDeviceSpecifier
)
2406 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2408 value
= alcCaptureDefaultDeviceSpecifier
;
2409 if(Device
) ALCdevice_DecRef(Device
);
2412 case ALC_EXTENSIONS
:
2413 if(!VerifyDevice(Device
))
2414 value
= alcNoDeviceExtList
;
2417 value
= alcExtensionList
;
2418 ALCdevice_DecRef(Device
);
2423 Device
= VerifyDevice(Device
);
2424 alcSetError(Device
, ALC_INVALID_ENUM
);
2425 if(Device
) ALCdevice_DecRef(Device
);
2433 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2437 if(size
<= 0 || values
== NULL
)
2439 alcSetError(device
, ALC_INVALID_VALUE
);
2447 case ALC_MAJOR_VERSION
:
2448 values
[0] = alcMajorVersion
;
2450 case ALC_MINOR_VERSION
:
2451 values
[0] = alcMinorVersion
;
2454 case ALC_ATTRIBUTES_SIZE
:
2455 case ALC_ALL_ATTRIBUTES
:
2459 case ALC_MONO_SOURCES
:
2460 case ALC_STEREO_SOURCES
:
2461 case ALC_CAPTURE_SAMPLES
:
2462 case ALC_FORMAT_CHANNELS_SOFT
:
2463 case ALC_FORMAT_TYPE_SOFT
:
2464 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2468 alcSetError(NULL
, ALC_INVALID_ENUM
);
2474 if(device
->Type
== Capture
)
2478 case ALC_CAPTURE_SAMPLES
:
2479 ALCdevice_Lock(device
);
2480 values
[0] = V0(device
->Backend
,availableSamples
)();
2481 ALCdevice_Unlock(device
);
2485 values
[0] = device
->Connected
;
2489 alcSetError(device
, ALC_INVALID_ENUM
);
2498 case ALC_MAJOR_VERSION
:
2499 values
[0] = alcMajorVersion
;
2502 case ALC_MINOR_VERSION
:
2503 values
[0] = alcMinorVersion
;
2506 case ALC_EFX_MAJOR_VERSION
:
2507 values
[0] = alcEFXMajorVersion
;
2510 case ALC_EFX_MINOR_VERSION
:
2511 values
[0] = alcEFXMinorVersion
;
2514 case ALC_ATTRIBUTES_SIZE
:
2518 case ALC_ALL_ATTRIBUTES
:
2521 alcSetError(device
, ALC_INVALID_VALUE
);
2526 values
[i
++] = ALC_FREQUENCY
;
2527 values
[i
++] = device
->Frequency
;
2529 if(device
->Type
!= Loopback
)
2531 values
[i
++] = ALC_REFRESH
;
2532 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2534 values
[i
++] = ALC_SYNC
;
2535 values
[i
++] = ALC_FALSE
;
2539 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2540 values
[i
++] = device
->FmtChans
;
2542 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2543 values
[i
++] = device
->FmtType
;
2546 values
[i
++] = ALC_MONO_SOURCES
;
2547 values
[i
++] = device
->NumMonoSources
;
2549 values
[i
++] = ALC_STEREO_SOURCES
;
2550 values
[i
++] = device
->NumStereoSources
;
2552 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2553 values
[i
++] = device
->NumAuxSends
;
2555 values
[i
++] = ALC_HRTF_SOFT
;
2556 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2562 values
[0] = device
->Frequency
;
2566 if(device
->Type
== Loopback
)
2568 alcSetError(device
, ALC_INVALID_DEVICE
);
2571 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2575 if(device
->Type
== Loopback
)
2577 alcSetError(device
, ALC_INVALID_DEVICE
);
2580 values
[0] = ALC_FALSE
;
2583 case ALC_FORMAT_CHANNELS_SOFT
:
2584 if(device
->Type
!= Loopback
)
2586 alcSetError(device
, ALC_INVALID_DEVICE
);
2589 values
[0] = device
->FmtChans
;
2592 case ALC_FORMAT_TYPE_SOFT
:
2593 if(device
->Type
!= Loopback
)
2595 alcSetError(device
, ALC_INVALID_DEVICE
);
2598 values
[0] = device
->FmtType
;
2601 case ALC_MONO_SOURCES
:
2602 values
[0] = device
->NumMonoSources
;
2605 case ALC_STEREO_SOURCES
:
2606 values
[0] = device
->NumStereoSources
;
2609 case ALC_MAX_AUXILIARY_SENDS
:
2610 values
[0] = device
->NumAuxSends
;
2614 values
[0] = device
->Connected
;
2618 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2622 alcSetError(device
, ALC_INVALID_ENUM
);
2630 * Returns information about the device and the version of OpenAL
2632 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2634 device
= VerifyDevice(device
);
2635 if(size
<= 0 || values
== NULL
)
2636 alcSetError(device
, ALC_INVALID_VALUE
);
2638 GetIntegerv(device
, param
, size
, values
);
2639 if(device
) ALCdevice_DecRef(device
);
2642 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2647 device
= VerifyDevice(device
);
2648 if(size
<= 0 || values
== NULL
)
2649 alcSetError(device
, ALC_INVALID_VALUE
);
2650 else if(!device
|| device
->Type
== Capture
)
2652 ivals
= malloc(size
* sizeof(ALCint
));
2653 size
= GetIntegerv(device
, pname
, size
, ivals
);
2654 for(i
= 0;i
< size
;i
++)
2655 values
[i
] = ivals
[i
];
2658 else /* render device */
2662 case ALC_ATTRIBUTES_SIZE
:
2666 case ALC_ALL_ATTRIBUTES
:
2668 alcSetError(device
, ALC_INVALID_VALUE
);
2673 V0(device
->Backend
,lock
)();
2674 values
[i
++] = ALC_FREQUENCY
;
2675 values
[i
++] = device
->Frequency
;
2677 if(device
->Type
!= Loopback
)
2679 values
[i
++] = ALC_REFRESH
;
2680 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2682 values
[i
++] = ALC_SYNC
;
2683 values
[i
++] = ALC_FALSE
;
2687 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2688 values
[i
++] = device
->FmtChans
;
2690 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2691 values
[i
++] = device
->FmtType
;
2694 values
[i
++] = ALC_MONO_SOURCES
;
2695 values
[i
++] = device
->NumMonoSources
;
2697 values
[i
++] = ALC_STEREO_SOURCES
;
2698 values
[i
++] = device
->NumStereoSources
;
2700 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2701 values
[i
++] = device
->NumAuxSends
;
2703 values
[i
++] = ALC_HRTF_SOFT
;
2704 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2706 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2707 values
[i
++] = device
->ClockBase
+
2708 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2711 V0(device
->Backend
,unlock
)();
2715 case ALC_DEVICE_CLOCK_SOFT
:
2716 V0(device
->Backend
,lock
)();
2717 *values
= device
->ClockBase
+
2718 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2719 V0(device
->Backend
,unlock
)();
2723 ivals
= malloc(size
* sizeof(ALCint
));
2724 size
= GetIntegerv(device
, pname
, size
, ivals
);
2725 for(i
= 0;i
< size
;i
++)
2726 values
[i
] = ivals
[i
];
2732 ALCdevice_DecRef(device
);
2736 /* alcIsExtensionPresent
2738 * Determines if there is support for a particular extension
2740 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2742 ALCboolean bResult
= ALC_FALSE
;
2744 device
= VerifyDevice(device
);
2747 alcSetError(device
, ALC_INVALID_VALUE
);
2750 size_t len
= strlen(extName
);
2751 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2754 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2755 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2760 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2764 } while(isspace(*ptr
));
2769 ALCdevice_DecRef(device
);
2774 /* alcGetProcAddress
2776 * Retrieves the function address for a particular extension function
2778 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2780 ALCvoid
*ptr
= NULL
;
2784 device
= VerifyDevice(device
);
2785 alcSetError(device
, ALC_INVALID_VALUE
);
2786 if(device
) ALCdevice_DecRef(device
);
2791 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2793 ptr
= alcFunctions
[i
].address
;
2802 * Get the value for a particular ALC enumeration name
2804 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
2810 device
= VerifyDevice(device
);
2811 alcSetError(device
, ALC_INVALID_VALUE
);
2812 if(device
) ALCdevice_DecRef(device
);
2817 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
2819 val
= enumeration
[i
].value
;
2828 * Create and attach a context to the given device.
2830 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
2832 ALCcontext
*ALContext
;
2836 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
2839 alcSetError(device
, ALC_INVALID_DEVICE
);
2840 if(device
) ALCdevice_DecRef(device
);
2844 device
->LastError
= ALC_NO_ERROR
;
2846 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
2849 alcSetError(device
, err
);
2850 if(err
== ALC_INVALID_DEVICE
)
2852 ALCdevice_Lock(device
);
2853 aluHandleDisconnect(device
);
2854 ALCdevice_Unlock(device
);
2856 ALCdevice_DecRef(device
);
2860 ALContext
= calloc(1, sizeof(ALCcontext
)+sizeof(ALlistener
));
2863 InitRef(&ALContext
->ref
, 1);
2864 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
2866 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
2868 ALContext
->MaxActiveSources
= 256;
2869 ALContext
->ActiveSources
= calloc(ALContext
->MaxActiveSources
,
2870 sizeof(ALContext
->ActiveSources
[0]));
2872 if(!ALContext
|| !ALContext
->ActiveSources
)
2874 if(!device
->ContextList
)
2876 V0(device
->Backend
,stop
)();
2877 device
->Flags
&= ~DEVICE_RUNNING
;
2883 free(ALContext
->ActiveSources
);
2884 ALContext
->ActiveSources
= NULL
;
2886 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
2892 alcSetError(device
, ALC_OUT_OF_MEMORY
);
2893 ALCdevice_DecRef(device
);
2897 ALContext
->Device
= device
;
2898 ALCdevice_IncRef(device
);
2899 InitContext(ALContext
);
2902 ALContext
->next
= device
->ContextList
;
2903 } while(CompExchangePtr((XchgPtr
*)&device
->ContextList
, ALContext
->next
, ALContext
) != ALContext
->next
);
2906 ALCdevice_DecRef(device
);
2908 TRACE("Created context %p\n", ALContext
);
2912 /* alcDestroyContext
2914 * Remove a context from its device
2916 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
2921 /* alcGetContextsDevice sets an error for invalid contexts */
2922 Device
= alcGetContextsDevice(context
);
2925 ReleaseContext(context
, Device
);
2926 if(!Device
->ContextList
)
2928 V0(Device
->Backend
,stop
)();
2929 Device
->Flags
&= ~DEVICE_RUNNING
;
2936 /* alcGetCurrentContext
2938 * Returns the currently active context on the calling thread
2940 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
2942 ALCcontext
*Context
;
2944 Context
= altss_get(LocalContext
);
2945 if(!Context
) Context
= GlobalContext
;
2950 /* alcGetThreadContext
2952 * Returns the currently active thread-local context
2954 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
2956 ALCcontext
*Context
;
2957 Context
= altss_get(LocalContext
);
2962 /* alcMakeContextCurrent
2964 * Makes the given context the active process-wide context, and removes the
2965 * thread-local context for the calling thread.
2967 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
2969 /* context must be valid or NULL */
2970 if(context
&& !(context
=VerifyContext(context
)))
2972 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2975 /* context's reference count is already incremented */
2976 context
= ExchangePtr((XchgPtr
*)&GlobalContext
, context
);
2977 if(context
) ALCcontext_DecRef(context
);
2979 if((context
=altss_get(LocalContext
)) != NULL
)
2981 altss_set(LocalContext
, NULL
);
2982 ALCcontext_DecRef(context
);
2988 /* alcSetThreadContext
2990 * Makes the given context the active context for the current thread
2992 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
2996 /* context must be valid or NULL */
2997 if(context
&& !(context
=VerifyContext(context
)))
2999 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3002 /* context's reference count is already incremented */
3003 old
= altss_get(LocalContext
);
3004 altss_set(LocalContext
, context
);
3005 if(old
) ALCcontext_DecRef(old
);
3011 /* alcGetContextsDevice
3013 * Returns the device that a particular context is attached to
3015 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3019 if(!(Context
=VerifyContext(Context
)))
3021 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3024 Device
= Context
->Device
;
3025 ALCcontext_DecRef(Context
);
3033 * Opens the named device.
3035 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3043 if(!PlaybackBackend
.name
)
3045 alcSetError(NULL
, ALC_INVALID_VALUE
);
3049 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3052 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3055 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3060 InitRef(&device
->ref
, 1);
3061 device
->Connected
= ALC_TRUE
;
3062 device
->Type
= Playback
;
3063 device
->LastError
= ALC_NO_ERROR
;
3066 device
->Bs2b
= NULL
;
3067 device
->Bs2bLevel
= 0;
3068 AL_STRING_INIT(device
->DeviceName
);
3070 device
->ContextList
= NULL
;
3072 device
->ClockBase
= 0;
3073 device
->SamplesDone
= 0;
3075 device
->MaxNoOfSources
= 256;
3076 device
->AuxiliaryEffectSlotMax
= 4;
3077 device
->NumAuxSends
= MAX_SENDS
;
3079 InitUIntMap(&device
->BufferMap
, ~0);
3080 InitUIntMap(&device
->EffectMap
, ~0);
3081 InitUIntMap(&device
->FilterMap
, ~0);
3082 InitUIntMap(&device
->SfontMap
, ~0);
3083 InitUIntMap(&device
->PresetMap
, ~0);
3084 InitUIntMap(&device
->FontsoundMap
, ~0);
3087 device
->FmtChans
= DevFmtChannelsDefault
;
3088 device
->FmtType
= DevFmtTypeDefault
;
3089 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3090 device
->NumUpdates
= 4;
3091 device
->UpdateSize
= 1024;
3093 if(!PlaybackBackend
.getFactory
)
3094 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3095 ALCbackend_Playback
);
3098 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3099 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3101 if(!device
->Backend
)
3104 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3109 if(ConfigValueStr(NULL
, "channels", &fmt
))
3111 static const struct {
3112 const char name
[16];
3113 enum DevFmtChannels chans
;
3115 { "mono", DevFmtMono
},
3116 { "stereo", DevFmtStereo
},
3117 { "quad", DevFmtQuad
},
3118 { "surround51", DevFmtX51
},
3119 { "surround61", DevFmtX61
},
3120 { "surround71", DevFmtX71
},
3124 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3126 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3128 device
->FmtChans
= chanlist
[i
].chans
;
3129 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3133 if(i
== COUNTOF(chanlist
))
3134 ERR("Unsupported channels: %s\n", fmt
);
3136 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3138 static const struct {
3139 const char name
[16];
3140 enum DevFmtType type
;
3142 { "int8", DevFmtByte
},
3143 { "uint8", DevFmtUByte
},
3144 { "int16", DevFmtShort
},
3145 { "uint16", DevFmtUShort
},
3146 { "int32", DevFmtInt
},
3147 { "uint32", DevFmtUInt
},
3148 { "float32", DevFmtFloat
},
3152 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3154 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3156 device
->FmtType
= typelist
[i
].type
;
3157 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3161 if(i
== COUNTOF(typelist
))
3162 ERR("Unsupported sample-type: %s\n", fmt
);
3164 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3165 if((device
->Flags
&DEVICE_FORMAT_REQUEST
) != DEVICE_FORMAT_REQUEST
&&
3166 ConfigValueStr(NULL
, "format", &fmt
))
3168 static const struct {
3169 const char name
[32];
3170 enum DevFmtChannels channels
;
3171 enum DevFmtType type
;
3173 { "AL_FORMAT_MONO32", DevFmtMono
, DevFmtFloat
},
3174 { "AL_FORMAT_STEREO32", DevFmtStereo
, DevFmtFloat
},
3175 { "AL_FORMAT_QUAD32", DevFmtQuad
, DevFmtFloat
},
3176 { "AL_FORMAT_51CHN32", DevFmtX51
, DevFmtFloat
},
3177 { "AL_FORMAT_61CHN32", DevFmtX61
, DevFmtFloat
},
3178 { "AL_FORMAT_71CHN32", DevFmtX71
, DevFmtFloat
},
3180 { "AL_FORMAT_MONO16", DevFmtMono
, DevFmtShort
},
3181 { "AL_FORMAT_STEREO16", DevFmtStereo
, DevFmtShort
},
3182 { "AL_FORMAT_QUAD16", DevFmtQuad
, DevFmtShort
},
3183 { "AL_FORMAT_51CHN16", DevFmtX51
, DevFmtShort
},
3184 { "AL_FORMAT_61CHN16", DevFmtX61
, DevFmtShort
},
3185 { "AL_FORMAT_71CHN16", DevFmtX71
, DevFmtShort
},
3187 { "AL_FORMAT_MONO8", DevFmtMono
, DevFmtByte
},
3188 { "AL_FORMAT_STEREO8", DevFmtStereo
, DevFmtByte
},
3189 { "AL_FORMAT_QUAD8", DevFmtQuad
, DevFmtByte
},
3190 { "AL_FORMAT_51CHN8", DevFmtX51
, DevFmtByte
},
3191 { "AL_FORMAT_61CHN8", DevFmtX61
, DevFmtByte
},
3192 { "AL_FORMAT_71CHN8", DevFmtX71
, DevFmtByte
}
3196 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3197 for(i
= 0;i
< COUNTOF(formats
);i
++)
3199 if(strcasecmp(fmt
, formats
[i
].name
) == 0)
3201 if(!(device
->Flags
&DEVICE_CHANNELS_REQUEST
))
3202 device
->FmtChans
= formats
[i
].channels
;
3203 if(!(device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
3204 device
->FmtType
= formats
[i
].type
;
3205 device
->Flags
|= DEVICE_FORMAT_REQUEST
;
3209 if(i
== COUNTOF(formats
))
3210 ERR("Unsupported format: %s\n", fmt
);
3212 #undef DEVICE_FORMAT_REQUEST
3214 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3216 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3217 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3218 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3219 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3222 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3223 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3225 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3226 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3227 if((CPUCapFlags
&CPU_CAP_SSE
))
3228 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3230 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3231 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3233 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3234 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3236 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3237 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3239 ConfigValueInt(NULL
, "cf_level", &device
->Bs2bLevel
);
3241 device
->NumStereoSources
= 1;
3242 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3244 device
->Synth
= SynthCreate(device
);
3247 DELETE_OBJ(device
->Backend
);
3249 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3253 // Find a playback device to open
3254 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3256 DELETE_OBJ(device
->Synth
);
3257 DELETE_OBJ(device
->Backend
);
3259 alcSetError(NULL
, err
);
3263 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3265 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3266 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3268 device
->DefaultSlot
= NULL
;
3269 ERR("Failed to initialize the default effect slot\n");
3271 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3273 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3274 device
->DefaultSlot
= NULL
;
3276 ERR("Failed to initialize the default effect\n");
3281 device
->next
= DeviceList
;
3282 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3284 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3290 * Closes the given device.
3292 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*Device
)
3294 ALCdevice
*volatile*list
;
3299 while(*list
&& *list
!= Device
)
3300 list
= &(*list
)->next
;
3302 if(!*list
|| (*list
)->Type
== Capture
)
3304 alcSetError(*list
, ALC_INVALID_DEVICE
);
3309 *list
= (*list
)->next
;
3312 while((ctx
=Device
->ContextList
) != NULL
)
3314 WARN("Releasing context %p\n", ctx
);
3315 ReleaseContext(ctx
, Device
);
3317 if((Device
->Flags
&DEVICE_RUNNING
))
3318 V0(Device
->Backend
,stop
)();
3319 Device
->Flags
&= ~DEVICE_RUNNING
;
3321 ALCdevice_DecRef(Device
);
3327 /************************************************
3328 * ALC capture functions
3329 ************************************************/
3330 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3332 ALCdevice
*device
= NULL
;
3337 if(!CaptureBackend
.name
)
3339 alcSetError(NULL
, ALC_INVALID_VALUE
);
3345 alcSetError(NULL
, ALC_INVALID_VALUE
);
3349 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3352 device
= al_calloc(16, sizeof(ALCdevice
));
3355 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3360 InitRef(&device
->ref
, 1);
3361 device
->Connected
= ALC_TRUE
;
3362 device
->Type
= Capture
;
3364 AL_STRING_INIT(device
->DeviceName
);
3366 InitUIntMap(&device
->BufferMap
, ~0);
3367 InitUIntMap(&device
->EffectMap
, ~0);
3368 InitUIntMap(&device
->FilterMap
, ~0);
3369 InitUIntMap(&device
->SfontMap
, ~0);
3370 InitUIntMap(&device
->PresetMap
, ~0);
3371 InitUIntMap(&device
->FontsoundMap
, ~0);
3373 if(!CaptureBackend
.getFactory
)
3374 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3375 ALCbackend_Capture
);
3378 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3379 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3381 if(!device
->Backend
)
3384 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3388 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3389 device
->Frequency
= frequency
;
3391 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3392 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3395 alcSetError(NULL
, ALC_INVALID_ENUM
);
3399 device
->UpdateSize
= samples
;
3400 device
->NumUpdates
= 1;
3402 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3405 alcSetError(NULL
, err
);
3410 device
->next
= DeviceList
;
3411 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3413 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3417 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*Device
)
3419 ALCdevice
*volatile*list
;
3423 while(*list
&& *list
!= Device
)
3424 list
= &(*list
)->next
;
3426 if(!*list
|| (*list
)->Type
!= Capture
)
3428 alcSetError(*list
, ALC_INVALID_DEVICE
);
3433 *list
= (*list
)->next
;
3436 ALCdevice_DecRef(Device
);
3441 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3443 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3444 alcSetError(device
, ALC_INVALID_DEVICE
);
3447 ALCdevice_Lock(device
);
3448 if(device
->Connected
)
3450 if(!(device
->Flags
&DEVICE_RUNNING
))
3451 V0(device
->Backend
,start
)();
3452 device
->Flags
|= DEVICE_RUNNING
;
3454 ALCdevice_Unlock(device
);
3457 if(device
) ALCdevice_DecRef(device
);
3460 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3462 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3463 alcSetError(device
, ALC_INVALID_DEVICE
);
3466 ALCdevice_Lock(device
);
3467 if((device
->Flags
&DEVICE_RUNNING
))
3468 V0(device
->Backend
,stop
)();
3469 device
->Flags
&= ~DEVICE_RUNNING
;
3470 ALCdevice_Unlock(device
);
3473 if(device
) ALCdevice_DecRef(device
);
3476 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3478 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3479 alcSetError(device
, ALC_INVALID_DEVICE
);
3482 ALCenum err
= ALC_INVALID_VALUE
;
3484 ALCdevice_Lock(device
);
3485 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3486 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3487 ALCdevice_Unlock(device
);
3489 if(err
!= ALC_NO_ERROR
)
3490 alcSetError(device
, err
);
3492 if(device
) ALCdevice_DecRef(device
);
3496 /************************************************
3497 * ALC loopback functions
3498 ************************************************/
3500 /* alcLoopbackOpenDeviceSOFT
3502 * Open a loopback device, for manual rendering.
3504 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3506 ALCbackendFactory
*factory
;
3511 /* Make sure the device name, if specified, is us. */
3512 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3514 alcSetError(NULL
, ALC_INVALID_VALUE
);
3518 device
= al_calloc(16, sizeof(ALCdevice
));
3521 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3526 InitRef(&device
->ref
, 1);
3527 device
->Connected
= ALC_TRUE
;
3528 device
->Type
= Loopback
;
3529 device
->LastError
= ALC_NO_ERROR
;
3532 device
->Bs2b
= NULL
;
3533 device
->Bs2bLevel
= 0;
3534 AL_STRING_INIT(device
->DeviceName
);
3536 device
->ContextList
= NULL
;
3538 device
->ClockBase
= 0;
3539 device
->SamplesDone
= 0;
3541 device
->MaxNoOfSources
= 256;
3542 device
->AuxiliaryEffectSlotMax
= 4;
3543 device
->NumAuxSends
= MAX_SENDS
;
3545 InitUIntMap(&device
->BufferMap
, ~0);
3546 InitUIntMap(&device
->EffectMap
, ~0);
3547 InitUIntMap(&device
->FilterMap
, ~0);
3548 InitUIntMap(&device
->SfontMap
, ~0);
3549 InitUIntMap(&device
->PresetMap
, ~0);
3550 InitUIntMap(&device
->FontsoundMap
, ~0);
3552 factory
= ALCloopbackFactory_getFactory();
3553 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3554 if(!device
->Backend
)
3557 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3562 device
->NumUpdates
= 0;
3563 device
->UpdateSize
= 0;
3565 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3566 device
->FmtChans
= DevFmtChannelsDefault
;
3567 device
->FmtType
= DevFmtTypeDefault
;
3569 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3570 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3572 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3573 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3575 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3576 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3578 device
->NumStereoSources
= 1;
3579 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3581 device
->Synth
= SynthCreate(device
);
3584 DELETE_OBJ(device
->Backend
);
3586 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3590 // Open the "backend"
3591 V(device
->Backend
,open
)("Loopback");
3593 device
->next
= DeviceList
;
3594 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3596 TRACE("Created device %p\n", device
);
3600 /* alcIsRenderFormatSupportedSOFT
3602 * Determines if the loopback device supports the given format for rendering.
3604 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3606 ALCboolean ret
= ALC_FALSE
;
3608 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3609 alcSetError(device
, ALC_INVALID_DEVICE
);
3611 alcSetError(device
, ALC_INVALID_VALUE
);
3614 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3615 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3616 freq
>= MIN_OUTPUT_RATE
)
3619 if(device
) ALCdevice_DecRef(device
);
3624 /* alcRenderSamplesSOFT
3626 * Renders some samples into a buffer, using the format last set by the
3627 * attributes given to alcCreateContext.
3629 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3631 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3632 alcSetError(device
, ALC_INVALID_DEVICE
);
3633 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3634 alcSetError(device
, ALC_INVALID_VALUE
);
3636 aluMixData(device
, buffer
, samples
);
3637 if(device
) ALCdevice_DecRef(device
);
3641 /************************************************
3642 * ALC DSP pause/resume functions
3643 ************************************************/
3645 /* alcDevicePauseSOFT
3647 * Pause the DSP to stop audio processing.
3649 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3651 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3652 alcSetError(device
, ALC_INVALID_DEVICE
);
3656 if((device
->Flags
&DEVICE_RUNNING
))
3657 V0(device
->Backend
,stop
)();
3658 device
->Flags
&= ~DEVICE_RUNNING
;
3659 device
->Flags
|= DEVICE_PAUSED
;
3662 if(device
) ALCdevice_DecRef(device
);
3665 /* alcDeviceResumeSOFT
3667 * Resume the DSP to restart audio processing.
3669 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3671 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3672 alcSetError(device
, ALC_INVALID_DEVICE
);
3676 if((device
->Flags
&DEVICE_PAUSED
))
3678 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3680 device
->Flags
|= DEVICE_RUNNING
;
3681 device
->Flags
&= ~DEVICE_PAUSED
;
3685 alcSetError(device
, ALC_INVALID_DEVICE
);
3686 ALCdevice_Lock(device
);
3687 aluHandleDisconnect(device
);
3688 ALCdevice_Unlock(device
);
3693 if(device
) ALCdevice_DecRef(device
);