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
);
912 #if defined(HAVE_SSE4_1)
913 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE4_1
;
914 #elif defined(HAVE_SSE2)
915 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
916 #elif defined(HAVE_SSE)
917 capfilter
|= CPU_CAP_SSE
;
920 capfilter
|= CPU_CAP_NEON
;
922 if(ConfigValueStr(NULL
, "disable-cpu-exts", &str
))
924 if(strcasecmp(str
, "all") == 0)
929 const char *next
= str
;
933 while(isspace(str
[0]))
935 next
= strchr(str
, ',');
937 if(!str
[0] || str
[0] == ',')
940 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
941 while(len
> 0 && isspace(str
[len
-1]))
943 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
944 capfilter
&= ~CPU_CAP_SSE
;
945 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
946 capfilter
&= ~CPU_CAP_SSE2
;
947 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
948 capfilter
&= ~CPU_CAP_SSE4_1
;
949 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
950 capfilter
&= ~CPU_CAP_NEON
;
952 WARN("Invalid CPU extension \"%s\"\n", str
);
956 FillCPUCaps(capfilter
);
963 ConfigValueInt(NULL
, "rt-prio", &RTPrioLevel
);
965 if(ConfigValueStr(NULL
, "resampler", &str
))
967 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
968 DefaultResampler
= PointResampler
;
969 else if(strcasecmp(str
, "linear") == 0)
970 DefaultResampler
= LinearResampler
;
971 else if(strcasecmp(str
, "cubic") == 0)
972 DefaultResampler
= CubicResampler
;
977 n
= strtol(str
, &end
, 0);
978 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== CubicResampler
))
979 DefaultResampler
= n
;
981 WARN("Invalid resampler: %s\n", str
);
985 str
= getenv("ALSOFT_TRAP_ERROR");
986 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
988 TrapALError
= AL_TRUE
;
989 TrapALCError
= AL_TRUE
;
993 str
= getenv("ALSOFT_TRAP_AL_ERROR");
994 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
995 TrapALError
= AL_TRUE
;
996 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
998 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
999 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1000 TrapALCError
= ALC_TRUE
;
1001 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
1004 if(ConfigValueFloat("reverb", "boost", &valf
))
1005 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1007 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
1009 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1010 ConfigValueStr(NULL
, "drivers", &devs
))
1014 const char *next
= devs
;
1015 int endlist
, delitem
;
1020 while(isspace(devs
[0]))
1022 next
= strchr(devs
, ',');
1024 delitem
= (devs
[0] == '-');
1025 if(devs
[0] == '-') devs
++;
1027 if(!devs
[0] || devs
[0] == ',')
1034 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1035 while(len
> 0 && isspace(devs
[len
-1]))
1037 for(n
= i
;BackendList
[n
].name
;n
++)
1039 if(len
== strlen(BackendList
[n
].name
) &&
1040 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1045 BackendList
[n
] = BackendList
[n
+1];
1047 } while(BackendList
[n
].name
);
1051 struct BackendInfo Bkp
= BackendList
[n
];
1054 BackendList
[n
] = BackendList
[n
-1];
1057 BackendList
[n
] = Bkp
;
1068 BackendList
[i
].name
= NULL
;
1069 BackendList
[i
].getFactory
= NULL
;
1070 BackendList
[i
].Init
= NULL
;
1071 BackendList
[i
].Deinit
= NULL
;
1072 BackendList
[i
].Probe
= NULL
;
1076 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1078 if(BackendList
[i
].getFactory
)
1080 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1081 if(!V0(factory
,init
)())
1083 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1087 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1088 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1090 PlaybackBackend
= BackendList
[i
];
1091 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1093 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1095 CaptureBackend
= BackendList
[i
];
1096 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1102 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1104 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1108 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1109 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1111 PlaybackBackend
= BackendList
[i
];
1112 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1114 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1116 CaptureBackend
= BackendList
[i
];
1117 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1121 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1125 if(ConfigValueStr(NULL
, "excludefx", &str
))
1128 const char *next
= str
;
1132 next
= strchr(str
, ',');
1134 if(!str
[0] || next
== str
)
1137 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1138 for(n
= 0;EffectList
[n
].name
;n
++)
1140 if(len
== strlen(EffectList
[n
].name
) &&
1141 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1142 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1147 InitEffectFactoryMap();
1149 InitEffect(&DefaultEffect
);
1150 str
= getenv("ALSOFT_DEFAULT_REVERB");
1151 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1152 LoadReverbPreset(str
, &DefaultEffect
);
1154 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1157 /************************************************
1158 * Library deinitialization
1159 ************************************************/
1160 static void alc_cleanup(void)
1164 AL_STRING_DEINIT(alcAllDevicesList
);
1165 AL_STRING_DEINIT(alcCaptureDeviceList
);
1167 free(alcDefaultAllDevicesSpecifier
);
1168 alcDefaultAllDevicesSpecifier
= NULL
;
1169 free(alcCaptureDefaultDeviceSpecifier
);
1170 alcCaptureDefaultDeviceSpecifier
= NULL
;
1172 if((dev
=ExchangePtr((XchgPtr
*)&DeviceList
, NULL
)) != NULL
)
1177 } while((dev
=dev
->next
) != NULL
);
1178 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1181 DeinitEffectFactoryMap();
1184 static void alc_deinit_safe(void)
1192 almtx_destroy(&ListLock
);
1193 altss_delete(LocalContext
);
1195 if(LogFile
!= stderr
)
1200 static void alc_deinit(void)
1206 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1207 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1209 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1211 if(!BackendList
[i
].getFactory
)
1212 BackendList
[i
].Deinit();
1215 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1216 V0(factory
,deinit
)();
1220 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1221 V0(factory
,deinit
)();
1228 /************************************************
1229 * Device enumeration
1230 ************************************************/
1231 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1236 al_string_clear(list
);
1238 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1240 if(!PlaybackBackend
.getFactory
)
1241 PlaybackBackend
.Probe(type
);
1244 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1245 V(factory
,probe
)(type
);
1248 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1250 if(!CaptureBackend
.getFactory
)
1251 CaptureBackend
.Probe(type
);
1254 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1255 V(factory
,probe
)(type
);
1260 static void ProbeAllDevicesList(void)
1261 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1262 static void ProbeCaptureDeviceList(void)
1263 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1265 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1267 size_t len
= strlen(name
);
1270 al_string_append_range(devnames
, name
, name
+len
);
1271 al_string_append_char(devnames
, '\0');
1274 void AppendAllDevicesList(const ALCchar
*name
)
1275 { AppendDevice(name
, &alcAllDevicesList
); }
1276 void AppendCaptureDeviceList(const ALCchar
*name
)
1277 { AppendDevice(name
, &alcCaptureDeviceList
); }
1280 /************************************************
1281 * Device format information
1282 ************************************************/
1283 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1287 case DevFmtByte
: return "Signed Byte";
1288 case DevFmtUByte
: return "Unsigned Byte";
1289 case DevFmtShort
: return "Signed Short";
1290 case DevFmtUShort
: return "Unsigned Short";
1291 case DevFmtInt
: return "Signed Int";
1292 case DevFmtUInt
: return "Unsigned Int";
1293 case DevFmtFloat
: return "Float";
1295 return "(unknown type)";
1297 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1301 case DevFmtMono
: return "Mono";
1302 case DevFmtStereo
: return "Stereo";
1303 case DevFmtQuad
: return "Quadraphonic";
1304 case DevFmtX51
: return "5.1 Surround";
1305 case DevFmtX51Side
: return "5.1 Side";
1306 case DevFmtX61
: return "6.1 Surround";
1307 case DevFmtX71
: return "7.1 Surround";
1309 return "(unknown channels)";
1312 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1313 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1317 case DevFmtByte
: return sizeof(ALbyte
);
1318 case DevFmtUByte
: return sizeof(ALubyte
);
1319 case DevFmtShort
: return sizeof(ALshort
);
1320 case DevFmtUShort
: return sizeof(ALushort
);
1321 case DevFmtInt
: return sizeof(ALint
);
1322 case DevFmtUInt
: return sizeof(ALuint
);
1323 case DevFmtFloat
: return sizeof(ALfloat
);
1327 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1331 case DevFmtMono
: return 1;
1332 case DevFmtStereo
: return 2;
1333 case DevFmtQuad
: return 4;
1334 case DevFmtX51
: return 6;
1335 case DevFmtX51Side
: return 6;
1336 case DevFmtX61
: return 7;
1337 case DevFmtX71
: return 8;
1342 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1343 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1345 static const struct {
1347 enum DevFmtChannels channels
;
1348 enum DevFmtType type
;
1350 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1351 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1352 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1354 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1355 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1356 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1358 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1359 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1360 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1362 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1363 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1364 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1366 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1367 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1368 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1370 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1371 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1372 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1376 for(i
= 0;i
< COUNTOF(list
);i
++)
1378 if(list
[i
].format
== format
)
1380 *chans
= list
[i
].channels
;
1381 *type
= list
[i
].type
;
1389 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1394 case ALC_UNSIGNED_BYTE_SOFT
:
1395 case ALC_SHORT_SOFT
:
1396 case ALC_UNSIGNED_SHORT_SOFT
:
1398 case ALC_UNSIGNED_INT_SOFT
:
1399 case ALC_FLOAT_SOFT
:
1405 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1410 case ALC_STEREO_SOFT
:
1412 case ALC_5POINT1_SOFT
:
1413 case ALC_6POINT1_SOFT
:
1414 case ALC_7POINT1_SOFT
:
1421 /************************************************
1422 * Miscellaneous ALC helpers
1423 ************************************************/
1424 extern inline void LockContext(ALCcontext
*context
);
1425 extern inline void UnlockContext(ALCcontext
*context
);
1427 ALint64
ALCdevice_GetLatencyDefault(ALCdevice
*UNUSED(device
))
1432 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1434 return V0(device
->Backend
,getLatency
)();
1437 void ALCdevice_Lock(ALCdevice
*device
)
1439 V0(device
->Backend
,lock
)();
1442 void ALCdevice_Unlock(ALCdevice
*device
)
1444 V0(device
->Backend
,unlock
)();
1448 /* SetDefaultWFXChannelOrder
1450 * Sets the default channel order used by WaveFormatEx.
1452 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1456 for(i
= 0;i
< MaxChannels
;i
++)
1457 device
->ChannelOffsets
[i
] = INVALID_OFFSET
;
1459 switch(device
->FmtChans
)
1461 case DevFmtMono
: device
->ChannelOffsets
[FrontCenter
] = 0;
1463 case DevFmtStereo
: device
->ChannelOffsets
[FrontLeft
] = 0;
1464 device
->ChannelOffsets
[FrontRight
] = 1;
1466 case DevFmtQuad
: device
->ChannelOffsets
[FrontLeft
] = 0;
1467 device
->ChannelOffsets
[FrontRight
] = 1;
1468 device
->ChannelOffsets
[BackLeft
] = 2;
1469 device
->ChannelOffsets
[BackRight
] = 3;
1471 case DevFmtX51
: device
->ChannelOffsets
[FrontLeft
] = 0;
1472 device
->ChannelOffsets
[FrontRight
] = 1;
1473 device
->ChannelOffsets
[FrontCenter
] = 2;
1474 device
->ChannelOffsets
[LFE
] = 3;
1475 device
->ChannelOffsets
[BackLeft
] = 4;
1476 device
->ChannelOffsets
[BackRight
] = 5;
1478 case DevFmtX51Side
: device
->ChannelOffsets
[FrontLeft
] = 0;
1479 device
->ChannelOffsets
[FrontRight
] = 1;
1480 device
->ChannelOffsets
[FrontCenter
] = 2;
1481 device
->ChannelOffsets
[LFE
] = 3;
1482 device
->ChannelOffsets
[SideLeft
] = 4;
1483 device
->ChannelOffsets
[SideRight
] = 5;
1485 case DevFmtX61
: device
->ChannelOffsets
[FrontLeft
] = 0;
1486 device
->ChannelOffsets
[FrontRight
] = 1;
1487 device
->ChannelOffsets
[FrontCenter
] = 2;
1488 device
->ChannelOffsets
[LFE
] = 3;
1489 device
->ChannelOffsets
[BackCenter
] = 4;
1490 device
->ChannelOffsets
[SideLeft
] = 5;
1491 device
->ChannelOffsets
[SideRight
] = 6;
1493 case DevFmtX71
: device
->ChannelOffsets
[FrontLeft
] = 0;
1494 device
->ChannelOffsets
[FrontRight
] = 1;
1495 device
->ChannelOffsets
[FrontCenter
] = 2;
1496 device
->ChannelOffsets
[LFE
] = 3;
1497 device
->ChannelOffsets
[BackLeft
] = 4;
1498 device
->ChannelOffsets
[BackRight
] = 5;
1499 device
->ChannelOffsets
[SideLeft
] = 6;
1500 device
->ChannelOffsets
[SideRight
] = 7;
1505 /* SetDefaultChannelOrder
1507 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1509 void SetDefaultChannelOrder(ALCdevice
*device
)
1513 for(i
= 0;i
< MaxChannels
;i
++)
1514 device
->ChannelOffsets
[i
] = INVALID_OFFSET
;
1516 switch(device
->FmtChans
)
1518 case DevFmtX51
: 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;
1525 case DevFmtX71
: device
->ChannelOffsets
[FrontLeft
] = 0;
1526 device
->ChannelOffsets
[FrontRight
] = 1;
1527 device
->ChannelOffsets
[BackLeft
] = 2;
1528 device
->ChannelOffsets
[BackRight
] = 3;
1529 device
->ChannelOffsets
[FrontCenter
] = 4;
1530 device
->ChannelOffsets
[LFE
] = 5;
1531 device
->ChannelOffsets
[SideLeft
] = 6;
1532 device
->ChannelOffsets
[SideRight
] = 7;
1535 /* Same as WFX order */
1543 SetDefaultWFXChannelOrder(device
);
1549 * Stores the latest ALC device error
1551 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1556 /* DebugBreak() will cause an exception if there is no debugger */
1557 if(IsDebuggerPresent())
1559 #elif defined(SIGTRAP)
1565 device
->LastError
= errorCode
;
1567 LastNullDeviceError
= errorCode
;
1573 * Updates the device's base clock time with however many samples have been
1574 * done. This is used so frequency changes on the device don't cause the time
1575 * to jump forward or back.
1577 static inline void UpdateClockBase(ALCdevice
*device
)
1579 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1580 device
->SamplesDone
= 0;
1583 /* UpdateDeviceParams
1585 * Updates device parameters according to the attribute list (caller is
1586 * responsible for holding the list lock).
1588 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1590 ALCcontext
*context
;
1591 enum DevFmtChannels oldChans
;
1592 enum DevFmtType oldType
;
1596 // Check for attributes
1597 if(device
->Type
== Loopback
)
1603 GotAll
= GotFreq
|GotChans
|GotType
1605 ALCuint freq
, numMono
, numStereo
, numSends
, flags
;
1606 enum DevFmtChannels schans
;
1607 enum DevFmtType stype
;
1608 ALCuint attrIdx
= 0;
1613 WARN("Missing attributes for loopback device\n");
1614 return ALC_INVALID_VALUE
;
1617 numMono
= device
->NumMonoSources
;
1618 numStereo
= device
->NumStereoSources
;
1619 numSends
= device
->NumAuxSends
;
1620 schans
= device
->FmtChans
;
1621 stype
= device
->FmtType
;
1622 freq
= device
->Frequency
;
1623 flags
= device
->Flags
;
1625 while(attrList
[attrIdx
])
1627 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1629 ALCint val
= attrList
[attrIdx
+ 1];
1630 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1631 return ALC_INVALID_VALUE
;
1636 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1638 ALCint val
= attrList
[attrIdx
+ 1];
1639 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1640 return ALC_INVALID_VALUE
;
1645 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1647 freq
= attrList
[attrIdx
+ 1];
1648 if(freq
< MIN_OUTPUT_RATE
)
1649 return ALC_INVALID_VALUE
;
1653 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1655 numStereo
= attrList
[attrIdx
+ 1];
1656 if(numStereo
> device
->MaxNoOfSources
)
1657 numStereo
= device
->MaxNoOfSources
;
1659 numMono
= device
->MaxNoOfSources
- numStereo
;
1662 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1663 numSends
= attrList
[attrIdx
+ 1];
1665 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1667 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1668 flags
|= DEVICE_HRTF_REQUEST
;
1670 flags
&= ~DEVICE_HRTF_REQUEST
;
1676 if(gotFmt
!= GotAll
)
1678 WARN("Missing format for loopback device\n");
1679 return ALC_INVALID_VALUE
;
1682 ConfigValueUInt(NULL
, "sends", &numSends
);
1683 numSends
= minu(MAX_SENDS
, numSends
);
1685 if((device
->Flags
&DEVICE_RUNNING
))
1686 V0(device
->Backend
,stop
)();
1687 device
->Flags
= (flags
& ~DEVICE_RUNNING
);
1689 if(freq
!= device
->Frequency
)
1690 UpdateClockBase(device
);
1691 device
->Frequency
= freq
;
1692 device
->FmtChans
= schans
;
1693 device
->FmtType
= stype
;
1694 device
->NumMonoSources
= numMono
;
1695 device
->NumStereoSources
= numStereo
;
1696 device
->NumAuxSends
= numSends
;
1698 else if(attrList
&& attrList
[0])
1700 ALCuint freq
, numMono
, numStereo
, numSends
;
1701 ALCuint attrIdx
= 0;
1703 /* If a context is already running on the device, stop playback so the
1704 * device attributes can be updated. */
1705 if((device
->Flags
&DEVICE_RUNNING
))
1706 V0(device
->Backend
,stop
)();
1707 device
->Flags
&= ~DEVICE_RUNNING
;
1709 freq
= device
->Frequency
;
1710 numMono
= device
->NumMonoSources
;
1711 numStereo
= device
->NumStereoSources
;
1712 numSends
= device
->NumAuxSends
;
1714 while(attrList
[attrIdx
])
1716 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1718 freq
= attrList
[attrIdx
+ 1];
1719 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1722 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1724 numStereo
= attrList
[attrIdx
+ 1];
1725 if(numStereo
> device
->MaxNoOfSources
)
1726 numStereo
= device
->MaxNoOfSources
;
1728 numMono
= device
->MaxNoOfSources
- numStereo
;
1731 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1732 numSends
= attrList
[attrIdx
+ 1];
1734 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1736 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1737 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1739 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1745 ConfigValueUInt(NULL
, "frequency", &freq
);
1746 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1748 ConfigValueUInt(NULL
, "sends", &numSends
);
1749 numSends
= minu(MAX_SENDS
, numSends
);
1751 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1753 /* SSE and Neon do best with the update size being a multiple of 4 */
1754 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1755 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1757 if(freq
!= device
->Frequency
)
1758 UpdateClockBase(device
);
1759 device
->Frequency
= freq
;
1760 device
->NumMonoSources
= numMono
;
1761 device
->NumStereoSources
= numStereo
;
1762 device
->NumAuxSends
= numSends
;
1765 if((device
->Flags
&DEVICE_RUNNING
))
1766 return ALC_NO_ERROR
;
1768 UpdateClockBase(device
);
1770 oldFreq
= device
->Frequency
;
1771 oldChans
= device
->FmtChans
;
1772 oldType
= device
->FmtType
;
1774 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1775 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"",
1776 DevFmtChannelsString(device
->FmtChans
),
1777 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"",
1778 DevFmtTypeString(device
->FmtType
),
1779 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"",
1781 device
->UpdateSize
, device
->NumUpdates
);
1783 if(device
->Type
!= Loopback
)
1785 int nohrtf
= !(device
->Flags
&DEVICE_HRTF_REQUEST
);
1786 if(GetConfigValueBool(NULL
, "hrtf", !nohrtf
))
1787 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1789 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1791 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1793 enum DevFmtChannels chans
;
1795 if(FindHrtfFormat(device
, &chans
, &freq
))
1797 if(device
->Type
!= Loopback
)
1799 device
->Frequency
= freq
;
1800 device
->FmtChans
= chans
;
1801 device
->Flags
|= DEVICE_CHANNELS_REQUEST
|
1802 DEVICE_FREQUENCY_REQUEST
;
1804 else if(device
->Frequency
!= freq
|| device
->FmtChans
!= chans
)
1806 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1807 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1808 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1813 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1814 return ALC_INVALID_DEVICE
;
1816 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1818 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1819 DevFmtChannelsString(device
->FmtChans
));
1820 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1822 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1824 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1825 DevFmtTypeString(device
->FmtType
));
1826 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1828 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1830 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1831 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1834 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1835 DevFmtChannelsString(device
->FmtChans
),
1836 DevFmtTypeString(device
->FmtType
), device
->Frequency
,
1837 device
->UpdateSize
, device
->NumUpdates
);
1839 aluInitPanning(device
);
1841 V(device
->Synth
,update
)(device
);
1843 device
->Hrtf
= NULL
;
1844 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1846 device
->Hrtf
= GetHrtf(device
);
1848 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1850 TRACE("HRTF %s\n", device
->Hrtf
?"enabled":"disabled");
1852 if(!device
->Hrtf
&& device
->Bs2bLevel
> 0 && device
->Bs2bLevel
<= 6)
1856 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
1857 bs2b_clear(device
->Bs2b
);
1859 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
1860 bs2b_set_level(device
->Bs2b
, device
->Bs2bLevel
);
1861 TRACE("BS2B level %d\n", device
->Bs2bLevel
);
1866 device
->Bs2b
= NULL
;
1867 TRACE("BS2B disabled\n");
1870 device
->Flags
&= ~DEVICE_WIDE_STEREO
;
1871 if(device
->Type
!= Loopback
&& !device
->Hrtf
&& GetConfigValueBool(NULL
, "wide-stereo", AL_FALSE
))
1872 device
->Flags
|= DEVICE_WIDE_STEREO
;
1874 if(!device
->Hrtf
&& (device
->UpdateSize
&3))
1876 if((CPUCapFlags
&CPU_CAP_SSE
))
1877 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1878 if((CPUCapFlags
&CPU_CAP_NEON
))
1879 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1882 SetMixerFPUMode(&oldMode
);
1883 ALCdevice_Lock(device
);
1884 context
= device
->ContextList
;
1889 context
->UpdateSources
= AL_FALSE
;
1890 LockUIntMapRead(&context
->EffectSlotMap
);
1891 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
1893 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
1895 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1897 UnlockUIntMapRead(&context
->EffectSlotMap
);
1898 ALCdevice_Unlock(device
);
1899 RestoreFPUMode(&oldMode
);
1900 return ALC_INVALID_DEVICE
;
1902 slot
->NeedsUpdate
= AL_FALSE
;
1903 V(slot
->EffectState
,update
)(device
, slot
);
1905 UnlockUIntMapRead(&context
->EffectSlotMap
);
1907 LockUIntMapRead(&context
->SourceMap
);
1908 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1910 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
1911 ALuint s
= device
->NumAuxSends
;
1912 while(s
< MAX_SENDS
)
1914 if(source
->Send
[s
].Slot
)
1915 DecrementRef(&source
->Send
[s
].Slot
->ref
);
1916 source
->Send
[s
].Slot
= NULL
;
1917 source
->Send
[s
].Gain
= 1.0f
;
1918 source
->Send
[s
].GainHF
= 1.0f
;
1921 source
->NeedsUpdate
= AL_TRUE
;
1923 UnlockUIntMapRead(&context
->SourceMap
);
1925 for(pos
= 0;pos
< context
->ActiveSourceCount
;pos
++)
1927 ALactivesource
*src
= context
->ActiveSources
[pos
];
1928 ALsource
*source
= src
->Source
;
1929 ALuint s
= device
->NumAuxSends
;
1930 while(s
< MAX_SENDS
)
1932 src
->Send
[s
].Moving
= AL_FALSE
;
1933 src
->Send
[s
].Counter
= 0;
1937 src
->Update(src
, context
);
1938 source
->NeedsUpdate
= AL_FALSE
;
1941 context
= context
->next
;
1943 if(device
->DefaultSlot
)
1945 ALeffectslot
*slot
= device
->DefaultSlot
;
1947 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1949 ALCdevice_Unlock(device
);
1950 RestoreFPUMode(&oldMode
);
1951 return ALC_INVALID_DEVICE
;
1953 slot
->NeedsUpdate
= AL_FALSE
;
1954 V(slot
->EffectState
,update
)(device
, slot
);
1956 ALCdevice_Unlock(device
);
1957 RestoreFPUMode(&oldMode
);
1959 if(!(device
->Flags
&DEVICE_PAUSED
))
1961 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
1962 return ALC_INVALID_DEVICE
;
1963 device
->Flags
|= DEVICE_RUNNING
;
1966 return ALC_NO_ERROR
;
1971 * Frees the device structure, and destroys any objects the app failed to
1972 * delete. Called once there's no more references on the device.
1974 static ALCvoid
FreeDevice(ALCdevice
*device
)
1976 TRACE("%p\n", device
);
1978 V0(device
->Backend
,close
)();
1979 DELETE_OBJ(device
->Backend
);
1980 device
->Backend
= NULL
;
1982 DELETE_OBJ(device
->Synth
);
1983 device
->Synth
= NULL
;
1985 if(device
->DefaultSlot
)
1987 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
1988 device
->DefaultSlot
= NULL
;
1992 if(device
->DefaultSfont
)
1993 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
1994 device
->DefaultSfont
= NULL
;
1996 if(device
->BufferMap
.size
> 0)
1998 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
1999 ReleaseALBuffers(device
);
2001 ResetUIntMap(&device
->BufferMap
);
2003 if(device
->EffectMap
.size
> 0)
2005 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2006 ReleaseALEffects(device
);
2008 ResetUIntMap(&device
->EffectMap
);
2010 if(device
->FilterMap
.size
> 0)
2012 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2013 ReleaseALFilters(device
);
2015 ResetUIntMap(&device
->FilterMap
);
2017 if(device
->SfontMap
.size
> 0)
2019 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2020 ReleaseALSoundfonts(device
);
2022 ResetUIntMap(&device
->SfontMap
);
2024 if(device
->PresetMap
.size
> 0)
2026 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2027 ReleaseALPresets(device
);
2029 ResetUIntMap(&device
->PresetMap
);
2031 if(device
->FontsoundMap
.size
> 0)
2033 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2034 ReleaseALFontsounds(device
);
2036 ResetUIntMap(&device
->FontsoundMap
);
2039 device
->Bs2b
= NULL
;
2041 AL_STRING_DEINIT(device
->DeviceName
);
2047 void ALCdevice_IncRef(ALCdevice
*device
)
2050 ref
= IncrementRef(&device
->ref
);
2051 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2054 void ALCdevice_DecRef(ALCdevice
*device
)
2057 ref
= DecrementRef(&device
->ref
);
2058 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2059 if(ref
== 0) FreeDevice(device
);
2064 * Checks if the device handle is valid, and increments its ref count if so.
2066 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2068 ALCdevice
*tmpDevice
;
2074 tmpDevice
= DeviceList
;
2075 while(tmpDevice
&& tmpDevice
!= device
)
2076 tmpDevice
= tmpDevice
->next
;
2079 ALCdevice_IncRef(tmpDevice
);
2087 * Initializes context fields
2089 static ALvoid
InitContext(ALCcontext
*Context
)
2093 //Initialise listener
2094 Context
->Listener
->Gain
= 1.0f
;
2095 Context
->Listener
->MetersPerUnit
= 1.0f
;
2096 Context
->Listener
->Position
[0] = 0.0f
;
2097 Context
->Listener
->Position
[1] = 0.0f
;
2098 Context
->Listener
->Position
[2] = 0.0f
;
2099 Context
->Listener
->Velocity
[0] = 0.0f
;
2100 Context
->Listener
->Velocity
[1] = 0.0f
;
2101 Context
->Listener
->Velocity
[2] = 0.0f
;
2102 Context
->Listener
->Forward
[0] = 0.0f
;
2103 Context
->Listener
->Forward
[1] = 0.0f
;
2104 Context
->Listener
->Forward
[2] = -1.0f
;
2105 Context
->Listener
->Up
[0] = 0.0f
;
2106 Context
->Listener
->Up
[1] = 1.0f
;
2107 Context
->Listener
->Up
[2] = 0.0f
;
2108 for(i
= 0;i
< 4;i
++)
2110 for(j
= 0;j
< 4;j
++)
2111 Context
->Listener
->Params
.Matrix
[i
][j
] = ((i
==j
) ? 1.0f
: 0.0f
);
2113 for(i
= 0;i
< 3;i
++)
2114 Context
->Listener
->Params
.Velocity
[i
] = 0.0f
;
2117 Context
->LastError
= AL_NO_ERROR
;
2118 Context
->UpdateSources
= AL_FALSE
;
2119 Context
->ActiveSourceCount
= 0;
2120 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2121 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2124 Context
->DistanceModel
= DefaultDistanceModel
;
2125 Context
->SourceDistanceModel
= AL_FALSE
;
2126 Context
->DopplerFactor
= 1.0f
;
2127 Context
->DopplerVelocity
= 1.0f
;
2128 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2129 Context
->DeferUpdates
= AL_FALSE
;
2131 Context
->ExtensionList
= alExtList
;
2137 * Cleans up the context, and destroys any remaining objects the app failed to
2138 * delete. Called once there's no more references on the context.
2140 static ALCvoid
FreeContext(ALCcontext
*context
)
2144 TRACE("%p\n", context
);
2146 if(context
->SourceMap
.size
> 0)
2148 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2149 ReleaseALSources(context
);
2151 ResetUIntMap(&context
->SourceMap
);
2153 if(context
->EffectSlotMap
.size
> 0)
2155 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2156 ReleaseALAuxiliaryEffectSlots(context
);
2158 ResetUIntMap(&context
->EffectSlotMap
);
2160 for(i
= 0;i
< context
->MaxActiveSources
;i
++)
2162 al_free(context
->ActiveSources
[i
]);
2163 context
->ActiveSources
[i
] = NULL
;
2165 free(context
->ActiveSources
);
2166 context
->ActiveSources
= NULL
;
2167 context
->ActiveSourceCount
= 0;
2168 context
->MaxActiveSources
= 0;
2170 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2172 ALCdevice_DecRef(context
->Device
);
2173 context
->Device
= NULL
;
2175 //Invalidate context
2176 memset(context
, 0, sizeof(ALCcontext
));
2182 * Removes the context reference from the given device and removes it from
2183 * being current on the running thread or globally.
2185 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2187 ALCcontext
*volatile*tmp_ctx
;
2189 if(altss_get(LocalContext
) == context
)
2191 WARN("%p released while current on thread\n", context
);
2192 altss_set(LocalContext
, NULL
);
2193 ALCcontext_DecRef(context
);
2196 if(CompExchangePtr((XchgPtr
*)&GlobalContext
, context
, NULL
) == context
)
2197 ALCcontext_DecRef(context
);
2199 ALCdevice_Lock(device
);
2200 tmp_ctx
= &device
->ContextList
;
2203 if(CompExchangePtr((XchgPtr
*)tmp_ctx
, context
, context
->next
) == context
)
2205 tmp_ctx
= &(*tmp_ctx
)->next
;
2207 ALCdevice_Unlock(device
);
2209 ALCcontext_DecRef(context
);
2212 void ALCcontext_IncRef(ALCcontext
*context
)
2215 ref
= IncrementRef(&context
->ref
);
2216 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2219 void ALCcontext_DecRef(ALCcontext
*context
)
2222 ref
= DecrementRef(&context
->ref
);
2223 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2224 if(ref
== 0) FreeContext(context
);
2227 static void ReleaseThreadCtx(void *ptr
)
2229 WARN("%p current for thread being destroyed\n", ptr
);
2230 ALCcontext_DecRef(ptr
);
2235 * Checks that the given context is valid, and increments its reference count.
2237 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2245 ALCcontext
*tmp_ctx
= dev
->ContextList
;
2248 if(tmp_ctx
== context
)
2250 ALCcontext_IncRef(tmp_ctx
);
2254 tmp_ctx
= tmp_ctx
->next
;
2266 * Returns the currently active context for this thread, and adds a reference
2267 * without locking it.
2269 ALCcontext
*GetContextRef(void)
2271 ALCcontext
*context
;
2273 context
= altss_get(LocalContext
);
2275 ALCcontext_IncRef(context
);
2279 context
= GlobalContext
;
2281 ALCcontext_IncRef(context
);
2289 /************************************************
2290 * Standard ALC functions
2291 ************************************************/
2295 * Return last ALC generated error code for the given device
2297 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2301 if(VerifyDevice(device
))
2303 errorCode
= ExchangeInt(&device
->LastError
, ALC_NO_ERROR
);
2304 ALCdevice_DecRef(device
);
2307 errorCode
= ExchangeInt(&LastNullDeviceError
, ALC_NO_ERROR
);
2313 /* alcSuspendContext
2317 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*UNUSED(context
))
2321 /* alcProcessContext
2325 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*UNUSED(context
))
2332 * Returns information about the device, and error strings
2334 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2336 const ALCchar
*value
= NULL
;
2344 case ALC_INVALID_ENUM
:
2345 value
= alcErrInvalidEnum
;
2348 case ALC_INVALID_VALUE
:
2349 value
= alcErrInvalidValue
;
2352 case ALC_INVALID_DEVICE
:
2353 value
= alcErrInvalidDevice
;
2356 case ALC_INVALID_CONTEXT
:
2357 value
= alcErrInvalidContext
;
2360 case ALC_OUT_OF_MEMORY
:
2361 value
= alcErrOutOfMemory
;
2364 case ALC_DEVICE_SPECIFIER
:
2365 value
= alcDefaultName
;
2368 case ALC_ALL_DEVICES_SPECIFIER
:
2369 if(VerifyDevice(Device
))
2371 value
= al_string_get_cstr(Device
->DeviceName
);
2372 ALCdevice_DecRef(Device
);
2376 ProbeAllDevicesList();
2377 value
= al_string_get_cstr(alcAllDevicesList
);
2381 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2382 if(VerifyDevice(Device
))
2384 value
= al_string_get_cstr(Device
->DeviceName
);
2385 ALCdevice_DecRef(Device
);
2389 ProbeCaptureDeviceList();
2390 value
= al_string_get_cstr(alcCaptureDeviceList
);
2394 /* Default devices are always first in the list */
2395 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2396 value
= alcDefaultName
;
2399 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2400 if(al_string_empty(alcAllDevicesList
))
2401 ProbeAllDevicesList();
2403 Device
= VerifyDevice(Device
);
2405 free(alcDefaultAllDevicesSpecifier
);
2406 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2407 if(!alcDefaultAllDevicesSpecifier
)
2408 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2410 value
= alcDefaultAllDevicesSpecifier
;
2411 if(Device
) ALCdevice_DecRef(Device
);
2414 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2415 if(al_string_empty(alcCaptureDeviceList
))
2416 ProbeCaptureDeviceList();
2418 Device
= VerifyDevice(Device
);
2420 free(alcCaptureDefaultDeviceSpecifier
);
2421 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2422 if(!alcCaptureDefaultDeviceSpecifier
)
2423 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2425 value
= alcCaptureDefaultDeviceSpecifier
;
2426 if(Device
) ALCdevice_DecRef(Device
);
2429 case ALC_EXTENSIONS
:
2430 if(!VerifyDevice(Device
))
2431 value
= alcNoDeviceExtList
;
2434 value
= alcExtensionList
;
2435 ALCdevice_DecRef(Device
);
2440 Device
= VerifyDevice(Device
);
2441 alcSetError(Device
, ALC_INVALID_ENUM
);
2442 if(Device
) ALCdevice_DecRef(Device
);
2450 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2454 if(size
<= 0 || values
== NULL
)
2456 alcSetError(device
, ALC_INVALID_VALUE
);
2464 case ALC_MAJOR_VERSION
:
2465 values
[0] = alcMajorVersion
;
2467 case ALC_MINOR_VERSION
:
2468 values
[0] = alcMinorVersion
;
2471 case ALC_ATTRIBUTES_SIZE
:
2472 case ALC_ALL_ATTRIBUTES
:
2476 case ALC_MONO_SOURCES
:
2477 case ALC_STEREO_SOURCES
:
2478 case ALC_CAPTURE_SAMPLES
:
2479 case ALC_FORMAT_CHANNELS_SOFT
:
2480 case ALC_FORMAT_TYPE_SOFT
:
2481 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2485 alcSetError(NULL
, ALC_INVALID_ENUM
);
2491 if(device
->Type
== Capture
)
2495 case ALC_CAPTURE_SAMPLES
:
2496 ALCdevice_Lock(device
);
2497 values
[0] = V0(device
->Backend
,availableSamples
)();
2498 ALCdevice_Unlock(device
);
2502 values
[0] = device
->Connected
;
2506 alcSetError(device
, ALC_INVALID_ENUM
);
2515 case ALC_MAJOR_VERSION
:
2516 values
[0] = alcMajorVersion
;
2519 case ALC_MINOR_VERSION
:
2520 values
[0] = alcMinorVersion
;
2523 case ALC_EFX_MAJOR_VERSION
:
2524 values
[0] = alcEFXMajorVersion
;
2527 case ALC_EFX_MINOR_VERSION
:
2528 values
[0] = alcEFXMinorVersion
;
2531 case ALC_ATTRIBUTES_SIZE
:
2535 case ALC_ALL_ATTRIBUTES
:
2538 alcSetError(device
, ALC_INVALID_VALUE
);
2543 values
[i
++] = ALC_FREQUENCY
;
2544 values
[i
++] = device
->Frequency
;
2546 if(device
->Type
!= Loopback
)
2548 values
[i
++] = ALC_REFRESH
;
2549 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2551 values
[i
++] = ALC_SYNC
;
2552 values
[i
++] = ALC_FALSE
;
2556 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2557 values
[i
++] = device
->FmtChans
;
2559 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2560 values
[i
++] = device
->FmtType
;
2563 values
[i
++] = ALC_MONO_SOURCES
;
2564 values
[i
++] = device
->NumMonoSources
;
2566 values
[i
++] = ALC_STEREO_SOURCES
;
2567 values
[i
++] = device
->NumStereoSources
;
2569 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2570 values
[i
++] = device
->NumAuxSends
;
2572 values
[i
++] = ALC_HRTF_SOFT
;
2573 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2579 values
[0] = device
->Frequency
;
2583 if(device
->Type
== Loopback
)
2585 alcSetError(device
, ALC_INVALID_DEVICE
);
2588 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2592 if(device
->Type
== Loopback
)
2594 alcSetError(device
, ALC_INVALID_DEVICE
);
2597 values
[0] = ALC_FALSE
;
2600 case ALC_FORMAT_CHANNELS_SOFT
:
2601 if(device
->Type
!= Loopback
)
2603 alcSetError(device
, ALC_INVALID_DEVICE
);
2606 values
[0] = device
->FmtChans
;
2609 case ALC_FORMAT_TYPE_SOFT
:
2610 if(device
->Type
!= Loopback
)
2612 alcSetError(device
, ALC_INVALID_DEVICE
);
2615 values
[0] = device
->FmtType
;
2618 case ALC_MONO_SOURCES
:
2619 values
[0] = device
->NumMonoSources
;
2622 case ALC_STEREO_SOURCES
:
2623 values
[0] = device
->NumStereoSources
;
2626 case ALC_MAX_AUXILIARY_SENDS
:
2627 values
[0] = device
->NumAuxSends
;
2631 values
[0] = device
->Connected
;
2635 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2639 alcSetError(device
, ALC_INVALID_ENUM
);
2647 * Returns information about the device and the version of OpenAL
2649 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2651 device
= VerifyDevice(device
);
2652 if(size
<= 0 || values
== NULL
)
2653 alcSetError(device
, ALC_INVALID_VALUE
);
2655 GetIntegerv(device
, param
, size
, values
);
2656 if(device
) ALCdevice_DecRef(device
);
2659 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2664 device
= VerifyDevice(device
);
2665 if(size
<= 0 || values
== NULL
)
2666 alcSetError(device
, ALC_INVALID_VALUE
);
2667 else if(!device
|| device
->Type
== Capture
)
2669 ivals
= malloc(size
* sizeof(ALCint
));
2670 size
= GetIntegerv(device
, pname
, size
, ivals
);
2671 for(i
= 0;i
< size
;i
++)
2672 values
[i
] = ivals
[i
];
2675 else /* render device */
2679 case ALC_ATTRIBUTES_SIZE
:
2683 case ALC_ALL_ATTRIBUTES
:
2685 alcSetError(device
, ALC_INVALID_VALUE
);
2690 V0(device
->Backend
,lock
)();
2691 values
[i
++] = ALC_FREQUENCY
;
2692 values
[i
++] = device
->Frequency
;
2694 if(device
->Type
!= Loopback
)
2696 values
[i
++] = ALC_REFRESH
;
2697 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2699 values
[i
++] = ALC_SYNC
;
2700 values
[i
++] = ALC_FALSE
;
2704 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2705 values
[i
++] = device
->FmtChans
;
2707 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2708 values
[i
++] = device
->FmtType
;
2711 values
[i
++] = ALC_MONO_SOURCES
;
2712 values
[i
++] = device
->NumMonoSources
;
2714 values
[i
++] = ALC_STEREO_SOURCES
;
2715 values
[i
++] = device
->NumStereoSources
;
2717 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2718 values
[i
++] = device
->NumAuxSends
;
2720 values
[i
++] = ALC_HRTF_SOFT
;
2721 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2723 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2724 values
[i
++] = device
->ClockBase
+
2725 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2728 V0(device
->Backend
,unlock
)();
2732 case ALC_DEVICE_CLOCK_SOFT
:
2733 V0(device
->Backend
,lock
)();
2734 *values
= device
->ClockBase
+
2735 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2736 V0(device
->Backend
,unlock
)();
2740 ivals
= malloc(size
* sizeof(ALCint
));
2741 size
= GetIntegerv(device
, pname
, size
, ivals
);
2742 for(i
= 0;i
< size
;i
++)
2743 values
[i
] = ivals
[i
];
2749 ALCdevice_DecRef(device
);
2753 /* alcIsExtensionPresent
2755 * Determines if there is support for a particular extension
2757 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2759 ALCboolean bResult
= ALC_FALSE
;
2761 device
= VerifyDevice(device
);
2764 alcSetError(device
, ALC_INVALID_VALUE
);
2767 size_t len
= strlen(extName
);
2768 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2771 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2772 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2777 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2781 } while(isspace(*ptr
));
2786 ALCdevice_DecRef(device
);
2791 /* alcGetProcAddress
2793 * Retrieves the function address for a particular extension function
2795 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2797 ALCvoid
*ptr
= NULL
;
2801 device
= VerifyDevice(device
);
2802 alcSetError(device
, ALC_INVALID_VALUE
);
2803 if(device
) ALCdevice_DecRef(device
);
2808 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2810 ptr
= alcFunctions
[i
].address
;
2819 * Get the value for a particular ALC enumeration name
2821 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
2827 device
= VerifyDevice(device
);
2828 alcSetError(device
, ALC_INVALID_VALUE
);
2829 if(device
) ALCdevice_DecRef(device
);
2834 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
2836 val
= enumeration
[i
].value
;
2845 * Create and attach a context to the given device.
2847 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
2849 ALCcontext
*ALContext
;
2853 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
2856 alcSetError(device
, ALC_INVALID_DEVICE
);
2857 if(device
) ALCdevice_DecRef(device
);
2861 device
->LastError
= ALC_NO_ERROR
;
2863 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
2866 alcSetError(device
, err
);
2867 if(err
== ALC_INVALID_DEVICE
)
2869 ALCdevice_Lock(device
);
2870 aluHandleDisconnect(device
);
2871 ALCdevice_Unlock(device
);
2873 ALCdevice_DecRef(device
);
2877 ALContext
= calloc(1, sizeof(ALCcontext
)+sizeof(ALlistener
));
2880 InitRef(&ALContext
->ref
, 1);
2881 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
2883 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
2885 ALContext
->MaxActiveSources
= 256;
2886 ALContext
->ActiveSources
= calloc(ALContext
->MaxActiveSources
,
2887 sizeof(ALContext
->ActiveSources
[0]));
2889 if(!ALContext
|| !ALContext
->ActiveSources
)
2891 if(!device
->ContextList
)
2893 V0(device
->Backend
,stop
)();
2894 device
->Flags
&= ~DEVICE_RUNNING
;
2900 free(ALContext
->ActiveSources
);
2901 ALContext
->ActiveSources
= NULL
;
2903 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
2909 alcSetError(device
, ALC_OUT_OF_MEMORY
);
2910 ALCdevice_DecRef(device
);
2914 ALContext
->Device
= device
;
2915 ALCdevice_IncRef(device
);
2916 InitContext(ALContext
);
2919 ALContext
->next
= device
->ContextList
;
2920 } while(CompExchangePtr((XchgPtr
*)&device
->ContextList
, ALContext
->next
, ALContext
) != ALContext
->next
);
2923 ALCdevice_DecRef(device
);
2925 TRACE("Created context %p\n", ALContext
);
2929 /* alcDestroyContext
2931 * Remove a context from its device
2933 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
2938 /* alcGetContextsDevice sets an error for invalid contexts */
2939 Device
= alcGetContextsDevice(context
);
2942 ReleaseContext(context
, Device
);
2943 if(!Device
->ContextList
)
2945 V0(Device
->Backend
,stop
)();
2946 Device
->Flags
&= ~DEVICE_RUNNING
;
2953 /* alcGetCurrentContext
2955 * Returns the currently active context on the calling thread
2957 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
2959 ALCcontext
*Context
;
2961 Context
= altss_get(LocalContext
);
2962 if(!Context
) Context
= GlobalContext
;
2967 /* alcGetThreadContext
2969 * Returns the currently active thread-local context
2971 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
2973 ALCcontext
*Context
;
2974 Context
= altss_get(LocalContext
);
2979 /* alcMakeContextCurrent
2981 * Makes the given context the active process-wide context, and removes the
2982 * thread-local context for the calling thread.
2984 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
2986 /* context must be valid or NULL */
2987 if(context
&& !(context
=VerifyContext(context
)))
2989 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2992 /* context's reference count is already incremented */
2993 context
= ExchangePtr((XchgPtr
*)&GlobalContext
, context
);
2994 if(context
) ALCcontext_DecRef(context
);
2996 if((context
=altss_get(LocalContext
)) != NULL
)
2998 altss_set(LocalContext
, NULL
);
2999 ALCcontext_DecRef(context
);
3005 /* alcSetThreadContext
3007 * Makes the given context the active context for the current thread
3009 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3013 /* context must be valid or NULL */
3014 if(context
&& !(context
=VerifyContext(context
)))
3016 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3019 /* context's reference count is already incremented */
3020 old
= altss_get(LocalContext
);
3021 altss_set(LocalContext
, context
);
3022 if(old
) ALCcontext_DecRef(old
);
3028 /* alcGetContextsDevice
3030 * Returns the device that a particular context is attached to
3032 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3036 if(!(Context
=VerifyContext(Context
)))
3038 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3041 Device
= Context
->Device
;
3042 ALCcontext_DecRef(Context
);
3050 * Opens the named device.
3052 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3060 if(!PlaybackBackend
.name
)
3062 alcSetError(NULL
, ALC_INVALID_VALUE
);
3066 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3069 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3072 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3077 InitRef(&device
->ref
, 1);
3078 device
->Connected
= ALC_TRUE
;
3079 device
->Type
= Playback
;
3080 device
->LastError
= ALC_NO_ERROR
;
3083 device
->Bs2b
= NULL
;
3084 device
->Bs2bLevel
= 0;
3085 AL_STRING_INIT(device
->DeviceName
);
3087 device
->ContextList
= NULL
;
3089 device
->ClockBase
= 0;
3090 device
->SamplesDone
= 0;
3092 device
->MaxNoOfSources
= 256;
3093 device
->AuxiliaryEffectSlotMax
= 4;
3094 device
->NumAuxSends
= MAX_SENDS
;
3096 InitUIntMap(&device
->BufferMap
, ~0);
3097 InitUIntMap(&device
->EffectMap
, ~0);
3098 InitUIntMap(&device
->FilterMap
, ~0);
3099 InitUIntMap(&device
->SfontMap
, ~0);
3100 InitUIntMap(&device
->PresetMap
, ~0);
3101 InitUIntMap(&device
->FontsoundMap
, ~0);
3104 device
->FmtChans
= DevFmtChannelsDefault
;
3105 device
->FmtType
= DevFmtTypeDefault
;
3106 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3107 device
->NumUpdates
= 4;
3108 device
->UpdateSize
= 1024;
3110 if(!PlaybackBackend
.getFactory
)
3111 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3112 ALCbackend_Playback
);
3115 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3116 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3118 if(!device
->Backend
)
3121 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3126 if(ConfigValueStr(NULL
, "channels", &fmt
))
3128 static const struct {
3129 const char name
[16];
3130 enum DevFmtChannels chans
;
3132 { "mono", DevFmtMono
},
3133 { "stereo", DevFmtStereo
},
3134 { "quad", DevFmtQuad
},
3135 { "surround51", DevFmtX51
},
3136 { "surround61", DevFmtX61
},
3137 { "surround71", DevFmtX71
},
3141 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3143 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3145 device
->FmtChans
= chanlist
[i
].chans
;
3146 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3150 if(i
== COUNTOF(chanlist
))
3151 ERR("Unsupported channels: %s\n", fmt
);
3153 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3155 static const struct {
3156 const char name
[16];
3157 enum DevFmtType type
;
3159 { "int8", DevFmtByte
},
3160 { "uint8", DevFmtUByte
},
3161 { "int16", DevFmtShort
},
3162 { "uint16", DevFmtUShort
},
3163 { "int32", DevFmtInt
},
3164 { "uint32", DevFmtUInt
},
3165 { "float32", DevFmtFloat
},
3169 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3171 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3173 device
->FmtType
= typelist
[i
].type
;
3174 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3178 if(i
== COUNTOF(typelist
))
3179 ERR("Unsupported sample-type: %s\n", fmt
);
3181 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3182 if((device
->Flags
&DEVICE_FORMAT_REQUEST
) != DEVICE_FORMAT_REQUEST
&&
3183 ConfigValueStr(NULL
, "format", &fmt
))
3185 static const struct {
3186 const char name
[32];
3187 enum DevFmtChannels channels
;
3188 enum DevFmtType type
;
3190 { "AL_FORMAT_MONO32", DevFmtMono
, DevFmtFloat
},
3191 { "AL_FORMAT_STEREO32", DevFmtStereo
, DevFmtFloat
},
3192 { "AL_FORMAT_QUAD32", DevFmtQuad
, DevFmtFloat
},
3193 { "AL_FORMAT_51CHN32", DevFmtX51
, DevFmtFloat
},
3194 { "AL_FORMAT_61CHN32", DevFmtX61
, DevFmtFloat
},
3195 { "AL_FORMAT_71CHN32", DevFmtX71
, DevFmtFloat
},
3197 { "AL_FORMAT_MONO16", DevFmtMono
, DevFmtShort
},
3198 { "AL_FORMAT_STEREO16", DevFmtStereo
, DevFmtShort
},
3199 { "AL_FORMAT_QUAD16", DevFmtQuad
, DevFmtShort
},
3200 { "AL_FORMAT_51CHN16", DevFmtX51
, DevFmtShort
},
3201 { "AL_FORMAT_61CHN16", DevFmtX61
, DevFmtShort
},
3202 { "AL_FORMAT_71CHN16", DevFmtX71
, DevFmtShort
},
3204 { "AL_FORMAT_MONO8", DevFmtMono
, DevFmtByte
},
3205 { "AL_FORMAT_STEREO8", DevFmtStereo
, DevFmtByte
},
3206 { "AL_FORMAT_QUAD8", DevFmtQuad
, DevFmtByte
},
3207 { "AL_FORMAT_51CHN8", DevFmtX51
, DevFmtByte
},
3208 { "AL_FORMAT_61CHN8", DevFmtX61
, DevFmtByte
},
3209 { "AL_FORMAT_71CHN8", DevFmtX71
, DevFmtByte
}
3213 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3214 for(i
= 0;i
< COUNTOF(formats
);i
++)
3216 if(strcasecmp(fmt
, formats
[i
].name
) == 0)
3218 if(!(device
->Flags
&DEVICE_CHANNELS_REQUEST
))
3219 device
->FmtChans
= formats
[i
].channels
;
3220 if(!(device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
3221 device
->FmtType
= formats
[i
].type
;
3222 device
->Flags
|= DEVICE_FORMAT_REQUEST
;
3226 if(i
== COUNTOF(formats
))
3227 ERR("Unsupported format: %s\n", fmt
);
3229 #undef DEVICE_FORMAT_REQUEST
3231 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3233 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3234 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3235 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3236 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3239 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3240 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3242 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3243 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3244 if((CPUCapFlags
&CPU_CAP_SSE
))
3245 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3247 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3248 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3250 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3251 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3253 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3254 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3256 ConfigValueInt(NULL
, "cf_level", &device
->Bs2bLevel
);
3258 device
->NumStereoSources
= 1;
3259 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3261 device
->Synth
= SynthCreate(device
);
3264 DELETE_OBJ(device
->Backend
);
3266 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3270 // Find a playback device to open
3271 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3273 DELETE_OBJ(device
->Synth
);
3274 DELETE_OBJ(device
->Backend
);
3276 alcSetError(NULL
, err
);
3280 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3282 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3283 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3285 device
->DefaultSlot
= NULL
;
3286 ERR("Failed to initialize the default effect slot\n");
3288 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3290 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3291 device
->DefaultSlot
= NULL
;
3293 ERR("Failed to initialize the default effect\n");
3298 device
->next
= DeviceList
;
3299 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3301 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3307 * Closes the given device.
3309 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*Device
)
3311 ALCdevice
*volatile*list
;
3316 while(*list
&& *list
!= Device
)
3317 list
= &(*list
)->next
;
3319 if(!*list
|| (*list
)->Type
== Capture
)
3321 alcSetError(*list
, ALC_INVALID_DEVICE
);
3326 *list
= (*list
)->next
;
3329 while((ctx
=Device
->ContextList
) != NULL
)
3331 WARN("Releasing context %p\n", ctx
);
3332 ReleaseContext(ctx
, Device
);
3334 if((Device
->Flags
&DEVICE_RUNNING
))
3335 V0(Device
->Backend
,stop
)();
3336 Device
->Flags
&= ~DEVICE_RUNNING
;
3338 ALCdevice_DecRef(Device
);
3344 /************************************************
3345 * ALC capture functions
3346 ************************************************/
3347 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3349 ALCdevice
*device
= NULL
;
3354 if(!CaptureBackend
.name
)
3356 alcSetError(NULL
, ALC_INVALID_VALUE
);
3362 alcSetError(NULL
, ALC_INVALID_VALUE
);
3366 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3369 device
= al_calloc(16, sizeof(ALCdevice
));
3372 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3377 InitRef(&device
->ref
, 1);
3378 device
->Connected
= ALC_TRUE
;
3379 device
->Type
= Capture
;
3381 AL_STRING_INIT(device
->DeviceName
);
3383 InitUIntMap(&device
->BufferMap
, ~0);
3384 InitUIntMap(&device
->EffectMap
, ~0);
3385 InitUIntMap(&device
->FilterMap
, ~0);
3386 InitUIntMap(&device
->SfontMap
, ~0);
3387 InitUIntMap(&device
->PresetMap
, ~0);
3388 InitUIntMap(&device
->FontsoundMap
, ~0);
3390 if(!CaptureBackend
.getFactory
)
3391 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3392 ALCbackend_Capture
);
3395 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3396 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3398 if(!device
->Backend
)
3401 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3405 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3406 device
->Frequency
= frequency
;
3408 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3409 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3412 alcSetError(NULL
, ALC_INVALID_ENUM
);
3416 device
->UpdateSize
= samples
;
3417 device
->NumUpdates
= 1;
3419 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3422 alcSetError(NULL
, err
);
3427 device
->next
= DeviceList
;
3428 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3430 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3434 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*Device
)
3436 ALCdevice
*volatile*list
;
3440 while(*list
&& *list
!= Device
)
3441 list
= &(*list
)->next
;
3443 if(!*list
|| (*list
)->Type
!= Capture
)
3445 alcSetError(*list
, ALC_INVALID_DEVICE
);
3450 *list
= (*list
)->next
;
3453 ALCdevice_DecRef(Device
);
3458 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3460 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3461 alcSetError(device
, ALC_INVALID_DEVICE
);
3464 ALCdevice_Lock(device
);
3465 if(device
->Connected
)
3467 if(!(device
->Flags
&DEVICE_RUNNING
))
3468 V0(device
->Backend
,start
)();
3469 device
->Flags
|= DEVICE_RUNNING
;
3471 ALCdevice_Unlock(device
);
3474 if(device
) ALCdevice_DecRef(device
);
3477 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3479 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3480 alcSetError(device
, ALC_INVALID_DEVICE
);
3483 ALCdevice_Lock(device
);
3484 if((device
->Flags
&DEVICE_RUNNING
))
3485 V0(device
->Backend
,stop
)();
3486 device
->Flags
&= ~DEVICE_RUNNING
;
3487 ALCdevice_Unlock(device
);
3490 if(device
) ALCdevice_DecRef(device
);
3493 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3495 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3496 alcSetError(device
, ALC_INVALID_DEVICE
);
3499 ALCenum err
= ALC_INVALID_VALUE
;
3501 ALCdevice_Lock(device
);
3502 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3503 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3504 ALCdevice_Unlock(device
);
3506 if(err
!= ALC_NO_ERROR
)
3507 alcSetError(device
, err
);
3509 if(device
) ALCdevice_DecRef(device
);
3513 /************************************************
3514 * ALC loopback functions
3515 ************************************************/
3517 /* alcLoopbackOpenDeviceSOFT
3519 * Open a loopback device, for manual rendering.
3521 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3523 ALCbackendFactory
*factory
;
3528 /* Make sure the device name, if specified, is us. */
3529 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3531 alcSetError(NULL
, ALC_INVALID_VALUE
);
3535 device
= al_calloc(16, sizeof(ALCdevice
));
3538 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3543 InitRef(&device
->ref
, 1);
3544 device
->Connected
= ALC_TRUE
;
3545 device
->Type
= Loopback
;
3546 device
->LastError
= ALC_NO_ERROR
;
3549 device
->Bs2b
= NULL
;
3550 device
->Bs2bLevel
= 0;
3551 AL_STRING_INIT(device
->DeviceName
);
3553 device
->ContextList
= NULL
;
3555 device
->ClockBase
= 0;
3556 device
->SamplesDone
= 0;
3558 device
->MaxNoOfSources
= 256;
3559 device
->AuxiliaryEffectSlotMax
= 4;
3560 device
->NumAuxSends
= MAX_SENDS
;
3562 InitUIntMap(&device
->BufferMap
, ~0);
3563 InitUIntMap(&device
->EffectMap
, ~0);
3564 InitUIntMap(&device
->FilterMap
, ~0);
3565 InitUIntMap(&device
->SfontMap
, ~0);
3566 InitUIntMap(&device
->PresetMap
, ~0);
3567 InitUIntMap(&device
->FontsoundMap
, ~0);
3569 factory
= ALCloopbackFactory_getFactory();
3570 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3571 if(!device
->Backend
)
3574 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3579 device
->NumUpdates
= 0;
3580 device
->UpdateSize
= 0;
3582 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3583 device
->FmtChans
= DevFmtChannelsDefault
;
3584 device
->FmtType
= DevFmtTypeDefault
;
3586 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3587 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3589 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3590 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3592 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3593 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3595 device
->NumStereoSources
= 1;
3596 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3598 device
->Synth
= SynthCreate(device
);
3601 DELETE_OBJ(device
->Backend
);
3603 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3607 // Open the "backend"
3608 V(device
->Backend
,open
)("Loopback");
3610 device
->next
= DeviceList
;
3611 } while(CompExchangePtr((XchgPtr
*)&DeviceList
, device
->next
, device
) != device
->next
);
3613 TRACE("Created device %p\n", device
);
3617 /* alcIsRenderFormatSupportedSOFT
3619 * Determines if the loopback device supports the given format for rendering.
3621 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3623 ALCboolean ret
= ALC_FALSE
;
3625 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3626 alcSetError(device
, ALC_INVALID_DEVICE
);
3628 alcSetError(device
, ALC_INVALID_VALUE
);
3631 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3632 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3633 freq
>= MIN_OUTPUT_RATE
)
3636 if(device
) ALCdevice_DecRef(device
);
3641 /* alcRenderSamplesSOFT
3643 * Renders some samples into a buffer, using the format last set by the
3644 * attributes given to alcCreateContext.
3646 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3648 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3649 alcSetError(device
, ALC_INVALID_DEVICE
);
3650 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3651 alcSetError(device
, ALC_INVALID_VALUE
);
3653 aluMixData(device
, buffer
, samples
);
3654 if(device
) ALCdevice_DecRef(device
);
3658 /************************************************
3659 * ALC DSP pause/resume functions
3660 ************************************************/
3662 /* alcDevicePauseSOFT
3664 * Pause the DSP to stop audio processing.
3666 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3668 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3669 alcSetError(device
, ALC_INVALID_DEVICE
);
3673 if((device
->Flags
&DEVICE_RUNNING
))
3674 V0(device
->Backend
,stop
)();
3675 device
->Flags
&= ~DEVICE_RUNNING
;
3676 device
->Flags
|= DEVICE_PAUSED
;
3679 if(device
) ALCdevice_DecRef(device
);
3682 /* alcDeviceResumeSOFT
3684 * Resume the DSP to restart audio processing.
3686 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3688 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3689 alcSetError(device
, ALC_INVALID_DEVICE
);
3693 if((device
->Flags
&DEVICE_PAUSED
))
3695 device
->Flags
&= ~DEVICE_PAUSED
;
3696 if(device
->ContextList
!= NULL
)
3698 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3699 device
->Flags
|= DEVICE_RUNNING
;
3702 alcSetError(device
, ALC_INVALID_DEVICE
);
3703 ALCdevice_Lock(device
);
3704 aluHandleDisconnect(device
);
3705 ALCdevice_Unlock(device
);
3711 if(device
) ALCdevice_DecRef(device
);