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 }
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", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, 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", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, 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
;
751 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
754 static ALCboolean SuspendDefers
= ALC_TRUE
;
757 /************************************************
759 ************************************************/
760 static const ALCchar alcNoDeviceExtList
[] =
761 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
762 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
763 static const ALCchar alcExtensionList
[] =
764 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
765 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
766 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
767 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
768 static const ALCint alcMajorVersion
= 1;
769 static const ALCint alcMinorVersion
= 1;
771 static const ALCint alcEFXMajorVersion
= 1;
772 static const ALCint alcEFXMinorVersion
= 0;
775 /************************************************
777 ************************************************/
778 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
780 static almtx_t ListLock
;
781 static inline void LockLists(void)
783 int lockret
= almtx_lock(&ListLock
);
784 assert(lockret
== althrd_success
);
786 static inline void UnlockLists(void)
788 int unlockret
= almtx_unlock(&ListLock
);
789 assert(unlockret
== althrd_success
);
792 /************************************************
793 * Library initialization
794 ************************************************/
796 static void alc_init(void);
797 static void alc_deinit(void);
798 static void alc_deinit_safe(void);
800 #ifndef AL_LIBTYPE_STATIC
801 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
805 case DLL_PROCESS_ATTACH
:
806 /* Pin the DLL so we won't get unloaded until the process terminates */
807 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
808 (WCHAR
*)hModule
, &hModule
);
812 case DLL_THREAD_DETACH
:
815 case DLL_PROCESS_DETACH
:
824 #elif defined(_MSC_VER)
825 #pragma section(".CRT$XCU",read)
826 static void alc_constructor(void);
827 static void alc_destructor(void);
828 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
830 static void alc_constructor(void)
832 atexit(alc_destructor
);
836 static void alc_destructor(void)
840 #elif defined(HAVE_GCC_DESTRUCTOR)
841 static void alc_init(void) __attribute__((constructor
));
842 static void alc_deinit(void) __attribute__((destructor
));
844 #error "No static initialization available on this platform!"
847 #elif defined(HAVE_GCC_DESTRUCTOR)
849 static void alc_init(void) __attribute__((constructor
));
850 static void alc_deinit(void) __attribute__((destructor
));
853 #error "No global initialization available on this platform!"
856 static void ReleaseThreadCtx(void *ptr
);
857 static void alc_init(void)
864 AL_STRING_INIT(alcAllDevicesList
);
865 AL_STRING_INIT(alcCaptureDeviceList
);
867 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
868 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
871 str
= getenv("__ALSOFT_REVERSE_Z");
872 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
875 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
876 assert(ret
== althrd_success
);
878 ret
= almtx_init(&ListLock
, almtx_recursive
);
879 assert(ret
== althrd_success
);
884 static void alc_initconfig(void)
886 const char *devs
, *str
;
891 str
= getenv("ALSOFT_LOGLEVEL");
894 long lvl
= strtol(str
, NULL
, 0);
895 if(lvl
>= NoLog
&& lvl
<= LogRef
)
899 str
= getenv("ALSOFT_LOGFILE");
902 FILE *logfile
= al_fopen(str
, "wt");
903 if(logfile
) LogFile
= logfile
;
904 else ERR("Failed to open log file '%s'\n", str
);
909 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
910 for(i
= 1;BackendList
[i
].name
;i
++)
911 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
912 TRACE("Supported backends: %s\n", buf
);
916 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
919 if(strcasecmp(str
, "ignore") == 0)
921 SuspendDefers
= ALC_FALSE
;
922 TRACE("Selected context suspend behavior, \"ignore\"\n");
925 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
929 #if defined(HAVE_SSE4_1)
930 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE4_1
;
931 #elif defined(HAVE_SSE2)
932 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
933 #elif defined(HAVE_SSE)
934 capfilter
|= CPU_CAP_SSE
;
937 capfilter
|= CPU_CAP_NEON
;
939 if(ConfigValueStr(NULL
, "disable-cpu-exts", &str
))
941 if(strcasecmp(str
, "all") == 0)
946 const char *next
= str
;
950 while(isspace(str
[0]))
952 next
= strchr(str
, ',');
954 if(!str
[0] || str
[0] == ',')
957 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
958 while(len
> 0 && isspace(str
[len
-1]))
960 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
961 capfilter
&= ~CPU_CAP_SSE
;
962 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
963 capfilter
&= ~CPU_CAP_SSE2
;
964 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
965 capfilter
&= ~CPU_CAP_SSE4_1
;
966 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
967 capfilter
&= ~CPU_CAP_NEON
;
969 WARN("Invalid CPU extension \"%s\"\n", str
);
973 FillCPUCaps(capfilter
);
980 ConfigValueInt(NULL
, "rt-prio", &RTPrioLevel
);
982 if(ConfigValueStr(NULL
, "resampler", &str
))
984 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
985 DefaultResampler
= PointResampler
;
986 else if(strcasecmp(str
, "linear") == 0)
987 DefaultResampler
= LinearResampler
;
988 else if(strcasecmp(str
, "cubic") == 0)
989 DefaultResampler
= CubicResampler
;
994 n
= strtol(str
, &end
, 0);
995 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== CubicResampler
))
996 DefaultResampler
= n
;
998 WARN("Invalid resampler: %s\n", str
);
1002 str
= getenv("ALSOFT_TRAP_ERROR");
1003 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1005 TrapALError
= AL_TRUE
;
1006 TrapALCError
= AL_TRUE
;
1010 str
= getenv("ALSOFT_TRAP_AL_ERROR");
1011 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1012 TrapALError
= AL_TRUE
;
1013 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
1015 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1016 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1017 TrapALCError
= ALC_TRUE
;
1018 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
1021 if(ConfigValueFloat("reverb", "boost", &valf
))
1022 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1024 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
1026 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1027 ConfigValueStr(NULL
, "drivers", &devs
))
1031 const char *next
= devs
;
1032 int endlist
, delitem
;
1037 while(isspace(devs
[0]))
1039 next
= strchr(devs
, ',');
1041 delitem
= (devs
[0] == '-');
1042 if(devs
[0] == '-') devs
++;
1044 if(!devs
[0] || devs
[0] == ',')
1051 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1052 while(len
> 0 && isspace(devs
[len
-1]))
1054 for(n
= i
;BackendList
[n
].name
;n
++)
1056 if(len
== strlen(BackendList
[n
].name
) &&
1057 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1062 BackendList
[n
] = BackendList
[n
+1];
1064 } while(BackendList
[n
].name
);
1068 struct BackendInfo Bkp
= BackendList
[n
];
1071 BackendList
[n
] = BackendList
[n
-1];
1074 BackendList
[n
] = Bkp
;
1085 BackendList
[i
].name
= NULL
;
1086 BackendList
[i
].getFactory
= NULL
;
1087 BackendList
[i
].Init
= NULL
;
1088 BackendList
[i
].Deinit
= NULL
;
1089 BackendList
[i
].Probe
= NULL
;
1093 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1095 if(BackendList
[i
].getFactory
)
1097 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1098 if(!V0(factory
,init
)())
1100 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1104 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1105 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1107 PlaybackBackend
= BackendList
[i
];
1108 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1110 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1112 CaptureBackend
= BackendList
[i
];
1113 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1119 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1121 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1125 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1126 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1128 PlaybackBackend
= BackendList
[i
];
1129 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1131 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1133 CaptureBackend
= BackendList
[i
];
1134 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1138 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1142 if(ConfigValueStr(NULL
, "excludefx", &str
))
1145 const char *next
= str
;
1149 next
= strchr(str
, ',');
1151 if(!str
[0] || next
== str
)
1154 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1155 for(n
= 0;EffectList
[n
].name
;n
++)
1157 if(len
== strlen(EffectList
[n
].name
) &&
1158 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1159 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1164 InitEffectFactoryMap();
1166 InitEffect(&DefaultEffect
);
1167 str
= getenv("ALSOFT_DEFAULT_REVERB");
1168 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1169 LoadReverbPreset(str
, &DefaultEffect
);
1171 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1174 /************************************************
1175 * Library deinitialization
1176 ************************************************/
1177 static void alc_cleanup(void)
1181 AL_STRING_DEINIT(alcAllDevicesList
);
1182 AL_STRING_DEINIT(alcCaptureDeviceList
);
1184 free(alcDefaultAllDevicesSpecifier
);
1185 alcDefaultAllDevicesSpecifier
= NULL
;
1186 free(alcCaptureDefaultDeviceSpecifier
);
1187 alcCaptureDefaultDeviceSpecifier
= NULL
;
1189 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1194 } while((dev
=dev
->next
) != NULL
);
1195 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1198 DeinitEffectFactoryMap();
1201 static void alc_deinit_safe(void)
1209 almtx_destroy(&ListLock
);
1210 altss_delete(LocalContext
);
1212 if(LogFile
!= stderr
)
1217 static void alc_deinit(void)
1223 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1224 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1226 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1228 if(!BackendList
[i
].getFactory
)
1229 BackendList
[i
].Deinit();
1232 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1233 V0(factory
,deinit
)();
1237 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1238 V0(factory
,deinit
)();
1245 /************************************************
1246 * Device enumeration
1247 ************************************************/
1248 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1253 al_string_clear(list
);
1255 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1257 if(!PlaybackBackend
.getFactory
)
1258 PlaybackBackend
.Probe(type
);
1261 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1262 V(factory
,probe
)(type
);
1265 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1267 if(!CaptureBackend
.getFactory
)
1268 CaptureBackend
.Probe(type
);
1271 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1272 V(factory
,probe
)(type
);
1277 static void ProbeAllDevicesList(void)
1278 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1279 static void ProbeCaptureDeviceList(void)
1280 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1282 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1284 size_t len
= strlen(name
);
1286 al_string_append_range(devnames
, name
, name
+len
+1);
1288 void AppendAllDevicesList(const ALCchar
*name
)
1289 { AppendDevice(name
, &alcAllDevicesList
); }
1290 void AppendCaptureDeviceList(const ALCchar
*name
)
1291 { AppendDevice(name
, &alcCaptureDeviceList
); }
1294 /************************************************
1295 * Device format information
1296 ************************************************/
1297 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1301 case DevFmtByte
: return "Signed Byte";
1302 case DevFmtUByte
: return "Unsigned Byte";
1303 case DevFmtShort
: return "Signed Short";
1304 case DevFmtUShort
: return "Unsigned Short";
1305 case DevFmtInt
: return "Signed Int";
1306 case DevFmtUInt
: return "Unsigned Int";
1307 case DevFmtFloat
: return "Float";
1309 return "(unknown type)";
1311 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1315 case DevFmtMono
: return "Mono";
1316 case DevFmtStereo
: return "Stereo";
1317 case DevFmtQuad
: return "Quadraphonic";
1318 case DevFmtX51
: return "5.1 Surround";
1319 case DevFmtX51Side
: return "5.1 Side";
1320 case DevFmtX61
: return "6.1 Surround";
1321 case DevFmtX71
: return "7.1 Surround";
1323 return "(unknown channels)";
1326 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1327 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1331 case DevFmtByte
: return sizeof(ALbyte
);
1332 case DevFmtUByte
: return sizeof(ALubyte
);
1333 case DevFmtShort
: return sizeof(ALshort
);
1334 case DevFmtUShort
: return sizeof(ALushort
);
1335 case DevFmtInt
: return sizeof(ALint
);
1336 case DevFmtUInt
: return sizeof(ALuint
);
1337 case DevFmtFloat
: return sizeof(ALfloat
);
1341 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1345 case DevFmtMono
: return 1;
1346 case DevFmtStereo
: return 2;
1347 case DevFmtQuad
: return 4;
1348 case DevFmtX51
: return 6;
1349 case DevFmtX51Side
: return 6;
1350 case DevFmtX61
: return 7;
1351 case DevFmtX71
: return 8;
1356 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1357 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1359 static const struct {
1361 enum DevFmtChannels channels
;
1362 enum DevFmtType type
;
1364 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1365 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1366 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1368 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1369 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1370 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1372 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1373 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1374 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1376 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1377 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1378 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1380 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1381 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1382 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1384 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1385 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1386 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1390 for(i
= 0;i
< COUNTOF(list
);i
++)
1392 if(list
[i
].format
== format
)
1394 *chans
= list
[i
].channels
;
1395 *type
= list
[i
].type
;
1403 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1408 case ALC_UNSIGNED_BYTE_SOFT
:
1409 case ALC_SHORT_SOFT
:
1410 case ALC_UNSIGNED_SHORT_SOFT
:
1412 case ALC_UNSIGNED_INT_SOFT
:
1413 case ALC_FLOAT_SOFT
:
1419 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1424 case ALC_STEREO_SOFT
:
1426 case ALC_5POINT1_SOFT
:
1427 case ALC_6POINT1_SOFT
:
1428 case ALC_7POINT1_SOFT
:
1435 /************************************************
1436 * Miscellaneous ALC helpers
1437 ************************************************/
1438 extern inline void LockContext(ALCcontext
*context
);
1439 extern inline void UnlockContext(ALCcontext
*context
);
1441 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1443 return V0(device
->Backend
,getLatency
)();
1446 void ALCdevice_Lock(ALCdevice
*device
)
1448 V0(device
->Backend
,lock
)();
1451 void ALCdevice_Unlock(ALCdevice
*device
)
1453 V0(device
->Backend
,unlock
)();
1457 /* SetDefaultWFXChannelOrder
1459 * Sets the default channel order used by WaveFormatEx.
1461 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1465 for(i
= 0;i
< MaxChannels
;i
++)
1466 device
->ChannelName
[i
] = InvalidChannel
;
1468 switch(device
->FmtChans
)
1470 case DevFmtMono
: device
->ChannelName
[0] = FrontCenter
;
1472 case DevFmtStereo
: device
->ChannelName
[0] = FrontLeft
;
1473 device
->ChannelName
[1] = FrontRight
;
1475 case DevFmtQuad
: device
->ChannelName
[0] = FrontLeft
;
1476 device
->ChannelName
[1] = FrontRight
;
1477 device
->ChannelName
[2] = BackLeft
;
1478 device
->ChannelName
[3] = BackRight
;
1480 case DevFmtX51
: device
->ChannelName
[0] = FrontLeft
;
1481 device
->ChannelName
[1] = FrontRight
;
1482 device
->ChannelName
[2] = FrontCenter
;
1483 device
->ChannelName
[3] = LFE
;
1484 device
->ChannelName
[4] = BackLeft
;
1485 device
->ChannelName
[5] = BackRight
;
1487 case DevFmtX51Side
: device
->ChannelName
[0] = FrontLeft
;
1488 device
->ChannelName
[1] = FrontRight
;
1489 device
->ChannelName
[2] = FrontCenter
;
1490 device
->ChannelName
[3] = LFE
;
1491 device
->ChannelName
[4] = SideLeft
;
1492 device
->ChannelName
[5] = SideRight
;
1494 case DevFmtX61
: device
->ChannelName
[0] = FrontLeft
;
1495 device
->ChannelName
[1] = FrontRight
;
1496 device
->ChannelName
[2] = FrontCenter
;
1497 device
->ChannelName
[3] = LFE
;
1498 device
->ChannelName
[4] = BackCenter
;
1499 device
->ChannelName
[5] = SideLeft
;
1500 device
->ChannelName
[6] = SideRight
;
1502 case DevFmtX71
: device
->ChannelName
[0] = FrontLeft
;
1503 device
->ChannelName
[1] = FrontRight
;
1504 device
->ChannelName
[2] = FrontCenter
;
1505 device
->ChannelName
[3] = LFE
;
1506 device
->ChannelName
[4] = BackLeft
;
1507 device
->ChannelName
[5] = BackRight
;
1508 device
->ChannelName
[6] = SideLeft
;
1509 device
->ChannelName
[7] = SideRight
;
1514 /* SetDefaultChannelOrder
1516 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1518 void SetDefaultChannelOrder(ALCdevice
*device
)
1522 for(i
= 0;i
< MaxChannels
;i
++)
1523 device
->ChannelName
[i
] = InvalidChannel
;
1525 switch(device
->FmtChans
)
1527 case DevFmtX51
: device
->ChannelName
[0] = FrontLeft
;
1528 device
->ChannelName
[1] = FrontRight
;
1529 device
->ChannelName
[2] = BackLeft
;
1530 device
->ChannelName
[3] = BackRight
;
1531 device
->ChannelName
[4] = FrontCenter
;
1532 device
->ChannelName
[5] = LFE
;
1534 case DevFmtX71
: device
->ChannelName
[0] = FrontLeft
;
1535 device
->ChannelName
[1] = FrontRight
;
1536 device
->ChannelName
[2] = BackLeft
;
1537 device
->ChannelName
[3] = BackRight
;
1538 device
->ChannelName
[4] = FrontCenter
;
1539 device
->ChannelName
[5] = LFE
;
1540 device
->ChannelName
[6] = SideLeft
;
1541 device
->ChannelName
[7] = SideRight
;
1544 /* Same as WFX order */
1550 SetDefaultWFXChannelOrder(device
);
1555 extern inline ALint
GetChannelIdxByName(const ALCdevice
*device
, enum Channel chan
);
1558 /* ALCcontext_DeferUpdates
1560 * Defers/suspends updates for the given context's listener and sources. This
1561 * does *NOT* stop mixing, but rather prevents certain property changes from
1564 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1566 ALCdevice
*device
= context
->Device
;
1569 SetMixerFPUMode(&oldMode
);
1571 V0(device
->Backend
,lock
)();
1572 if(!ExchangeInt(&context
->DeferUpdates
, AL_TRUE
))
1574 ALboolean UpdateSources
;
1575 ALvoice
*voice
, *voice_end
;
1576 ALeffectslot
**slot
, **slot_end
;
1577 /* Make sure all pending updates are performed */
1578 UpdateSources
= ATOMIC_EXCHANGE(ALenum
, &context
->UpdateSources
, AL_FALSE
);
1580 voice
= context
->Voices
;
1581 voice_end
= voice
+ context
->VoiceCount
;
1582 while(voice
!= voice_end
)
1584 ALsource
*source
= voice
->Source
;
1585 if(!source
) goto next
;
1587 if(source
->state
!= AL_PLAYING
&& source
->state
!= AL_PAUSED
)
1589 voice
->Source
= NULL
;
1593 if(ATOMIC_EXCHANGE(ALenum
, &source
->NeedsUpdate
, AL_FALSE
) || UpdateSources
)
1594 voice
->Update(voice
, source
, context
);
1599 slot
= VECTOR_ITER_BEGIN(context
->ActiveAuxSlots
);
1600 slot_end
= VECTOR_ITER_END(context
->ActiveAuxSlots
);
1601 while(slot
!= slot_end
)
1603 if(ATOMIC_EXCHANGE(ALenum
, &(*slot
)->NeedsUpdate
, AL_FALSE
))
1604 V((*slot
)->EffectState
,update
)(context
->Device
, *slot
);
1608 V0(device
->Backend
,unlock
)();
1610 RestoreFPUMode(&oldMode
);
1613 /* ALCcontext_ProcessUpdates
1615 * Resumes update processing after being deferred.
1617 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1619 ALCdevice
*device
= context
->Device
;
1621 V0(device
->Backend
,lock
)();
1622 if(ExchangeInt(&context
->DeferUpdates
, AL_FALSE
))
1626 LockUIntMapRead(&context
->SourceMap
);
1627 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1629 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1632 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1633 Source
->Offset
>= 0.0)
1635 ReadLock(&Source
->queue_lock
);
1636 ApplyOffset(Source
);
1637 ReadUnlock(&Source
->queue_lock
);
1640 new_state
= ExchangeInt(&Source
->new_state
, AL_NONE
);
1642 SetSourceState(Source
, context
, new_state
);
1644 UnlockUIntMapRead(&context
->SourceMap
);
1646 V0(device
->Backend
,unlock
)();
1652 * Stores the latest ALC device error
1654 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1659 /* DebugBreak() will cause an exception if there is no debugger */
1660 if(IsDebuggerPresent())
1662 #elif defined(SIGTRAP)
1668 ATOMIC_STORE(&device
->LastError
, errorCode
);
1670 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1676 * Updates the device's base clock time with however many samples have been
1677 * done. This is used so frequency changes on the device don't cause the time
1678 * to jump forward or back.
1680 static inline void UpdateClockBase(ALCdevice
*device
)
1682 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1683 device
->SamplesDone
= 0;
1686 /* UpdateDeviceParams
1688 * Updates device parameters according to the attribute list (caller is
1689 * responsible for holding the list lock).
1691 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1693 ALCcontext
*context
;
1694 enum DevFmtChannels oldChans
;
1695 enum DevFmtType oldType
;
1699 // Check for attributes
1700 if(device
->Type
== Loopback
)
1706 GotAll
= GotFreq
|GotChans
|GotType
1708 ALCuint freq
, numMono
, numStereo
, numSends
, flags
;
1709 enum DevFmtChannels schans
;
1710 enum DevFmtType stype
;
1711 ALCuint attrIdx
= 0;
1716 WARN("Missing attributes for loopback device\n");
1717 return ALC_INVALID_VALUE
;
1720 numMono
= device
->NumMonoSources
;
1721 numStereo
= device
->NumStereoSources
;
1722 numSends
= device
->NumAuxSends
;
1723 schans
= device
->FmtChans
;
1724 stype
= device
->FmtType
;
1725 freq
= device
->Frequency
;
1726 flags
= device
->Flags
;
1728 while(attrList
[attrIdx
])
1730 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1732 ALCint val
= attrList
[attrIdx
+ 1];
1733 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1734 return ALC_INVALID_VALUE
;
1739 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1741 ALCint val
= attrList
[attrIdx
+ 1];
1742 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1743 return ALC_INVALID_VALUE
;
1748 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1750 freq
= attrList
[attrIdx
+ 1];
1751 if(freq
< MIN_OUTPUT_RATE
)
1752 return ALC_INVALID_VALUE
;
1756 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1758 numStereo
= attrList
[attrIdx
+ 1];
1759 if(numStereo
> device
->MaxNoOfSources
)
1760 numStereo
= device
->MaxNoOfSources
;
1762 numMono
= device
->MaxNoOfSources
- numStereo
;
1765 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1766 numSends
= attrList
[attrIdx
+ 1];
1768 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1770 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1771 flags
|= DEVICE_HRTF_REQUEST
;
1773 flags
&= ~DEVICE_HRTF_REQUEST
;
1779 if(gotFmt
!= GotAll
)
1781 WARN("Missing format for loopback device\n");
1782 return ALC_INVALID_VALUE
;
1785 ConfigValueUInt(NULL
, "sends", &numSends
);
1786 numSends
= minu(MAX_SENDS
, numSends
);
1788 if((device
->Flags
&DEVICE_RUNNING
))
1789 V0(device
->Backend
,stop
)();
1790 device
->Flags
= (flags
& ~DEVICE_RUNNING
);
1792 UpdateClockBase(device
);
1794 device
->Frequency
= freq
;
1795 device
->FmtChans
= schans
;
1796 device
->FmtType
= stype
;
1797 device
->NumMonoSources
= numMono
;
1798 device
->NumStereoSources
= numStereo
;
1799 device
->NumAuxSends
= numSends
;
1801 else if(attrList
&& attrList
[0])
1803 ALCuint freq
, numMono
, numStereo
, numSends
;
1804 ALCuint attrIdx
= 0;
1806 /* If a context is already running on the device, stop playback so the
1807 * device attributes can be updated. */
1808 if((device
->Flags
&DEVICE_RUNNING
))
1809 V0(device
->Backend
,stop
)();
1810 device
->Flags
&= ~DEVICE_RUNNING
;
1812 freq
= device
->Frequency
;
1813 numMono
= device
->NumMonoSources
;
1814 numStereo
= device
->NumStereoSources
;
1815 numSends
= device
->NumAuxSends
;
1817 while(attrList
[attrIdx
])
1819 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1821 freq
= attrList
[attrIdx
+ 1];
1822 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1825 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1827 numStereo
= attrList
[attrIdx
+ 1];
1828 if(numStereo
> device
->MaxNoOfSources
)
1829 numStereo
= device
->MaxNoOfSources
;
1831 numMono
= device
->MaxNoOfSources
- numStereo
;
1834 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1835 numSends
= attrList
[attrIdx
+ 1];
1837 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1839 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1840 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1842 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1848 ConfigValueUInt(NULL
, "frequency", &freq
);
1849 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1851 ConfigValueUInt(NULL
, "sends", &numSends
);
1852 numSends
= minu(MAX_SENDS
, numSends
);
1854 UpdateClockBase(device
);
1856 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1858 /* SSE and Neon do best with the update size being a multiple of 4 */
1859 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1860 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1862 device
->Frequency
= freq
;
1863 device
->NumMonoSources
= numMono
;
1864 device
->NumStereoSources
= numStereo
;
1865 device
->NumAuxSends
= numSends
;
1868 if((device
->Flags
&DEVICE_RUNNING
))
1869 return ALC_NO_ERROR
;
1871 UpdateClockBase(device
);
1873 if(device
->Type
!= Loopback
)
1875 bool usehrtf
= !!(device
->Flags
&DEVICE_HRTF_REQUEST
);
1876 if(GetConfigValueBool(NULL
, "hrtf", usehrtf
))
1877 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1879 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1881 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1883 enum DevFmtChannels chans
= device
->FmtChans
;
1884 ALCuint freq
= device
->Frequency
;
1885 if(FindHrtfFormat(&chans
, &freq
))
1887 if(device
->Type
!= Loopback
)
1889 device
->Frequency
= freq
;
1890 device
->FmtChans
= chans
;
1891 device
->Flags
|= DEVICE_CHANNELS_REQUEST
|
1892 DEVICE_FREQUENCY_REQUEST
;
1894 else if(device
->Frequency
!= freq
|| device
->FmtChans
!= chans
)
1896 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1897 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1898 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1903 oldFreq
= device
->Frequency
;
1904 oldChans
= device
->FmtChans
;
1905 oldType
= device
->FmtType
;
1907 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1908 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"",
1909 DevFmtChannelsString(device
->FmtChans
),
1910 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"",
1911 DevFmtTypeString(device
->FmtType
),
1912 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"",
1914 device
->UpdateSize
, device
->NumUpdates
);
1916 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1917 return ALC_INVALID_DEVICE
;
1919 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1921 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1922 DevFmtChannelsString(device
->FmtChans
));
1923 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1925 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1927 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1928 DevFmtTypeString(device
->FmtType
));
1929 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1931 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1933 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1934 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1937 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1938 DevFmtChannelsString(device
->FmtChans
),
1939 DevFmtTypeString(device
->FmtType
), device
->Frequency
,
1940 device
->UpdateSize
, device
->NumUpdates
);
1942 aluInitPanning(device
);
1944 V(device
->Synth
,update
)(device
);
1946 device
->Hrtf
= NULL
;
1947 if((device
->Flags
&DEVICE_HRTF_REQUEST
))
1949 device
->Hrtf
= GetHrtf(device
->FmtChans
, device
->Frequency
);
1951 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1953 TRACE("HRTF %s\n", device
->Hrtf
?"enabled":"disabled");
1955 if(!device
->Hrtf
&& device
->Bs2bLevel
> 0 && device
->Bs2bLevel
<= 6)
1959 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
1960 bs2b_clear(device
->Bs2b
);
1962 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
1963 bs2b_set_level(device
->Bs2b
, device
->Bs2bLevel
);
1964 TRACE("BS2B level %d\n", device
->Bs2bLevel
);
1969 device
->Bs2b
= NULL
;
1970 TRACE("BS2B disabled\n");
1973 device
->Flags
&= ~DEVICE_WIDE_STEREO
;
1974 if(device
->Type
!= Loopback
&& !device
->Hrtf
&& GetConfigValueBool(NULL
, "wide-stereo", AL_FALSE
))
1975 device
->Flags
|= DEVICE_WIDE_STEREO
;
1977 if(!device
->Hrtf
&& (device
->UpdateSize
&3))
1979 if((CPUCapFlags
&CPU_CAP_SSE
))
1980 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1981 if((CPUCapFlags
&CPU_CAP_NEON
))
1982 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1985 SetMixerFPUMode(&oldMode
);
1986 ALCdevice_Lock(device
);
1987 context
= ATOMIC_LOAD(&device
->ContextList
);
1992 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
1993 LockUIntMapRead(&context
->EffectSlotMap
);
1994 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
1996 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
1998 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2000 UnlockUIntMapRead(&context
->EffectSlotMap
);
2001 ALCdevice_Unlock(device
);
2002 RestoreFPUMode(&oldMode
);
2003 return ALC_INVALID_DEVICE
;
2005 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2006 V(slot
->EffectState
,update
)(device
, slot
);
2008 UnlockUIntMapRead(&context
->EffectSlotMap
);
2010 LockUIntMapRead(&context
->SourceMap
);
2011 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2013 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2014 ALuint s
= device
->NumAuxSends
;
2015 while(s
< MAX_SENDS
)
2017 if(source
->Send
[s
].Slot
)
2018 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2019 source
->Send
[s
].Slot
= NULL
;
2020 source
->Send
[s
].Gain
= 1.0f
;
2021 source
->Send
[s
].GainHF
= 1.0f
;
2024 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2026 UnlockUIntMapRead(&context
->SourceMap
);
2028 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2030 ALvoice
*voice
= &context
->Voices
[pos
];
2031 ALsource
*source
= voice
->Source
;
2032 ALuint s
= device
->NumAuxSends
;
2034 while(s
< MAX_SENDS
)
2036 voice
->Send
[s
].Moving
= AL_FALSE
;
2037 voice
->Send
[s
].Counter
= 0;
2043 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2044 voice
->Update(voice
, source
, context
);
2048 context
= context
->next
;
2050 if(device
->DefaultSlot
)
2052 ALeffectslot
*slot
= device
->DefaultSlot
;
2054 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2056 ALCdevice_Unlock(device
);
2057 RestoreFPUMode(&oldMode
);
2058 return ALC_INVALID_DEVICE
;
2060 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2061 V(slot
->EffectState
,update
)(device
, slot
);
2063 ALCdevice_Unlock(device
);
2064 RestoreFPUMode(&oldMode
);
2066 if(!(device
->Flags
&DEVICE_PAUSED
))
2068 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2069 return ALC_INVALID_DEVICE
;
2070 device
->Flags
|= DEVICE_RUNNING
;
2073 return ALC_NO_ERROR
;
2078 * Frees the device structure, and destroys any objects the app failed to
2079 * delete. Called once there's no more references on the device.
2081 static ALCvoid
FreeDevice(ALCdevice
*device
)
2083 TRACE("%p\n", device
);
2085 V0(device
->Backend
,close
)();
2086 DELETE_OBJ(device
->Backend
);
2087 device
->Backend
= NULL
;
2089 DELETE_OBJ(device
->Synth
);
2090 device
->Synth
= NULL
;
2092 if(device
->DefaultSlot
)
2094 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2095 device
->DefaultSlot
= NULL
;
2099 if(device
->DefaultSfont
)
2100 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
2101 device
->DefaultSfont
= NULL
;
2103 if(device
->BufferMap
.size
> 0)
2105 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2106 ReleaseALBuffers(device
);
2108 ResetUIntMap(&device
->BufferMap
);
2110 if(device
->EffectMap
.size
> 0)
2112 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2113 ReleaseALEffects(device
);
2115 ResetUIntMap(&device
->EffectMap
);
2117 if(device
->FilterMap
.size
> 0)
2119 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2120 ReleaseALFilters(device
);
2122 ResetUIntMap(&device
->FilterMap
);
2124 if(device
->SfontMap
.size
> 0)
2126 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2127 ReleaseALSoundfonts(device
);
2129 ResetUIntMap(&device
->SfontMap
);
2131 if(device
->PresetMap
.size
> 0)
2133 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2134 ReleaseALPresets(device
);
2136 ResetUIntMap(&device
->PresetMap
);
2138 if(device
->FontsoundMap
.size
> 0)
2140 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2141 ReleaseALFontsounds(device
);
2143 ResetUIntMap(&device
->FontsoundMap
);
2146 device
->Bs2b
= NULL
;
2148 AL_STRING_DEINIT(device
->DeviceName
);
2154 void ALCdevice_IncRef(ALCdevice
*device
)
2157 ref
= IncrementRef(&device
->ref
);
2158 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2161 void ALCdevice_DecRef(ALCdevice
*device
)
2164 ref
= DecrementRef(&device
->ref
);
2165 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2166 if(ref
== 0) FreeDevice(device
);
2171 * Checks if the device handle is valid, and increments its ref count if so.
2173 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2175 ALCdevice
*tmpDevice
;
2181 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2182 while(tmpDevice
&& tmpDevice
!= device
)
2183 tmpDevice
= tmpDevice
->next
;
2186 ALCdevice_IncRef(tmpDevice
);
2194 * Initializes context fields
2196 static ALvoid
InitContext(ALCcontext
*Context
)
2200 //Initialise listener
2201 Context
->Listener
->Gain
= 1.0f
;
2202 Context
->Listener
->MetersPerUnit
= 1.0f
;
2203 Context
->Listener
->Position
[0] = 0.0f
;
2204 Context
->Listener
->Position
[1] = 0.0f
;
2205 Context
->Listener
->Position
[2] = 0.0f
;
2206 Context
->Listener
->Velocity
[0] = 0.0f
;
2207 Context
->Listener
->Velocity
[1] = 0.0f
;
2208 Context
->Listener
->Velocity
[2] = 0.0f
;
2209 Context
->Listener
->Forward
[0] = 0.0f
;
2210 Context
->Listener
->Forward
[1] = 0.0f
;
2211 Context
->Listener
->Forward
[2] = -1.0f
;
2212 Context
->Listener
->Up
[0] = 0.0f
;
2213 Context
->Listener
->Up
[1] = 1.0f
;
2214 Context
->Listener
->Up
[2] = 0.0f
;
2215 for(i
= 0;i
< 4;i
++)
2217 for(j
= 0;j
< 4;j
++)
2218 Context
->Listener
->Params
.Matrix
[i
][j
] = ((i
==j
) ? 1.0f
: 0.0f
);
2220 for(i
= 0;i
< 3;i
++)
2221 Context
->Listener
->Params
.Velocity
[i
] = 0.0f
;
2224 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2225 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2226 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2227 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2230 Context
->DistanceModel
= DefaultDistanceModel
;
2231 Context
->SourceDistanceModel
= AL_FALSE
;
2232 Context
->DopplerFactor
= 1.0f
;
2233 Context
->DopplerVelocity
= 1.0f
;
2234 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2235 Context
->DeferUpdates
= AL_FALSE
;
2237 Context
->ExtensionList
= alExtList
;
2243 * Cleans up the context, and destroys any remaining objects the app failed to
2244 * delete. Called once there's no more references on the context.
2246 static void FreeContext(ALCcontext
*context
)
2248 TRACE("%p\n", context
);
2250 if(context
->SourceMap
.size
> 0)
2252 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2253 ReleaseALSources(context
);
2255 ResetUIntMap(&context
->SourceMap
);
2257 if(context
->EffectSlotMap
.size
> 0)
2259 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2260 ReleaseALAuxiliaryEffectSlots(context
);
2262 ResetUIntMap(&context
->EffectSlotMap
);
2264 al_free(context
->Voices
);
2265 context
->Voices
= NULL
;
2266 context
->VoiceCount
= 0;
2267 context
->MaxVoices
= 0;
2269 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2271 ALCdevice_DecRef(context
->Device
);
2272 context
->Device
= NULL
;
2274 //Invalidate context
2275 memset(context
, 0, sizeof(ALCcontext
));
2281 * Removes the context reference from the given device and removes it from
2282 * being current on the running thread or globally.
2284 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2286 ALCcontext
*nextctx
;
2287 ALCcontext
*origctx
;
2289 if(altss_get(LocalContext
) == context
)
2291 WARN("%p released while current on thread\n", context
);
2292 altss_set(LocalContext
, NULL
);
2293 ALCcontext_DecRef(context
);
2297 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2298 ALCcontext_DecRef(context
);
2300 ALCdevice_Lock(device
);
2302 nextctx
= context
->next
;
2303 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2309 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2311 ALCdevice_Unlock(device
);
2313 ALCcontext_DecRef(context
);
2316 void ALCcontext_IncRef(ALCcontext
*context
)
2319 ref
= IncrementRef(&context
->ref
);
2320 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2323 void ALCcontext_DecRef(ALCcontext
*context
)
2326 ref
= DecrementRef(&context
->ref
);
2327 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2328 if(ref
== 0) FreeContext(context
);
2331 static void ReleaseThreadCtx(void *ptr
)
2333 WARN("%p current for thread being destroyed\n", ptr
);
2334 ALCcontext_DecRef(ptr
);
2339 * Checks that the given context is valid, and increments its reference count.
2341 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2346 dev
= ATOMIC_LOAD(&DeviceList
);
2349 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2354 ALCcontext_IncRef(ctx
);
2370 * Returns the currently active context for this thread, and adds a reference
2371 * without locking it.
2373 ALCcontext
*GetContextRef(void)
2375 ALCcontext
*context
;
2377 context
= altss_get(LocalContext
);
2379 ALCcontext_IncRef(context
);
2383 context
= ATOMIC_LOAD(&GlobalContext
);
2385 ALCcontext_IncRef(context
);
2393 /************************************************
2394 * Standard ALC functions
2395 ************************************************/
2399 * Return last ALC generated error code for the given device
2401 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2405 if(VerifyDevice(device
))
2407 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2408 ALCdevice_DecRef(device
);
2411 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2417 /* alcSuspendContext
2419 * Suspends updates for the given context
2421 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2426 context
= VerifyContext(context
);
2428 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2431 ALCcontext_DeferUpdates(context
);
2432 ALCcontext_DecRef(context
);
2436 /* alcProcessContext
2438 * Resumes processing updates for the given context
2440 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2445 context
= VerifyContext(context
);
2447 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2450 ALCcontext_ProcessUpdates(context
);
2451 ALCcontext_DecRef(context
);
2458 * Returns information about the device, and error strings
2460 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2462 const ALCchar
*value
= NULL
;
2470 case ALC_INVALID_ENUM
:
2471 value
= alcErrInvalidEnum
;
2474 case ALC_INVALID_VALUE
:
2475 value
= alcErrInvalidValue
;
2478 case ALC_INVALID_DEVICE
:
2479 value
= alcErrInvalidDevice
;
2482 case ALC_INVALID_CONTEXT
:
2483 value
= alcErrInvalidContext
;
2486 case ALC_OUT_OF_MEMORY
:
2487 value
= alcErrOutOfMemory
;
2490 case ALC_DEVICE_SPECIFIER
:
2491 value
= alcDefaultName
;
2494 case ALC_ALL_DEVICES_SPECIFIER
:
2495 if(VerifyDevice(Device
))
2497 value
= al_string_get_cstr(Device
->DeviceName
);
2498 ALCdevice_DecRef(Device
);
2502 ProbeAllDevicesList();
2503 value
= al_string_get_cstr(alcAllDevicesList
);
2507 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2508 if(VerifyDevice(Device
))
2510 value
= al_string_get_cstr(Device
->DeviceName
);
2511 ALCdevice_DecRef(Device
);
2515 ProbeCaptureDeviceList();
2516 value
= al_string_get_cstr(alcCaptureDeviceList
);
2520 /* Default devices are always first in the list */
2521 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2522 value
= alcDefaultName
;
2525 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2526 if(al_string_empty(alcAllDevicesList
))
2527 ProbeAllDevicesList();
2529 Device
= VerifyDevice(Device
);
2531 free(alcDefaultAllDevicesSpecifier
);
2532 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2533 if(!alcDefaultAllDevicesSpecifier
)
2534 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2536 value
= alcDefaultAllDevicesSpecifier
;
2537 if(Device
) ALCdevice_DecRef(Device
);
2540 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2541 if(al_string_empty(alcCaptureDeviceList
))
2542 ProbeCaptureDeviceList();
2544 Device
= VerifyDevice(Device
);
2546 free(alcCaptureDefaultDeviceSpecifier
);
2547 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2548 if(!alcCaptureDefaultDeviceSpecifier
)
2549 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2551 value
= alcCaptureDefaultDeviceSpecifier
;
2552 if(Device
) ALCdevice_DecRef(Device
);
2555 case ALC_EXTENSIONS
:
2556 if(!VerifyDevice(Device
))
2557 value
= alcNoDeviceExtList
;
2560 value
= alcExtensionList
;
2561 ALCdevice_DecRef(Device
);
2566 Device
= VerifyDevice(Device
);
2567 alcSetError(Device
, ALC_INVALID_ENUM
);
2568 if(Device
) ALCdevice_DecRef(Device
);
2576 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2580 if(size
<= 0 || values
== NULL
)
2582 alcSetError(device
, ALC_INVALID_VALUE
);
2590 case ALC_MAJOR_VERSION
:
2591 values
[0] = alcMajorVersion
;
2593 case ALC_MINOR_VERSION
:
2594 values
[0] = alcMinorVersion
;
2597 case ALC_ATTRIBUTES_SIZE
:
2598 case ALC_ALL_ATTRIBUTES
:
2602 case ALC_MONO_SOURCES
:
2603 case ALC_STEREO_SOURCES
:
2604 case ALC_CAPTURE_SAMPLES
:
2605 case ALC_FORMAT_CHANNELS_SOFT
:
2606 case ALC_FORMAT_TYPE_SOFT
:
2607 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2611 alcSetError(NULL
, ALC_INVALID_ENUM
);
2617 if(device
->Type
== Capture
)
2621 case ALC_CAPTURE_SAMPLES
:
2622 ALCdevice_Lock(device
);
2623 values
[0] = V0(device
->Backend
,availableSamples
)();
2624 ALCdevice_Unlock(device
);
2628 values
[0] = device
->Connected
;
2632 alcSetError(device
, ALC_INVALID_ENUM
);
2641 case ALC_MAJOR_VERSION
:
2642 values
[0] = alcMajorVersion
;
2645 case ALC_MINOR_VERSION
:
2646 values
[0] = alcMinorVersion
;
2649 case ALC_EFX_MAJOR_VERSION
:
2650 values
[0] = alcEFXMajorVersion
;
2653 case ALC_EFX_MINOR_VERSION
:
2654 values
[0] = alcEFXMinorVersion
;
2657 case ALC_ATTRIBUTES_SIZE
:
2661 case ALC_ALL_ATTRIBUTES
:
2664 alcSetError(device
, ALC_INVALID_VALUE
);
2669 values
[i
++] = ALC_FREQUENCY
;
2670 values
[i
++] = device
->Frequency
;
2672 if(device
->Type
!= Loopback
)
2674 values
[i
++] = ALC_REFRESH
;
2675 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2677 values
[i
++] = ALC_SYNC
;
2678 values
[i
++] = ALC_FALSE
;
2682 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2683 values
[i
++] = device
->FmtChans
;
2685 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2686 values
[i
++] = device
->FmtType
;
2689 values
[i
++] = ALC_MONO_SOURCES
;
2690 values
[i
++] = device
->NumMonoSources
;
2692 values
[i
++] = ALC_STEREO_SOURCES
;
2693 values
[i
++] = device
->NumStereoSources
;
2695 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2696 values
[i
++] = device
->NumAuxSends
;
2698 values
[i
++] = ALC_HRTF_SOFT
;
2699 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2705 values
[0] = device
->Frequency
;
2709 if(device
->Type
== Loopback
)
2711 alcSetError(device
, ALC_INVALID_DEVICE
);
2714 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2718 if(device
->Type
== Loopback
)
2720 alcSetError(device
, ALC_INVALID_DEVICE
);
2723 values
[0] = ALC_FALSE
;
2726 case ALC_FORMAT_CHANNELS_SOFT
:
2727 if(device
->Type
!= Loopback
)
2729 alcSetError(device
, ALC_INVALID_DEVICE
);
2732 values
[0] = device
->FmtChans
;
2735 case ALC_FORMAT_TYPE_SOFT
:
2736 if(device
->Type
!= Loopback
)
2738 alcSetError(device
, ALC_INVALID_DEVICE
);
2741 values
[0] = device
->FmtType
;
2744 case ALC_MONO_SOURCES
:
2745 values
[0] = device
->NumMonoSources
;
2748 case ALC_STEREO_SOURCES
:
2749 values
[0] = device
->NumStereoSources
;
2752 case ALC_MAX_AUXILIARY_SENDS
:
2753 values
[0] = device
->NumAuxSends
;
2757 values
[0] = device
->Connected
;
2761 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2765 alcSetError(device
, ALC_INVALID_ENUM
);
2773 * Returns information about the device and the version of OpenAL
2775 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2777 device
= VerifyDevice(device
);
2778 if(size
<= 0 || values
== NULL
)
2779 alcSetError(device
, ALC_INVALID_VALUE
);
2781 GetIntegerv(device
, param
, size
, values
);
2782 if(device
) ALCdevice_DecRef(device
);
2785 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2790 device
= VerifyDevice(device
);
2791 if(size
<= 0 || values
== NULL
)
2792 alcSetError(device
, ALC_INVALID_VALUE
);
2793 else if(!device
|| device
->Type
== Capture
)
2795 ivals
= malloc(size
* sizeof(ALCint
));
2796 size
= GetIntegerv(device
, pname
, size
, ivals
);
2797 for(i
= 0;i
< size
;i
++)
2798 values
[i
] = ivals
[i
];
2801 else /* render device */
2805 case ALC_ATTRIBUTES_SIZE
:
2809 case ALC_ALL_ATTRIBUTES
:
2811 alcSetError(device
, ALC_INVALID_VALUE
);
2816 V0(device
->Backend
,lock
)();
2817 values
[i
++] = ALC_FREQUENCY
;
2818 values
[i
++] = device
->Frequency
;
2820 if(device
->Type
!= Loopback
)
2822 values
[i
++] = ALC_REFRESH
;
2823 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2825 values
[i
++] = ALC_SYNC
;
2826 values
[i
++] = ALC_FALSE
;
2830 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2831 values
[i
++] = device
->FmtChans
;
2833 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2834 values
[i
++] = device
->FmtType
;
2837 values
[i
++] = ALC_MONO_SOURCES
;
2838 values
[i
++] = device
->NumMonoSources
;
2840 values
[i
++] = ALC_STEREO_SOURCES
;
2841 values
[i
++] = device
->NumStereoSources
;
2843 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2844 values
[i
++] = device
->NumAuxSends
;
2846 values
[i
++] = ALC_HRTF_SOFT
;
2847 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2849 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2850 values
[i
++] = device
->ClockBase
+
2851 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2854 V0(device
->Backend
,unlock
)();
2858 case ALC_DEVICE_CLOCK_SOFT
:
2859 V0(device
->Backend
,lock
)();
2860 *values
= device
->ClockBase
+
2861 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2862 V0(device
->Backend
,unlock
)();
2866 ivals
= malloc(size
* sizeof(ALCint
));
2867 size
= GetIntegerv(device
, pname
, size
, ivals
);
2868 for(i
= 0;i
< size
;i
++)
2869 values
[i
] = ivals
[i
];
2875 ALCdevice_DecRef(device
);
2879 /* alcIsExtensionPresent
2881 * Determines if there is support for a particular extension
2883 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2885 ALCboolean bResult
= ALC_FALSE
;
2887 device
= VerifyDevice(device
);
2890 alcSetError(device
, ALC_INVALID_VALUE
);
2893 size_t len
= strlen(extName
);
2894 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2897 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2898 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2903 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2907 } while(isspace(*ptr
));
2912 ALCdevice_DecRef(device
);
2917 /* alcGetProcAddress
2919 * Retrieves the function address for a particular extension function
2921 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2923 ALCvoid
*ptr
= NULL
;
2927 device
= VerifyDevice(device
);
2928 alcSetError(device
, ALC_INVALID_VALUE
);
2929 if(device
) ALCdevice_DecRef(device
);
2934 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2936 ptr
= alcFunctions
[i
].address
;
2945 * Get the value for a particular ALC enumeration name
2947 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
2953 device
= VerifyDevice(device
);
2954 alcSetError(device
, ALC_INVALID_VALUE
);
2955 if(device
) ALCdevice_DecRef(device
);
2960 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
2962 val
= enumeration
[i
].value
;
2971 * Create and attach a context to the given device.
2973 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
2975 ALCcontext
*ALContext
;
2979 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
2982 alcSetError(device
, ALC_INVALID_DEVICE
);
2983 if(device
) ALCdevice_DecRef(device
);
2987 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
2989 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
2992 alcSetError(device
, err
);
2993 if(err
== ALC_INVALID_DEVICE
)
2995 ALCdevice_Lock(device
);
2996 aluHandleDisconnect(device
);
2997 ALCdevice_Unlock(device
);
2999 ALCdevice_DecRef(device
);
3003 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3006 InitRef(&ALContext
->ref
, 1);
3007 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3009 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3011 ALContext
->VoiceCount
= 0;
3012 ALContext
->MaxVoices
= 256;
3013 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3015 if(!ALContext
|| !ALContext
->Voices
)
3017 if(!ATOMIC_LOAD(&device
->ContextList
))
3019 V0(device
->Backend
,stop
)();
3020 device
->Flags
&= ~DEVICE_RUNNING
;
3026 al_free(ALContext
->Voices
);
3027 ALContext
->Voices
= NULL
;
3029 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3035 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3036 ALCdevice_DecRef(device
);
3040 ALContext
->Device
= device
;
3041 ALCdevice_IncRef(device
);
3042 InitContext(ALContext
);
3045 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3047 ALContext
->next
= head
;
3048 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3052 ALCdevice_DecRef(device
);
3054 TRACE("Created context %p\n", ALContext
);
3058 /* alcDestroyContext
3060 * Remove a context from its device
3062 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3067 /* alcGetContextsDevice sets an error for invalid contexts */
3068 Device
= alcGetContextsDevice(context
);
3071 ReleaseContext(context
, Device
);
3072 if(!ATOMIC_LOAD(&Device
->ContextList
))
3074 V0(Device
->Backend
,stop
)();
3075 Device
->Flags
&= ~DEVICE_RUNNING
;
3082 /* alcGetCurrentContext
3084 * Returns the currently active context on the calling thread
3086 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3088 ALCcontext
*Context
= altss_get(LocalContext
);
3089 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3093 /* alcGetThreadContext
3095 * Returns the currently active thread-local context
3097 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3099 return altss_get(LocalContext
);
3103 /* alcMakeContextCurrent
3105 * Makes the given context the active process-wide context, and removes the
3106 * thread-local context for the calling thread.
3108 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3110 /* context must be valid or NULL */
3111 if(context
&& !(context
=VerifyContext(context
)))
3113 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3116 /* context's reference count is already incremented */
3117 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3118 if(context
) ALCcontext_DecRef(context
);
3120 if((context
=altss_get(LocalContext
)) != NULL
)
3122 altss_set(LocalContext
, NULL
);
3123 ALCcontext_DecRef(context
);
3129 /* alcSetThreadContext
3131 * Makes the given context the active context for the current thread
3133 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3137 /* context must be valid or NULL */
3138 if(context
&& !(context
=VerifyContext(context
)))
3140 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3143 /* context's reference count is already incremented */
3144 old
= altss_get(LocalContext
);
3145 altss_set(LocalContext
, context
);
3146 if(old
) ALCcontext_DecRef(old
);
3152 /* alcGetContextsDevice
3154 * Returns the device that a particular context is attached to
3156 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3160 if(!(Context
=VerifyContext(Context
)))
3162 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3165 Device
= Context
->Device
;
3166 ALCcontext_DecRef(Context
);
3174 * Opens the named device.
3176 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3184 if(!PlaybackBackend
.name
)
3186 alcSetError(NULL
, ALC_INVALID_VALUE
);
3190 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3193 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3196 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3201 InitRef(&device
->ref
, 1);
3202 device
->Connected
= ALC_TRUE
;
3203 device
->Type
= Playback
;
3204 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3207 device
->Bs2b
= NULL
;
3208 device
->Bs2bLevel
= 0;
3209 AL_STRING_INIT(device
->DeviceName
);
3211 ATOMIC_INIT(&device
->ContextList
, NULL
);
3213 device
->ClockBase
= 0;
3214 device
->SamplesDone
= 0;
3216 device
->MaxNoOfSources
= 256;
3217 device
->AuxiliaryEffectSlotMax
= 4;
3218 device
->NumAuxSends
= MAX_SENDS
;
3220 InitUIntMap(&device
->BufferMap
, ~0);
3221 InitUIntMap(&device
->EffectMap
, ~0);
3222 InitUIntMap(&device
->FilterMap
, ~0);
3223 InitUIntMap(&device
->SfontMap
, ~0);
3224 InitUIntMap(&device
->PresetMap
, ~0);
3225 InitUIntMap(&device
->FontsoundMap
, ~0);
3228 device
->FmtChans
= DevFmtChannelsDefault
;
3229 device
->FmtType
= DevFmtTypeDefault
;
3230 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3231 device
->NumUpdates
= 4;
3232 device
->UpdateSize
= 1024;
3234 if(!PlaybackBackend
.getFactory
)
3235 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3236 ALCbackend_Playback
);
3239 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3240 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3242 if(!device
->Backend
)
3245 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3250 if(ConfigValueStr(NULL
, "channels", &fmt
))
3252 static const struct {
3253 const char name
[16];
3254 enum DevFmtChannels chans
;
3256 { "mono", DevFmtMono
},
3257 { "stereo", DevFmtStereo
},
3258 { "quad", DevFmtQuad
},
3259 { "surround51", DevFmtX51
},
3260 { "surround61", DevFmtX61
},
3261 { "surround71", DevFmtX71
},
3265 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3267 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3269 device
->FmtChans
= chanlist
[i
].chans
;
3270 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3274 if(i
== COUNTOF(chanlist
))
3275 ERR("Unsupported channels: %s\n", fmt
);
3277 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3279 static const struct {
3280 const char name
[16];
3281 enum DevFmtType type
;
3283 { "int8", DevFmtByte
},
3284 { "uint8", DevFmtUByte
},
3285 { "int16", DevFmtShort
},
3286 { "uint16", DevFmtUShort
},
3287 { "int32", DevFmtInt
},
3288 { "uint32", DevFmtUInt
},
3289 { "float32", DevFmtFloat
},
3293 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3295 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3297 device
->FmtType
= typelist
[i
].type
;
3298 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3302 if(i
== COUNTOF(typelist
))
3303 ERR("Unsupported sample-type: %s\n", fmt
);
3305 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3306 if((device
->Flags
&DEVICE_FORMAT_REQUEST
) != DEVICE_FORMAT_REQUEST
&&
3307 ConfigValueStr(NULL
, "format", &fmt
))
3309 static const struct {
3310 const char name
[32];
3311 enum DevFmtChannels channels
;
3312 enum DevFmtType type
;
3314 { "AL_FORMAT_MONO32", DevFmtMono
, DevFmtFloat
},
3315 { "AL_FORMAT_STEREO32", DevFmtStereo
, DevFmtFloat
},
3316 { "AL_FORMAT_QUAD32", DevFmtQuad
, DevFmtFloat
},
3317 { "AL_FORMAT_51CHN32", DevFmtX51
, DevFmtFloat
},
3318 { "AL_FORMAT_61CHN32", DevFmtX61
, DevFmtFloat
},
3319 { "AL_FORMAT_71CHN32", DevFmtX71
, DevFmtFloat
},
3321 { "AL_FORMAT_MONO16", DevFmtMono
, DevFmtShort
},
3322 { "AL_FORMAT_STEREO16", DevFmtStereo
, DevFmtShort
},
3323 { "AL_FORMAT_QUAD16", DevFmtQuad
, DevFmtShort
},
3324 { "AL_FORMAT_51CHN16", DevFmtX51
, DevFmtShort
},
3325 { "AL_FORMAT_61CHN16", DevFmtX61
, DevFmtShort
},
3326 { "AL_FORMAT_71CHN16", DevFmtX71
, DevFmtShort
},
3328 { "AL_FORMAT_MONO8", DevFmtMono
, DevFmtByte
},
3329 { "AL_FORMAT_STEREO8", DevFmtStereo
, DevFmtByte
},
3330 { "AL_FORMAT_QUAD8", DevFmtQuad
, DevFmtByte
},
3331 { "AL_FORMAT_51CHN8", DevFmtX51
, DevFmtByte
},
3332 { "AL_FORMAT_61CHN8", DevFmtX61
, DevFmtByte
},
3333 { "AL_FORMAT_71CHN8", DevFmtX71
, DevFmtByte
}
3337 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3338 for(i
= 0;i
< COUNTOF(formats
);i
++)
3340 if(strcasecmp(fmt
, formats
[i
].name
) == 0)
3342 if(!(device
->Flags
&DEVICE_CHANNELS_REQUEST
))
3343 device
->FmtChans
= formats
[i
].channels
;
3344 if(!(device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
3345 device
->FmtType
= formats
[i
].type
;
3346 device
->Flags
|= DEVICE_FORMAT_REQUEST
;
3350 if(i
== COUNTOF(formats
))
3351 ERR("Unsupported format: %s\n", fmt
);
3353 #undef DEVICE_FORMAT_REQUEST
3355 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3357 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3358 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3359 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3360 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3363 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3364 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3366 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3367 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3368 if((CPUCapFlags
&CPU_CAP_SSE
))
3369 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3371 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3372 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3374 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3375 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3377 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3378 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3380 ConfigValueInt(NULL
, "cf_level", &device
->Bs2bLevel
);
3382 device
->NumStereoSources
= 1;
3383 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3385 device
->Synth
= SynthCreate(device
);
3388 DELETE_OBJ(device
->Backend
);
3390 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3394 // Find a playback device to open
3395 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3397 DELETE_OBJ(device
->Synth
);
3398 DELETE_OBJ(device
->Backend
);
3400 alcSetError(NULL
, err
);
3404 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3406 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3407 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3409 device
->DefaultSlot
= NULL
;
3410 ERR("Failed to initialize the default effect slot\n");
3412 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3414 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3415 device
->DefaultSlot
= NULL
;
3417 ERR("Failed to initialize the default effect\n");
3422 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3424 device
->next
= head
;
3425 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3428 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3434 * Closes the given device.
3436 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3438 ALCdevice
*list
, *origdev
, *nextdev
;
3442 list
= ATOMIC_LOAD(&DeviceList
);
3446 } while((list
=list
->next
) != NULL
);
3447 if(!list
|| list
->Type
== Capture
)
3449 alcSetError(list
, ALC_INVALID_DEVICE
);
3455 nextdev
= device
->next
;
3456 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3461 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3465 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3468 ALCcontext
*next
= ctx
->next
;
3469 WARN("Releasing context %p\n", ctx
);
3470 ReleaseContext(ctx
, device
);
3473 if((device
->Flags
&DEVICE_RUNNING
))
3474 V0(device
->Backend
,stop
)();
3475 device
->Flags
&= ~DEVICE_RUNNING
;
3477 ALCdevice_DecRef(device
);
3483 /************************************************
3484 * ALC capture functions
3485 ************************************************/
3486 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3488 ALCdevice
*device
= NULL
;
3493 if(!CaptureBackend
.name
)
3495 alcSetError(NULL
, ALC_INVALID_VALUE
);
3501 alcSetError(NULL
, ALC_INVALID_VALUE
);
3505 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3508 device
= al_calloc(16, sizeof(ALCdevice
));
3511 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3516 InitRef(&device
->ref
, 1);
3517 device
->Connected
= ALC_TRUE
;
3518 device
->Type
= Capture
;
3520 AL_STRING_INIT(device
->DeviceName
);
3522 InitUIntMap(&device
->BufferMap
, ~0);
3523 InitUIntMap(&device
->EffectMap
, ~0);
3524 InitUIntMap(&device
->FilterMap
, ~0);
3525 InitUIntMap(&device
->SfontMap
, ~0);
3526 InitUIntMap(&device
->PresetMap
, ~0);
3527 InitUIntMap(&device
->FontsoundMap
, ~0);
3529 if(!CaptureBackend
.getFactory
)
3530 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3531 ALCbackend_Capture
);
3534 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3535 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3537 if(!device
->Backend
)
3540 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3544 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3545 device
->Frequency
= frequency
;
3547 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3548 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3551 alcSetError(NULL
, ALC_INVALID_ENUM
);
3555 device
->UpdateSize
= samples
;
3556 device
->NumUpdates
= 1;
3558 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3561 alcSetError(NULL
, err
);
3566 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3568 device
->next
= head
;
3569 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3572 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3576 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3578 ALCdevice
*list
, *next
, *nextdev
;
3581 list
= ATOMIC_LOAD(&DeviceList
);
3585 } while((list
=list
->next
) != NULL
);
3586 if(!list
|| list
->Type
!= Capture
)
3588 alcSetError(list
, ALC_INVALID_DEVICE
);
3594 nextdev
= device
->next
;
3595 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3600 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3604 ALCdevice_DecRef(device
);
3609 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3611 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3612 alcSetError(device
, ALC_INVALID_DEVICE
);
3615 ALCdevice_Lock(device
);
3616 if(device
->Connected
)
3618 if(!(device
->Flags
&DEVICE_RUNNING
))
3619 V0(device
->Backend
,start
)();
3620 device
->Flags
|= DEVICE_RUNNING
;
3622 ALCdevice_Unlock(device
);
3625 if(device
) ALCdevice_DecRef(device
);
3628 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3630 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3631 alcSetError(device
, ALC_INVALID_DEVICE
);
3634 ALCdevice_Lock(device
);
3635 if((device
->Flags
&DEVICE_RUNNING
))
3636 V0(device
->Backend
,stop
)();
3637 device
->Flags
&= ~DEVICE_RUNNING
;
3638 ALCdevice_Unlock(device
);
3641 if(device
) ALCdevice_DecRef(device
);
3644 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3646 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3647 alcSetError(device
, ALC_INVALID_DEVICE
);
3650 ALCenum err
= ALC_INVALID_VALUE
;
3652 ALCdevice_Lock(device
);
3653 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3654 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3655 ALCdevice_Unlock(device
);
3657 if(err
!= ALC_NO_ERROR
)
3658 alcSetError(device
, err
);
3660 if(device
) ALCdevice_DecRef(device
);
3664 /************************************************
3665 * ALC loopback functions
3666 ************************************************/
3668 /* alcLoopbackOpenDeviceSOFT
3670 * Open a loopback device, for manual rendering.
3672 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3674 ALCbackendFactory
*factory
;
3679 /* Make sure the device name, if specified, is us. */
3680 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3682 alcSetError(NULL
, ALC_INVALID_VALUE
);
3686 device
= al_calloc(16, sizeof(ALCdevice
));
3689 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3694 InitRef(&device
->ref
, 1);
3695 device
->Connected
= ALC_TRUE
;
3696 device
->Type
= Loopback
;
3697 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3700 device
->Bs2b
= NULL
;
3701 device
->Bs2bLevel
= 0;
3702 AL_STRING_INIT(device
->DeviceName
);
3704 ATOMIC_INIT(&device
->ContextList
, NULL
);
3706 device
->ClockBase
= 0;
3707 device
->SamplesDone
= 0;
3709 device
->MaxNoOfSources
= 256;
3710 device
->AuxiliaryEffectSlotMax
= 4;
3711 device
->NumAuxSends
= MAX_SENDS
;
3713 InitUIntMap(&device
->BufferMap
, ~0);
3714 InitUIntMap(&device
->EffectMap
, ~0);
3715 InitUIntMap(&device
->FilterMap
, ~0);
3716 InitUIntMap(&device
->SfontMap
, ~0);
3717 InitUIntMap(&device
->PresetMap
, ~0);
3718 InitUIntMap(&device
->FontsoundMap
, ~0);
3720 factory
= ALCloopbackFactory_getFactory();
3721 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3722 if(!device
->Backend
)
3725 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3730 device
->NumUpdates
= 0;
3731 device
->UpdateSize
= 0;
3733 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3734 device
->FmtChans
= DevFmtChannelsDefault
;
3735 device
->FmtType
= DevFmtTypeDefault
;
3737 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3738 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3740 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3741 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3743 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3744 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3746 device
->NumStereoSources
= 1;
3747 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3749 device
->Synth
= SynthCreate(device
);
3752 DELETE_OBJ(device
->Backend
);
3754 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3758 // Open the "backend"
3759 V(device
->Backend
,open
)("Loopback");
3762 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3764 device
->next
= head
;
3765 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3768 TRACE("Created device %p\n", device
);
3772 /* alcIsRenderFormatSupportedSOFT
3774 * Determines if the loopback device supports the given format for rendering.
3776 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3778 ALCboolean ret
= ALC_FALSE
;
3780 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3781 alcSetError(device
, ALC_INVALID_DEVICE
);
3783 alcSetError(device
, ALC_INVALID_VALUE
);
3786 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3787 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3788 freq
>= MIN_OUTPUT_RATE
)
3791 if(device
) ALCdevice_DecRef(device
);
3796 /* alcRenderSamplesSOFT
3798 * Renders some samples into a buffer, using the format last set by the
3799 * attributes given to alcCreateContext.
3801 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3803 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3804 alcSetError(device
, ALC_INVALID_DEVICE
);
3805 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3806 alcSetError(device
, ALC_INVALID_VALUE
);
3808 aluMixData(device
, buffer
, samples
);
3809 if(device
) ALCdevice_DecRef(device
);
3813 /************************************************
3814 * ALC DSP pause/resume functions
3815 ************************************************/
3817 /* alcDevicePauseSOFT
3819 * Pause the DSP to stop audio processing.
3821 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3823 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3824 alcSetError(device
, ALC_INVALID_DEVICE
);
3828 if((device
->Flags
&DEVICE_RUNNING
))
3829 V0(device
->Backend
,stop
)();
3830 device
->Flags
&= ~DEVICE_RUNNING
;
3831 device
->Flags
|= DEVICE_PAUSED
;
3834 if(device
) ALCdevice_DecRef(device
);
3837 /* alcDeviceResumeSOFT
3839 * Resume the DSP to restart audio processing.
3841 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3843 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3844 alcSetError(device
, ALC_INVALID_DEVICE
);
3848 if((device
->Flags
&DEVICE_PAUSED
))
3850 device
->Flags
&= ~DEVICE_PAUSED
;
3851 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3853 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3854 device
->Flags
|= DEVICE_RUNNING
;
3857 alcSetError(device
, ALC_INVALID_DEVICE
);
3858 ALCdevice_Lock(device
);
3859 aluHandleDisconnect(device
);
3860 ALCdevice_Unlock(device
);
3866 if(device
) ALCdevice_DecRef(device
);