2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
32 #include "alListener.h"
36 #include "alAuxEffectSlot.h"
46 #include "backends/base.h"
47 #include "midi/base.h"
50 /************************************************
52 ************************************************/
55 ALCbackendFactory
* (*getFactory
)(void);
56 ALCboolean (*Init
)(BackendFuncs
*);
58 void (*Probe
)(enum DevProbe
);
62 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 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(alGetSoundfontivSOFT
),
297 DECL(alSoundfontPresetsSOFT
),
298 DECL(alGenPresetsSOFT
),
299 DECL(alDeletePresetsSOFT
),
300 DECL(alIsPresetSOFT
),
302 DECL(alPresetivSOFT
),
303 DECL(alGetPresetivSOFT
),
304 DECL(alPresetFontsoundsSOFT
),
305 DECL(alGenFontsoundsSOFT
),
306 DECL(alDeleteFontsoundsSOFT
),
307 DECL(alIsFontsoundSOFT
),
308 DECL(alFontsoundiSOFT
),
309 DECL(alFontsound2iSOFT
),
310 DECL(alFontsoundivSOFT
),
311 DECL(alGetFontsoundivSOFT
),
312 DECL(alFontsoundModulatoriSOFT
),
313 DECL(alGetFontsoundModulatorivSOFT
),
314 DECL(alMidiSoundfontSOFT
),
315 DECL(alMidiSoundfontvSOFT
),
316 DECL(alMidiEventSOFT
),
317 DECL(alMidiSysExSOFT
),
318 DECL(alMidiPlaySOFT
),
319 DECL(alMidiPauseSOFT
),
320 DECL(alMidiStopSOFT
),
321 DECL(alMidiResetSOFT
),
322 DECL(alMidiGainSOFT
),
323 DECL(alGetInteger64SOFT
),
324 DECL(alGetInteger64vSOFT
),
325 DECL(alLoadSoundfontSOFT
),
331 #define DECL(x) { #x, (x) }
332 static const ALCenums enumeration
[] = {
337 DECL(ALC_MAJOR_VERSION
),
338 DECL(ALC_MINOR_VERSION
),
339 DECL(ALC_ATTRIBUTES_SIZE
),
340 DECL(ALC_ALL_ATTRIBUTES
),
341 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
342 DECL(ALC_DEVICE_SPECIFIER
),
343 DECL(ALC_ALL_DEVICES_SPECIFIER
),
344 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
345 DECL(ALC_EXTENSIONS
),
349 DECL(ALC_MONO_SOURCES
),
350 DECL(ALC_STEREO_SOURCES
),
351 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
352 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
353 DECL(ALC_CAPTURE_SAMPLES
),
356 DECL(ALC_EFX_MAJOR_VERSION
),
357 DECL(ALC_EFX_MINOR_VERSION
),
358 DECL(ALC_MAX_AUXILIARY_SENDS
),
360 DECL(ALC_FORMAT_CHANNELS_SOFT
),
361 DECL(ALC_FORMAT_TYPE_SOFT
),
364 DECL(ALC_STEREO_SOFT
),
366 DECL(ALC_5POINT1_SOFT
),
367 DECL(ALC_6POINT1_SOFT
),
368 DECL(ALC_7POINT1_SOFT
),
371 DECL(ALC_UNSIGNED_BYTE_SOFT
),
372 DECL(ALC_SHORT_SOFT
),
373 DECL(ALC_UNSIGNED_SHORT_SOFT
),
375 DECL(ALC_UNSIGNED_INT_SOFT
),
376 DECL(ALC_FLOAT_SOFT
),
379 DECL(ALC_INVALID_DEVICE
),
380 DECL(ALC_INVALID_CONTEXT
),
381 DECL(ALC_INVALID_ENUM
),
382 DECL(ALC_INVALID_VALUE
),
383 DECL(ALC_OUT_OF_MEMORY
),
391 DECL(AL_SOURCE_RELATIVE
),
392 DECL(AL_CONE_INNER_ANGLE
),
393 DECL(AL_CONE_OUTER_ANGLE
),
403 DECL(AL_ORIENTATION
),
404 DECL(AL_REFERENCE_DISTANCE
),
405 DECL(AL_ROLLOFF_FACTOR
),
406 DECL(AL_CONE_OUTER_GAIN
),
407 DECL(AL_MAX_DISTANCE
),
409 DECL(AL_SAMPLE_OFFSET
),
410 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
411 DECL(AL_BYTE_OFFSET
),
412 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
413 DECL(AL_SOURCE_TYPE
),
416 DECL(AL_UNDETERMINED
),
417 DECL(AL_METERS_PER_UNIT
),
418 DECL(AL_DIRECT_CHANNELS_SOFT
),
420 DECL(AL_DIRECT_FILTER
),
421 DECL(AL_AUXILIARY_SEND_FILTER
),
422 DECL(AL_AIR_ABSORPTION_FACTOR
),
423 DECL(AL_ROOM_ROLLOFF_FACTOR
),
424 DECL(AL_CONE_OUTER_GAINHF
),
425 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
426 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
427 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
429 DECL(AL_SOURCE_STATE
),
435 DECL(AL_BUFFERS_QUEUED
),
436 DECL(AL_BUFFERS_PROCESSED
),
438 DECL(AL_FORMAT_MONO8
),
439 DECL(AL_FORMAT_MONO16
),
440 DECL(AL_FORMAT_MONO_FLOAT32
),
441 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
442 DECL(AL_FORMAT_STEREO8
),
443 DECL(AL_FORMAT_STEREO16
),
444 DECL(AL_FORMAT_STEREO_FLOAT32
),
445 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
446 DECL(AL_FORMAT_MONO_IMA4
),
447 DECL(AL_FORMAT_STEREO_IMA4
),
448 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
449 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
450 DECL(AL_FORMAT_QUAD8_LOKI
),
451 DECL(AL_FORMAT_QUAD16_LOKI
),
452 DECL(AL_FORMAT_QUAD8
),
453 DECL(AL_FORMAT_QUAD16
),
454 DECL(AL_FORMAT_QUAD32
),
455 DECL(AL_FORMAT_51CHN8
),
456 DECL(AL_FORMAT_51CHN16
),
457 DECL(AL_FORMAT_51CHN32
),
458 DECL(AL_FORMAT_61CHN8
),
459 DECL(AL_FORMAT_61CHN16
),
460 DECL(AL_FORMAT_61CHN32
),
461 DECL(AL_FORMAT_71CHN8
),
462 DECL(AL_FORMAT_71CHN16
),
463 DECL(AL_FORMAT_71CHN32
),
464 DECL(AL_FORMAT_REAR8
),
465 DECL(AL_FORMAT_REAR16
),
466 DECL(AL_FORMAT_REAR32
),
467 DECL(AL_FORMAT_MONO_MULAW
),
468 DECL(AL_FORMAT_MONO_MULAW_EXT
),
469 DECL(AL_FORMAT_STEREO_MULAW
),
470 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
471 DECL(AL_FORMAT_QUAD_MULAW
),
472 DECL(AL_FORMAT_51CHN_MULAW
),
473 DECL(AL_FORMAT_61CHN_MULAW
),
474 DECL(AL_FORMAT_71CHN_MULAW
),
475 DECL(AL_FORMAT_REAR_MULAW
),
476 DECL(AL_FORMAT_MONO_ALAW_EXT
),
477 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
480 DECL(AL_MONO16_SOFT
),
481 DECL(AL_MONO32F_SOFT
),
482 DECL(AL_STEREO8_SOFT
),
483 DECL(AL_STEREO16_SOFT
),
484 DECL(AL_STEREO32F_SOFT
),
486 DECL(AL_QUAD16_SOFT
),
487 DECL(AL_QUAD32F_SOFT
),
489 DECL(AL_REAR16_SOFT
),
490 DECL(AL_REAR32F_SOFT
),
491 DECL(AL_5POINT1_8_SOFT
),
492 DECL(AL_5POINT1_16_SOFT
),
493 DECL(AL_5POINT1_32F_SOFT
),
494 DECL(AL_6POINT1_8_SOFT
),
495 DECL(AL_6POINT1_16_SOFT
),
496 DECL(AL_6POINT1_32F_SOFT
),
497 DECL(AL_7POINT1_8_SOFT
),
498 DECL(AL_7POINT1_16_SOFT
),
499 DECL(AL_7POINT1_32F_SOFT
),
502 DECL(AL_STEREO_SOFT
),
505 DECL(AL_5POINT1_SOFT
),
506 DECL(AL_6POINT1_SOFT
),
507 DECL(AL_7POINT1_SOFT
),
510 DECL(AL_UNSIGNED_BYTE_SOFT
),
512 DECL(AL_UNSIGNED_SHORT_SOFT
),
514 DECL(AL_UNSIGNED_INT_SOFT
),
516 DECL(AL_DOUBLE_SOFT
),
518 DECL(AL_UNSIGNED_BYTE3_SOFT
),
524 DECL(AL_INTERNAL_FORMAT_SOFT
),
525 DECL(AL_BYTE_LENGTH_SOFT
),
526 DECL(AL_SAMPLE_LENGTH_SOFT
),
527 DECL(AL_SEC_LENGTH_SOFT
),
528 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
529 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
536 DECL(AL_INVALID_NAME
),
537 DECL(AL_INVALID_ENUM
),
538 DECL(AL_INVALID_VALUE
),
539 DECL(AL_INVALID_OPERATION
),
540 DECL(AL_OUT_OF_MEMORY
),
547 DECL(AL_DOPPLER_FACTOR
),
548 DECL(AL_DOPPLER_VELOCITY
),
549 DECL(AL_DISTANCE_MODEL
),
550 DECL(AL_SPEED_OF_SOUND
),
551 DECL(AL_SOURCE_DISTANCE_MODEL
),
552 DECL(AL_DEFERRED_UPDATES_SOFT
),
554 DECL(AL_INVERSE_DISTANCE
),
555 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
556 DECL(AL_LINEAR_DISTANCE
),
557 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
558 DECL(AL_EXPONENT_DISTANCE
),
559 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
561 DECL(AL_FILTER_TYPE
),
562 DECL(AL_FILTER_NULL
),
563 DECL(AL_FILTER_LOWPASS
),
564 DECL(AL_FILTER_HIGHPASS
),
565 DECL(AL_FILTER_BANDPASS
),
567 DECL(AL_LOWPASS_GAIN
),
568 DECL(AL_LOWPASS_GAINHF
),
570 DECL(AL_HIGHPASS_GAIN
),
571 DECL(AL_HIGHPASS_GAINLF
),
573 DECL(AL_BANDPASS_GAIN
),
574 DECL(AL_BANDPASS_GAINHF
),
575 DECL(AL_BANDPASS_GAINLF
),
577 DECL(AL_EFFECT_TYPE
),
578 DECL(AL_EFFECT_NULL
),
579 DECL(AL_EFFECT_REVERB
),
580 DECL(AL_EFFECT_EAXREVERB
),
581 DECL(AL_EFFECT_CHORUS
),
582 DECL(AL_EFFECT_DISTORTION
),
583 DECL(AL_EFFECT_ECHO
),
584 DECL(AL_EFFECT_FLANGER
),
586 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
587 DECL(AL_EFFECT_VOCAL_MORPHER
),
588 DECL(AL_EFFECT_PITCH_SHIFTER
),
590 DECL(AL_EFFECT_RING_MODULATOR
),
592 DECL(AL_EFFECT_AUTOWAH
),
594 DECL(AL_EFFECT_COMPRESSOR
),
595 DECL(AL_EFFECT_EQUALIZER
),
596 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
597 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
599 DECL(AL_EAXREVERB_DENSITY
),
600 DECL(AL_EAXREVERB_DIFFUSION
),
601 DECL(AL_EAXREVERB_GAIN
),
602 DECL(AL_EAXREVERB_GAINHF
),
603 DECL(AL_EAXREVERB_GAINLF
),
604 DECL(AL_EAXREVERB_DECAY_TIME
),
605 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
606 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
607 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
608 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
609 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
610 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
611 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
612 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
613 DECL(AL_EAXREVERB_ECHO_TIME
),
614 DECL(AL_EAXREVERB_ECHO_DEPTH
),
615 DECL(AL_EAXREVERB_MODULATION_TIME
),
616 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
617 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
618 DECL(AL_EAXREVERB_HFREFERENCE
),
619 DECL(AL_EAXREVERB_LFREFERENCE
),
620 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
621 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
623 DECL(AL_REVERB_DENSITY
),
624 DECL(AL_REVERB_DIFFUSION
),
625 DECL(AL_REVERB_GAIN
),
626 DECL(AL_REVERB_GAINHF
),
627 DECL(AL_REVERB_DECAY_TIME
),
628 DECL(AL_REVERB_DECAY_HFRATIO
),
629 DECL(AL_REVERB_REFLECTIONS_GAIN
),
630 DECL(AL_REVERB_REFLECTIONS_DELAY
),
631 DECL(AL_REVERB_LATE_REVERB_GAIN
),
632 DECL(AL_REVERB_LATE_REVERB_DELAY
),
633 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
634 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
635 DECL(AL_REVERB_DECAY_HFLIMIT
),
637 DECL(AL_CHORUS_WAVEFORM
),
638 DECL(AL_CHORUS_PHASE
),
639 DECL(AL_CHORUS_RATE
),
640 DECL(AL_CHORUS_DEPTH
),
641 DECL(AL_CHORUS_FEEDBACK
),
642 DECL(AL_CHORUS_DELAY
),
644 DECL(AL_DISTORTION_EDGE
),
645 DECL(AL_DISTORTION_GAIN
),
646 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
647 DECL(AL_DISTORTION_EQCENTER
),
648 DECL(AL_DISTORTION_EQBANDWIDTH
),
651 DECL(AL_ECHO_LRDELAY
),
652 DECL(AL_ECHO_DAMPING
),
653 DECL(AL_ECHO_FEEDBACK
),
654 DECL(AL_ECHO_SPREAD
),
656 DECL(AL_FLANGER_WAVEFORM
),
657 DECL(AL_FLANGER_PHASE
),
658 DECL(AL_FLANGER_RATE
),
659 DECL(AL_FLANGER_DEPTH
),
660 DECL(AL_FLANGER_FEEDBACK
),
661 DECL(AL_FLANGER_DELAY
),
663 DECL(AL_RING_MODULATOR_FREQUENCY
),
664 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
665 DECL(AL_RING_MODULATOR_WAVEFORM
),
668 DECL(AL_AUTOWAH_ATTACK_TIME
),
669 DECL(AL_AUTOWAH_PEAK_GAIN
),
670 DECL(AL_AUTOWAH_RELEASE_TIME
),
671 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_SOFT_MSADPCM AL_SOFT_source_latency "
723 "AL_SOFT_source_length";
725 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
727 /* Thread-local current context */
728 static altss_t LocalContext
;
729 /* Process-wide current context */
730 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(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_SOFT_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 ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(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
=ATOMIC_EXCHANGE(ALCdevice
*, &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 ATOMIC_STORE(&device
->LastError
, errorCode
);
1567 ATOMIC_STORE(&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 bool usehrtf
= !!(device
->Flags
&DEVICE_HRTF_REQUEST
);
1786 if(GetConfigValueBool(NULL
, "hrtf", usehrtf
))
1787 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1789 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1791 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1793 enum DevFmtChannels chans
= device
->FmtChans
;
1794 ALCuint freq
= device
->Frequency
;
1795 if(FindHrtfFormat(&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
->FmtChans
, device
->Frequency
);
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
= ATOMIC_LOAD(&device
->ContextList
);
1889 ATOMIC_STORE(&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 ATOMIC_STORE(&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 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
1923 UnlockUIntMapRead(&context
->SourceMap
);
1925 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
1927 ALvoice
*voice
= &context
->Voices
[pos
];
1928 ALsource
*source
= voice
->Source
;
1929 ALuint s
= device
->NumAuxSends
;
1931 while(s
< MAX_SENDS
)
1933 voice
->Send
[s
].Moving
= AL_FALSE
;
1934 voice
->Send
[s
].Counter
= 0;
1940 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
1941 voice
->Update(voice
, source
, context
);
1945 context
= context
->next
;
1947 if(device
->DefaultSlot
)
1949 ALeffectslot
*slot
= device
->DefaultSlot
;
1951 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
1953 ALCdevice_Unlock(device
);
1954 RestoreFPUMode(&oldMode
);
1955 return ALC_INVALID_DEVICE
;
1957 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
1958 V(slot
->EffectState
,update
)(device
, slot
);
1960 ALCdevice_Unlock(device
);
1961 RestoreFPUMode(&oldMode
);
1963 if(!(device
->Flags
&DEVICE_PAUSED
))
1965 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
1966 return ALC_INVALID_DEVICE
;
1967 device
->Flags
|= DEVICE_RUNNING
;
1970 return ALC_NO_ERROR
;
1975 * Frees the device structure, and destroys any objects the app failed to
1976 * delete. Called once there's no more references on the device.
1978 static ALCvoid
FreeDevice(ALCdevice
*device
)
1980 TRACE("%p\n", device
);
1982 V0(device
->Backend
,close
)();
1983 DELETE_OBJ(device
->Backend
);
1984 device
->Backend
= NULL
;
1986 DELETE_OBJ(device
->Synth
);
1987 device
->Synth
= NULL
;
1989 if(device
->DefaultSlot
)
1991 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
1992 device
->DefaultSlot
= NULL
;
1996 if(device
->DefaultSfont
)
1997 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
1998 device
->DefaultSfont
= NULL
;
2000 if(device
->BufferMap
.size
> 0)
2002 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2003 ReleaseALBuffers(device
);
2005 ResetUIntMap(&device
->BufferMap
);
2007 if(device
->EffectMap
.size
> 0)
2009 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2010 ReleaseALEffects(device
);
2012 ResetUIntMap(&device
->EffectMap
);
2014 if(device
->FilterMap
.size
> 0)
2016 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2017 ReleaseALFilters(device
);
2019 ResetUIntMap(&device
->FilterMap
);
2021 if(device
->SfontMap
.size
> 0)
2023 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2024 ReleaseALSoundfonts(device
);
2026 ResetUIntMap(&device
->SfontMap
);
2028 if(device
->PresetMap
.size
> 0)
2030 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2031 ReleaseALPresets(device
);
2033 ResetUIntMap(&device
->PresetMap
);
2035 if(device
->FontsoundMap
.size
> 0)
2037 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2038 ReleaseALFontsounds(device
);
2040 ResetUIntMap(&device
->FontsoundMap
);
2043 device
->Bs2b
= NULL
;
2045 AL_STRING_DEINIT(device
->DeviceName
);
2051 void ALCdevice_IncRef(ALCdevice
*device
)
2054 ref
= IncrementRef(&device
->ref
);
2055 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2058 void ALCdevice_DecRef(ALCdevice
*device
)
2061 ref
= DecrementRef(&device
->ref
);
2062 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2063 if(ref
== 0) FreeDevice(device
);
2068 * Checks if the device handle is valid, and increments its ref count if so.
2070 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2072 ALCdevice
*tmpDevice
;
2078 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2079 while(tmpDevice
&& tmpDevice
!= device
)
2080 tmpDevice
= tmpDevice
->next
;
2083 ALCdevice_IncRef(tmpDevice
);
2091 * Initializes context fields
2093 static ALvoid
InitContext(ALCcontext
*Context
)
2097 //Initialise listener
2098 Context
->Listener
->Gain
= 1.0f
;
2099 Context
->Listener
->MetersPerUnit
= 1.0f
;
2100 Context
->Listener
->Position
[0] = 0.0f
;
2101 Context
->Listener
->Position
[1] = 0.0f
;
2102 Context
->Listener
->Position
[2] = 0.0f
;
2103 Context
->Listener
->Velocity
[0] = 0.0f
;
2104 Context
->Listener
->Velocity
[1] = 0.0f
;
2105 Context
->Listener
->Velocity
[2] = 0.0f
;
2106 Context
->Listener
->Forward
[0] = 0.0f
;
2107 Context
->Listener
->Forward
[1] = 0.0f
;
2108 Context
->Listener
->Forward
[2] = -1.0f
;
2109 Context
->Listener
->Up
[0] = 0.0f
;
2110 Context
->Listener
->Up
[1] = 1.0f
;
2111 Context
->Listener
->Up
[2] = 0.0f
;
2112 for(i
= 0;i
< 4;i
++)
2114 for(j
= 0;j
< 4;j
++)
2115 Context
->Listener
->Params
.Matrix
[i
][j
] = ((i
==j
) ? 1.0f
: 0.0f
);
2117 for(i
= 0;i
< 3;i
++)
2118 Context
->Listener
->Params
.Velocity
[i
] = 0.0f
;
2121 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2122 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2123 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2124 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2127 Context
->DistanceModel
= DefaultDistanceModel
;
2128 Context
->SourceDistanceModel
= AL_FALSE
;
2129 Context
->DopplerFactor
= 1.0f
;
2130 Context
->DopplerVelocity
= 1.0f
;
2131 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2132 Context
->DeferUpdates
= AL_FALSE
;
2134 Context
->ExtensionList
= alExtList
;
2140 * Cleans up the context, and destroys any remaining objects the app failed to
2141 * delete. Called once there's no more references on the context.
2143 static void FreeContext(ALCcontext
*context
)
2145 TRACE("%p\n", context
);
2147 if(context
->SourceMap
.size
> 0)
2149 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2150 ReleaseALSources(context
);
2152 ResetUIntMap(&context
->SourceMap
);
2154 if(context
->EffectSlotMap
.size
> 0)
2156 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2157 ReleaseALAuxiliaryEffectSlots(context
);
2159 ResetUIntMap(&context
->EffectSlotMap
);
2161 free(context
->Voices
);
2162 context
->Voices
= NULL
;
2163 context
->VoiceCount
= 0;
2164 context
->MaxVoices
= 0;
2166 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2168 ALCdevice_DecRef(context
->Device
);
2169 context
->Device
= NULL
;
2171 //Invalidate context
2172 memset(context
, 0, sizeof(ALCcontext
));
2178 * Removes the context reference from the given device and removes it from
2179 * being current on the running thread or globally.
2181 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2183 ALCcontext
*nextctx
;
2184 ALCcontext
*origctx
;
2186 if(altss_get(LocalContext
) == context
)
2188 WARN("%p released while current on thread\n", context
);
2189 altss_set(LocalContext
, NULL
);
2190 ALCcontext_DecRef(context
);
2194 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2195 ALCcontext_DecRef(context
);
2197 ALCdevice_Lock(device
);
2199 nextctx
= context
->next
;
2200 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2206 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2208 ALCdevice_Unlock(device
);
2210 ALCcontext_DecRef(context
);
2213 void ALCcontext_IncRef(ALCcontext
*context
)
2216 ref
= IncrementRef(&context
->ref
);
2217 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2220 void ALCcontext_DecRef(ALCcontext
*context
)
2223 ref
= DecrementRef(&context
->ref
);
2224 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2225 if(ref
== 0) FreeContext(context
);
2228 static void ReleaseThreadCtx(void *ptr
)
2230 WARN("%p current for thread being destroyed\n", ptr
);
2231 ALCcontext_DecRef(ptr
);
2236 * Checks that the given context is valid, and increments its reference count.
2238 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2243 dev
= ATOMIC_LOAD(&DeviceList
);
2246 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2251 ALCcontext_IncRef(ctx
);
2267 * Returns the currently active context for this thread, and adds a reference
2268 * without locking it.
2270 ALCcontext
*GetContextRef(void)
2272 ALCcontext
*context
;
2274 context
= altss_get(LocalContext
);
2276 ALCcontext_IncRef(context
);
2280 context
= ATOMIC_LOAD(&GlobalContext
);
2282 ALCcontext_IncRef(context
);
2290 /************************************************
2291 * Standard ALC functions
2292 ************************************************/
2296 * Return last ALC generated error code for the given device
2298 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2302 if(VerifyDevice(device
))
2304 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2305 ALCdevice_DecRef(device
);
2308 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2314 /* alcSuspendContext
2318 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*UNUSED(context
))
2322 /* alcProcessContext
2326 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*UNUSED(context
))
2333 * Returns information about the device, and error strings
2335 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2337 const ALCchar
*value
= NULL
;
2345 case ALC_INVALID_ENUM
:
2346 value
= alcErrInvalidEnum
;
2349 case ALC_INVALID_VALUE
:
2350 value
= alcErrInvalidValue
;
2353 case ALC_INVALID_DEVICE
:
2354 value
= alcErrInvalidDevice
;
2357 case ALC_INVALID_CONTEXT
:
2358 value
= alcErrInvalidContext
;
2361 case ALC_OUT_OF_MEMORY
:
2362 value
= alcErrOutOfMemory
;
2365 case ALC_DEVICE_SPECIFIER
:
2366 value
= alcDefaultName
;
2369 case ALC_ALL_DEVICES_SPECIFIER
:
2370 if(VerifyDevice(Device
))
2372 value
= al_string_get_cstr(Device
->DeviceName
);
2373 ALCdevice_DecRef(Device
);
2377 ProbeAllDevicesList();
2378 value
= al_string_get_cstr(alcAllDevicesList
);
2382 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2383 if(VerifyDevice(Device
))
2385 value
= al_string_get_cstr(Device
->DeviceName
);
2386 ALCdevice_DecRef(Device
);
2390 ProbeCaptureDeviceList();
2391 value
= al_string_get_cstr(alcCaptureDeviceList
);
2395 /* Default devices are always first in the list */
2396 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2397 value
= alcDefaultName
;
2400 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2401 if(al_string_empty(alcAllDevicesList
))
2402 ProbeAllDevicesList();
2404 Device
= VerifyDevice(Device
);
2406 free(alcDefaultAllDevicesSpecifier
);
2407 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2408 if(!alcDefaultAllDevicesSpecifier
)
2409 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2411 value
= alcDefaultAllDevicesSpecifier
;
2412 if(Device
) ALCdevice_DecRef(Device
);
2415 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2416 if(al_string_empty(alcCaptureDeviceList
))
2417 ProbeCaptureDeviceList();
2419 Device
= VerifyDevice(Device
);
2421 free(alcCaptureDefaultDeviceSpecifier
);
2422 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2423 if(!alcCaptureDefaultDeviceSpecifier
)
2424 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2426 value
= alcCaptureDefaultDeviceSpecifier
;
2427 if(Device
) ALCdevice_DecRef(Device
);
2430 case ALC_EXTENSIONS
:
2431 if(!VerifyDevice(Device
))
2432 value
= alcNoDeviceExtList
;
2435 value
= alcExtensionList
;
2436 ALCdevice_DecRef(Device
);
2441 Device
= VerifyDevice(Device
);
2442 alcSetError(Device
, ALC_INVALID_ENUM
);
2443 if(Device
) ALCdevice_DecRef(Device
);
2451 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2455 if(size
<= 0 || values
== NULL
)
2457 alcSetError(device
, ALC_INVALID_VALUE
);
2465 case ALC_MAJOR_VERSION
:
2466 values
[0] = alcMajorVersion
;
2468 case ALC_MINOR_VERSION
:
2469 values
[0] = alcMinorVersion
;
2472 case ALC_ATTRIBUTES_SIZE
:
2473 case ALC_ALL_ATTRIBUTES
:
2477 case ALC_MONO_SOURCES
:
2478 case ALC_STEREO_SOURCES
:
2479 case ALC_CAPTURE_SAMPLES
:
2480 case ALC_FORMAT_CHANNELS_SOFT
:
2481 case ALC_FORMAT_TYPE_SOFT
:
2482 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2486 alcSetError(NULL
, ALC_INVALID_ENUM
);
2492 if(device
->Type
== Capture
)
2496 case ALC_CAPTURE_SAMPLES
:
2497 ALCdevice_Lock(device
);
2498 values
[0] = V0(device
->Backend
,availableSamples
)();
2499 ALCdevice_Unlock(device
);
2503 values
[0] = device
->Connected
;
2507 alcSetError(device
, ALC_INVALID_ENUM
);
2516 case ALC_MAJOR_VERSION
:
2517 values
[0] = alcMajorVersion
;
2520 case ALC_MINOR_VERSION
:
2521 values
[0] = alcMinorVersion
;
2524 case ALC_EFX_MAJOR_VERSION
:
2525 values
[0] = alcEFXMajorVersion
;
2528 case ALC_EFX_MINOR_VERSION
:
2529 values
[0] = alcEFXMinorVersion
;
2532 case ALC_ATTRIBUTES_SIZE
:
2536 case ALC_ALL_ATTRIBUTES
:
2539 alcSetError(device
, ALC_INVALID_VALUE
);
2544 values
[i
++] = ALC_FREQUENCY
;
2545 values
[i
++] = device
->Frequency
;
2547 if(device
->Type
!= Loopback
)
2549 values
[i
++] = ALC_REFRESH
;
2550 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2552 values
[i
++] = ALC_SYNC
;
2553 values
[i
++] = ALC_FALSE
;
2557 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2558 values
[i
++] = device
->FmtChans
;
2560 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2561 values
[i
++] = device
->FmtType
;
2564 values
[i
++] = ALC_MONO_SOURCES
;
2565 values
[i
++] = device
->NumMonoSources
;
2567 values
[i
++] = ALC_STEREO_SOURCES
;
2568 values
[i
++] = device
->NumStereoSources
;
2570 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2571 values
[i
++] = device
->NumAuxSends
;
2573 values
[i
++] = ALC_HRTF_SOFT
;
2574 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2580 values
[0] = device
->Frequency
;
2584 if(device
->Type
== Loopback
)
2586 alcSetError(device
, ALC_INVALID_DEVICE
);
2589 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2593 if(device
->Type
== Loopback
)
2595 alcSetError(device
, ALC_INVALID_DEVICE
);
2598 values
[0] = ALC_FALSE
;
2601 case ALC_FORMAT_CHANNELS_SOFT
:
2602 if(device
->Type
!= Loopback
)
2604 alcSetError(device
, ALC_INVALID_DEVICE
);
2607 values
[0] = device
->FmtChans
;
2610 case ALC_FORMAT_TYPE_SOFT
:
2611 if(device
->Type
!= Loopback
)
2613 alcSetError(device
, ALC_INVALID_DEVICE
);
2616 values
[0] = device
->FmtType
;
2619 case ALC_MONO_SOURCES
:
2620 values
[0] = device
->NumMonoSources
;
2623 case ALC_STEREO_SOURCES
:
2624 values
[0] = device
->NumStereoSources
;
2627 case ALC_MAX_AUXILIARY_SENDS
:
2628 values
[0] = device
->NumAuxSends
;
2632 values
[0] = device
->Connected
;
2636 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2640 alcSetError(device
, ALC_INVALID_ENUM
);
2648 * Returns information about the device and the version of OpenAL
2650 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2652 device
= VerifyDevice(device
);
2653 if(size
<= 0 || values
== NULL
)
2654 alcSetError(device
, ALC_INVALID_VALUE
);
2656 GetIntegerv(device
, param
, size
, values
);
2657 if(device
) ALCdevice_DecRef(device
);
2660 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2665 device
= VerifyDevice(device
);
2666 if(size
<= 0 || values
== NULL
)
2667 alcSetError(device
, ALC_INVALID_VALUE
);
2668 else if(!device
|| device
->Type
== Capture
)
2670 ivals
= malloc(size
* sizeof(ALCint
));
2671 size
= GetIntegerv(device
, pname
, size
, ivals
);
2672 for(i
= 0;i
< size
;i
++)
2673 values
[i
] = ivals
[i
];
2676 else /* render device */
2680 case ALC_ATTRIBUTES_SIZE
:
2684 case ALC_ALL_ATTRIBUTES
:
2686 alcSetError(device
, ALC_INVALID_VALUE
);
2691 V0(device
->Backend
,lock
)();
2692 values
[i
++] = ALC_FREQUENCY
;
2693 values
[i
++] = device
->Frequency
;
2695 if(device
->Type
!= Loopback
)
2697 values
[i
++] = ALC_REFRESH
;
2698 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2700 values
[i
++] = ALC_SYNC
;
2701 values
[i
++] = ALC_FALSE
;
2705 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2706 values
[i
++] = device
->FmtChans
;
2708 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2709 values
[i
++] = device
->FmtType
;
2712 values
[i
++] = ALC_MONO_SOURCES
;
2713 values
[i
++] = device
->NumMonoSources
;
2715 values
[i
++] = ALC_STEREO_SOURCES
;
2716 values
[i
++] = device
->NumStereoSources
;
2718 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2719 values
[i
++] = device
->NumAuxSends
;
2721 values
[i
++] = ALC_HRTF_SOFT
;
2722 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2724 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2725 values
[i
++] = device
->ClockBase
+
2726 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2729 V0(device
->Backend
,unlock
)();
2733 case ALC_DEVICE_CLOCK_SOFT
:
2734 V0(device
->Backend
,lock
)();
2735 *values
= device
->ClockBase
+
2736 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2737 V0(device
->Backend
,unlock
)();
2741 ivals
= malloc(size
* sizeof(ALCint
));
2742 size
= GetIntegerv(device
, pname
, size
, ivals
);
2743 for(i
= 0;i
< size
;i
++)
2744 values
[i
] = ivals
[i
];
2750 ALCdevice_DecRef(device
);
2754 /* alcIsExtensionPresent
2756 * Determines if there is support for a particular extension
2758 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2760 ALCboolean bResult
= ALC_FALSE
;
2762 device
= VerifyDevice(device
);
2765 alcSetError(device
, ALC_INVALID_VALUE
);
2768 size_t len
= strlen(extName
);
2769 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2772 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2773 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2778 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2782 } while(isspace(*ptr
));
2787 ALCdevice_DecRef(device
);
2792 /* alcGetProcAddress
2794 * Retrieves the function address for a particular extension function
2796 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2798 ALCvoid
*ptr
= NULL
;
2802 device
= VerifyDevice(device
);
2803 alcSetError(device
, ALC_INVALID_VALUE
);
2804 if(device
) ALCdevice_DecRef(device
);
2809 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2811 ptr
= alcFunctions
[i
].address
;
2820 * Get the value for a particular ALC enumeration name
2822 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
2828 device
= VerifyDevice(device
);
2829 alcSetError(device
, ALC_INVALID_VALUE
);
2830 if(device
) ALCdevice_DecRef(device
);
2835 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
2837 val
= enumeration
[i
].value
;
2846 * Create and attach a context to the given device.
2848 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
2850 ALCcontext
*ALContext
;
2854 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
2857 alcSetError(device
, ALC_INVALID_DEVICE
);
2858 if(device
) ALCdevice_DecRef(device
);
2862 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
2864 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
2867 alcSetError(device
, err
);
2868 if(err
== ALC_INVALID_DEVICE
)
2870 ALCdevice_Lock(device
);
2871 aluHandleDisconnect(device
);
2872 ALCdevice_Unlock(device
);
2874 ALCdevice_DecRef(device
);
2878 ALContext
= calloc(1, sizeof(ALCcontext
)+sizeof(ALlistener
));
2881 InitRef(&ALContext
->ref
, 1);
2882 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
2884 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
2886 ALContext
->VoiceCount
= 0;
2887 ALContext
->MaxVoices
= 256;
2888 ALContext
->Voices
= calloc(ALContext
->MaxVoices
, sizeof(ALContext
->Voices
[0]));
2890 if(!ALContext
|| !ALContext
->Voices
)
2892 if(!ATOMIC_LOAD(&device
->ContextList
))
2894 V0(device
->Backend
,stop
)();
2895 device
->Flags
&= ~DEVICE_RUNNING
;
2901 free(ALContext
->Voices
);
2902 ALContext
->Voices
= NULL
;
2904 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
2910 alcSetError(device
, ALC_OUT_OF_MEMORY
);
2911 ALCdevice_DecRef(device
);
2915 ALContext
->Device
= device
;
2916 ALCdevice_IncRef(device
);
2917 InitContext(ALContext
);
2920 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
2922 ALContext
->next
= head
;
2923 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
2927 ALCdevice_DecRef(device
);
2929 TRACE("Created context %p\n", ALContext
);
2933 /* alcDestroyContext
2935 * Remove a context from its device
2937 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
2942 /* alcGetContextsDevice sets an error for invalid contexts */
2943 Device
= alcGetContextsDevice(context
);
2946 ReleaseContext(context
, Device
);
2947 if(!ATOMIC_LOAD(&Device
->ContextList
))
2949 V0(Device
->Backend
,stop
)();
2950 Device
->Flags
&= ~DEVICE_RUNNING
;
2957 /* alcGetCurrentContext
2959 * Returns the currently active context on the calling thread
2961 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
2963 ALCcontext
*Context
= altss_get(LocalContext
);
2964 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
2968 /* alcGetThreadContext
2970 * Returns the currently active thread-local context
2972 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
2974 return altss_get(LocalContext
);
2978 /* alcMakeContextCurrent
2980 * Makes the given context the active process-wide context, and removes the
2981 * thread-local context for the calling thread.
2983 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
2985 /* context must be valid or NULL */
2986 if(context
&& !(context
=VerifyContext(context
)))
2988 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2991 /* context's reference count is already incremented */
2992 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
2993 if(context
) ALCcontext_DecRef(context
);
2995 if((context
=altss_get(LocalContext
)) != NULL
)
2997 altss_set(LocalContext
, NULL
);
2998 ALCcontext_DecRef(context
);
3004 /* alcSetThreadContext
3006 * Makes the given context the active context for the current thread
3008 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3012 /* context must be valid or NULL */
3013 if(context
&& !(context
=VerifyContext(context
)))
3015 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3018 /* context's reference count is already incremented */
3019 old
= altss_get(LocalContext
);
3020 altss_set(LocalContext
, context
);
3021 if(old
) ALCcontext_DecRef(old
);
3027 /* alcGetContextsDevice
3029 * Returns the device that a particular context is attached to
3031 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3035 if(!(Context
=VerifyContext(Context
)))
3037 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3040 Device
= Context
->Device
;
3041 ALCcontext_DecRef(Context
);
3049 * Opens the named device.
3051 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3059 if(!PlaybackBackend
.name
)
3061 alcSetError(NULL
, ALC_INVALID_VALUE
);
3065 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3068 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3071 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3076 InitRef(&device
->ref
, 1);
3077 device
->Connected
= ALC_TRUE
;
3078 device
->Type
= Playback
;
3079 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3082 device
->Bs2b
= NULL
;
3083 device
->Bs2bLevel
= 0;
3084 AL_STRING_INIT(device
->DeviceName
);
3086 ATOMIC_INIT(&device
->ContextList
, NULL
);
3088 device
->ClockBase
= 0;
3089 device
->SamplesDone
= 0;
3091 device
->MaxNoOfSources
= 256;
3092 device
->AuxiliaryEffectSlotMax
= 4;
3093 device
->NumAuxSends
= MAX_SENDS
;
3095 InitUIntMap(&device
->BufferMap
, ~0);
3096 InitUIntMap(&device
->EffectMap
, ~0);
3097 InitUIntMap(&device
->FilterMap
, ~0);
3098 InitUIntMap(&device
->SfontMap
, ~0);
3099 InitUIntMap(&device
->PresetMap
, ~0);
3100 InitUIntMap(&device
->FontsoundMap
, ~0);
3103 device
->FmtChans
= DevFmtChannelsDefault
;
3104 device
->FmtType
= DevFmtTypeDefault
;
3105 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3106 device
->NumUpdates
= 4;
3107 device
->UpdateSize
= 1024;
3109 if(!PlaybackBackend
.getFactory
)
3110 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3111 ALCbackend_Playback
);
3114 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3115 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3117 if(!device
->Backend
)
3120 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3125 if(ConfigValueStr(NULL
, "channels", &fmt
))
3127 static const struct {
3128 const char name
[16];
3129 enum DevFmtChannels chans
;
3131 { "mono", DevFmtMono
},
3132 { "stereo", DevFmtStereo
},
3133 { "quad", DevFmtQuad
},
3134 { "surround51", DevFmtX51
},
3135 { "surround61", DevFmtX61
},
3136 { "surround71", DevFmtX71
},
3140 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3142 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3144 device
->FmtChans
= chanlist
[i
].chans
;
3145 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3149 if(i
== COUNTOF(chanlist
))
3150 ERR("Unsupported channels: %s\n", fmt
);
3152 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3154 static const struct {
3155 const char name
[16];
3156 enum DevFmtType type
;
3158 { "int8", DevFmtByte
},
3159 { "uint8", DevFmtUByte
},
3160 { "int16", DevFmtShort
},
3161 { "uint16", DevFmtUShort
},
3162 { "int32", DevFmtInt
},
3163 { "uint32", DevFmtUInt
},
3164 { "float32", DevFmtFloat
},
3168 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3170 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3172 device
->FmtType
= typelist
[i
].type
;
3173 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3177 if(i
== COUNTOF(typelist
))
3178 ERR("Unsupported sample-type: %s\n", fmt
);
3180 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3181 if((device
->Flags
&DEVICE_FORMAT_REQUEST
) != DEVICE_FORMAT_REQUEST
&&
3182 ConfigValueStr(NULL
, "format", &fmt
))
3184 static const struct {
3185 const char name
[32];
3186 enum DevFmtChannels channels
;
3187 enum DevFmtType type
;
3189 { "AL_FORMAT_MONO32", DevFmtMono
, DevFmtFloat
},
3190 { "AL_FORMAT_STEREO32", DevFmtStereo
, DevFmtFloat
},
3191 { "AL_FORMAT_QUAD32", DevFmtQuad
, DevFmtFloat
},
3192 { "AL_FORMAT_51CHN32", DevFmtX51
, DevFmtFloat
},
3193 { "AL_FORMAT_61CHN32", DevFmtX61
, DevFmtFloat
},
3194 { "AL_FORMAT_71CHN32", DevFmtX71
, DevFmtFloat
},
3196 { "AL_FORMAT_MONO16", DevFmtMono
, DevFmtShort
},
3197 { "AL_FORMAT_STEREO16", DevFmtStereo
, DevFmtShort
},
3198 { "AL_FORMAT_QUAD16", DevFmtQuad
, DevFmtShort
},
3199 { "AL_FORMAT_51CHN16", DevFmtX51
, DevFmtShort
},
3200 { "AL_FORMAT_61CHN16", DevFmtX61
, DevFmtShort
},
3201 { "AL_FORMAT_71CHN16", DevFmtX71
, DevFmtShort
},
3203 { "AL_FORMAT_MONO8", DevFmtMono
, DevFmtByte
},
3204 { "AL_FORMAT_STEREO8", DevFmtStereo
, DevFmtByte
},
3205 { "AL_FORMAT_QUAD8", DevFmtQuad
, DevFmtByte
},
3206 { "AL_FORMAT_51CHN8", DevFmtX51
, DevFmtByte
},
3207 { "AL_FORMAT_61CHN8", DevFmtX61
, DevFmtByte
},
3208 { "AL_FORMAT_71CHN8", DevFmtX71
, DevFmtByte
}
3212 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3213 for(i
= 0;i
< COUNTOF(formats
);i
++)
3215 if(strcasecmp(fmt
, formats
[i
].name
) == 0)
3217 if(!(device
->Flags
&DEVICE_CHANNELS_REQUEST
))
3218 device
->FmtChans
= formats
[i
].channels
;
3219 if(!(device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
3220 device
->FmtType
= formats
[i
].type
;
3221 device
->Flags
|= DEVICE_FORMAT_REQUEST
;
3225 if(i
== COUNTOF(formats
))
3226 ERR("Unsupported format: %s\n", fmt
);
3228 #undef DEVICE_FORMAT_REQUEST
3230 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3232 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3233 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3234 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3235 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3238 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3239 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3241 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3242 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3243 if((CPUCapFlags
&CPU_CAP_SSE
))
3244 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3246 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3247 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3249 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3250 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3252 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3253 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3255 ConfigValueInt(NULL
, "cf_level", &device
->Bs2bLevel
);
3257 device
->NumStereoSources
= 1;
3258 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3260 device
->Synth
= SynthCreate(device
);
3263 DELETE_OBJ(device
->Backend
);
3265 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3269 // Find a playback device to open
3270 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3272 DELETE_OBJ(device
->Synth
);
3273 DELETE_OBJ(device
->Backend
);
3275 alcSetError(NULL
, err
);
3279 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3281 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3282 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3284 device
->DefaultSlot
= NULL
;
3285 ERR("Failed to initialize the default effect slot\n");
3287 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3289 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3290 device
->DefaultSlot
= NULL
;
3292 ERR("Failed to initialize the default effect\n");
3297 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3299 device
->next
= head
;
3300 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3303 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3309 * Closes the given device.
3311 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3313 ALCdevice
*list
, *origdev
, *nextdev
;
3317 list
= ATOMIC_LOAD(&DeviceList
);
3321 } while((list
=list
->next
) != NULL
);
3322 if(!list
|| list
->Type
== Capture
)
3324 alcSetError(list
, ALC_INVALID_DEVICE
);
3330 nextdev
= device
->next
;
3331 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3336 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3340 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3343 ALCcontext
*next
= ctx
->next
;
3344 WARN("Releasing context %p\n", ctx
);
3345 ReleaseContext(ctx
, device
);
3348 if((device
->Flags
&DEVICE_RUNNING
))
3349 V0(device
->Backend
,stop
)();
3350 device
->Flags
&= ~DEVICE_RUNNING
;
3352 ALCdevice_DecRef(device
);
3358 /************************************************
3359 * ALC capture functions
3360 ************************************************/
3361 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3363 ALCdevice
*device
= NULL
;
3368 if(!CaptureBackend
.name
)
3370 alcSetError(NULL
, ALC_INVALID_VALUE
);
3376 alcSetError(NULL
, ALC_INVALID_VALUE
);
3380 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3383 device
= al_calloc(16, sizeof(ALCdevice
));
3386 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3391 InitRef(&device
->ref
, 1);
3392 device
->Connected
= ALC_TRUE
;
3393 device
->Type
= Capture
;
3395 AL_STRING_INIT(device
->DeviceName
);
3397 InitUIntMap(&device
->BufferMap
, ~0);
3398 InitUIntMap(&device
->EffectMap
, ~0);
3399 InitUIntMap(&device
->FilterMap
, ~0);
3400 InitUIntMap(&device
->SfontMap
, ~0);
3401 InitUIntMap(&device
->PresetMap
, ~0);
3402 InitUIntMap(&device
->FontsoundMap
, ~0);
3404 if(!CaptureBackend
.getFactory
)
3405 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3406 ALCbackend_Capture
);
3409 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3410 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3412 if(!device
->Backend
)
3415 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3419 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3420 device
->Frequency
= frequency
;
3422 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3423 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3426 alcSetError(NULL
, ALC_INVALID_ENUM
);
3430 device
->UpdateSize
= samples
;
3431 device
->NumUpdates
= 1;
3433 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3436 alcSetError(NULL
, err
);
3441 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3443 device
->next
= head
;
3444 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3447 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3451 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3453 ALCdevice
*list
, *next
, *nextdev
;
3456 list
= ATOMIC_LOAD(&DeviceList
);
3460 } while((list
=list
->next
) != NULL
);
3461 if(!list
|| list
->Type
!= Capture
)
3463 alcSetError(list
, ALC_INVALID_DEVICE
);
3469 nextdev
= device
->next
;
3470 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3475 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3479 ALCdevice_DecRef(device
);
3484 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3486 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3487 alcSetError(device
, ALC_INVALID_DEVICE
);
3490 ALCdevice_Lock(device
);
3491 if(device
->Connected
)
3493 if(!(device
->Flags
&DEVICE_RUNNING
))
3494 V0(device
->Backend
,start
)();
3495 device
->Flags
|= DEVICE_RUNNING
;
3497 ALCdevice_Unlock(device
);
3500 if(device
) ALCdevice_DecRef(device
);
3503 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3505 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3506 alcSetError(device
, ALC_INVALID_DEVICE
);
3509 ALCdevice_Lock(device
);
3510 if((device
->Flags
&DEVICE_RUNNING
))
3511 V0(device
->Backend
,stop
)();
3512 device
->Flags
&= ~DEVICE_RUNNING
;
3513 ALCdevice_Unlock(device
);
3516 if(device
) ALCdevice_DecRef(device
);
3519 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3521 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3522 alcSetError(device
, ALC_INVALID_DEVICE
);
3525 ALCenum err
= ALC_INVALID_VALUE
;
3527 ALCdevice_Lock(device
);
3528 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3529 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3530 ALCdevice_Unlock(device
);
3532 if(err
!= ALC_NO_ERROR
)
3533 alcSetError(device
, err
);
3535 if(device
) ALCdevice_DecRef(device
);
3539 /************************************************
3540 * ALC loopback functions
3541 ************************************************/
3543 /* alcLoopbackOpenDeviceSOFT
3545 * Open a loopback device, for manual rendering.
3547 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3549 ALCbackendFactory
*factory
;
3554 /* Make sure the device name, if specified, is us. */
3555 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3557 alcSetError(NULL
, ALC_INVALID_VALUE
);
3561 device
= al_calloc(16, sizeof(ALCdevice
));
3564 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3569 InitRef(&device
->ref
, 1);
3570 device
->Connected
= ALC_TRUE
;
3571 device
->Type
= Loopback
;
3572 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3575 device
->Bs2b
= NULL
;
3576 device
->Bs2bLevel
= 0;
3577 AL_STRING_INIT(device
->DeviceName
);
3579 ATOMIC_INIT(&device
->ContextList
, NULL
);
3581 device
->ClockBase
= 0;
3582 device
->SamplesDone
= 0;
3584 device
->MaxNoOfSources
= 256;
3585 device
->AuxiliaryEffectSlotMax
= 4;
3586 device
->NumAuxSends
= MAX_SENDS
;
3588 InitUIntMap(&device
->BufferMap
, ~0);
3589 InitUIntMap(&device
->EffectMap
, ~0);
3590 InitUIntMap(&device
->FilterMap
, ~0);
3591 InitUIntMap(&device
->SfontMap
, ~0);
3592 InitUIntMap(&device
->PresetMap
, ~0);
3593 InitUIntMap(&device
->FontsoundMap
, ~0);
3595 factory
= ALCloopbackFactory_getFactory();
3596 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3597 if(!device
->Backend
)
3600 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3605 device
->NumUpdates
= 0;
3606 device
->UpdateSize
= 0;
3608 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3609 device
->FmtChans
= DevFmtChannelsDefault
;
3610 device
->FmtType
= DevFmtTypeDefault
;
3612 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3613 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3615 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3616 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3618 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3619 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3621 device
->NumStereoSources
= 1;
3622 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3624 device
->Synth
= SynthCreate(device
);
3627 DELETE_OBJ(device
->Backend
);
3629 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3633 // Open the "backend"
3634 V(device
->Backend
,open
)("Loopback");
3637 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3639 device
->next
= head
;
3640 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3643 TRACE("Created device %p\n", device
);
3647 /* alcIsRenderFormatSupportedSOFT
3649 * Determines if the loopback device supports the given format for rendering.
3651 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3653 ALCboolean ret
= ALC_FALSE
;
3655 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3656 alcSetError(device
, ALC_INVALID_DEVICE
);
3658 alcSetError(device
, ALC_INVALID_VALUE
);
3661 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3662 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3663 freq
>= MIN_OUTPUT_RATE
)
3666 if(device
) ALCdevice_DecRef(device
);
3671 /* alcRenderSamplesSOFT
3673 * Renders some samples into a buffer, using the format last set by the
3674 * attributes given to alcCreateContext.
3676 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3678 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3679 alcSetError(device
, ALC_INVALID_DEVICE
);
3680 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3681 alcSetError(device
, ALC_INVALID_VALUE
);
3683 aluMixData(device
, buffer
, samples
);
3684 if(device
) ALCdevice_DecRef(device
);
3688 /************************************************
3689 * ALC DSP pause/resume functions
3690 ************************************************/
3692 /* alcDevicePauseSOFT
3694 * Pause the DSP to stop audio processing.
3696 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3698 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3699 alcSetError(device
, ALC_INVALID_DEVICE
);
3703 if((device
->Flags
&DEVICE_RUNNING
))
3704 V0(device
->Backend
,stop
)();
3705 device
->Flags
&= ~DEVICE_RUNNING
;
3706 device
->Flags
|= DEVICE_PAUSED
;
3709 if(device
) ALCdevice_DecRef(device
);
3712 /* alcDeviceResumeSOFT
3714 * Resume the DSP to restart audio processing.
3716 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3718 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3719 alcSetError(device
, ALC_INVALID_DEVICE
);
3723 if((device
->Flags
&DEVICE_PAUSED
))
3725 device
->Flags
&= ~DEVICE_PAUSED
;
3726 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3728 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3729 device
->Flags
|= DEVICE_RUNNING
;
3732 alcSetError(device
, ALC_INVALID_DEVICE
);
3733 ALCdevice_Lock(device
);
3734 aluHandleDisconnect(device
);
3735 ALCdevice_Unlock(device
);
3741 if(device
) ALCdevice_DecRef(device
);