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
[] = {
65 { "jack", ALCjackBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
67 #ifdef HAVE_PULSEAUDIO
68 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
71 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
74 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
77 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
80 { "solaris", NULL
, alc_solaris_init
, alc_solaris_deinit
, alc_solaris_probe
, EmptyFuncs
},
83 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
86 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
89 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
92 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
95 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
98 { "port", NULL
, alc_pa_init
, alc_pa_deinit
, alc_pa_probe
, EmptyFuncs
},
101 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
104 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
106 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
109 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
113 static struct BackendInfo PlaybackBackend
;
114 static struct BackendInfo CaptureBackend
;
117 /************************************************
118 * Functions, enums, and errors
119 ************************************************/
120 typedef struct ALCfunction
{
121 const ALCchar
*funcName
;
125 typedef struct ALCenums
{
126 const ALCchar
*enumName
;
130 #define DECL(x) { #x, (ALCvoid*)(x) }
131 static const ALCfunction alcFunctions
[] = {
132 DECL(alcCreateContext
),
133 DECL(alcMakeContextCurrent
),
134 DECL(alcProcessContext
),
135 DECL(alcSuspendContext
),
136 DECL(alcDestroyContext
),
137 DECL(alcGetCurrentContext
),
138 DECL(alcGetContextsDevice
),
140 DECL(alcCloseDevice
),
142 DECL(alcIsExtensionPresent
),
143 DECL(alcGetProcAddress
),
144 DECL(alcGetEnumValue
),
146 DECL(alcGetIntegerv
),
147 DECL(alcCaptureOpenDevice
),
148 DECL(alcCaptureCloseDevice
),
149 DECL(alcCaptureStart
),
150 DECL(alcCaptureStop
),
151 DECL(alcCaptureSamples
),
153 DECL(alcSetThreadContext
),
154 DECL(alcGetThreadContext
),
156 DECL(alcLoopbackOpenDeviceSOFT
),
157 DECL(alcIsRenderFormatSupportedSOFT
),
158 DECL(alcRenderSamplesSOFT
),
160 DECL(alcDevicePauseSOFT
),
161 DECL(alcDeviceResumeSOFT
),
163 DECL(alcGetInteger64vSOFT
),
178 DECL(alIsExtensionPresent
),
179 DECL(alGetProcAddress
),
180 DECL(alGetEnumValue
),
187 DECL(alGetListenerf
),
188 DECL(alGetListener3f
),
189 DECL(alGetListenerfv
),
190 DECL(alGetListeneri
),
191 DECL(alGetListener3i
),
192 DECL(alGetListeneriv
),
194 DECL(alDeleteSources
),
210 DECL(alSourceRewindv
),
211 DECL(alSourcePausev
),
214 DECL(alSourceRewind
),
216 DECL(alSourceQueueBuffers
),
217 DECL(alSourceUnqueueBuffers
),
219 DECL(alDeleteBuffers
),
234 DECL(alDopplerFactor
),
235 DECL(alDopplerVelocity
),
236 DECL(alSpeedOfSound
),
237 DECL(alDistanceModel
),
240 DECL(alDeleteFilters
),
251 DECL(alDeleteEffects
),
261 DECL(alGenAuxiliaryEffectSlots
),
262 DECL(alDeleteAuxiliaryEffectSlots
),
263 DECL(alIsAuxiliaryEffectSlot
),
264 DECL(alAuxiliaryEffectSloti
),
265 DECL(alAuxiliaryEffectSlotiv
),
266 DECL(alAuxiliaryEffectSlotf
),
267 DECL(alAuxiliaryEffectSlotfv
),
268 DECL(alGetAuxiliaryEffectSloti
),
269 DECL(alGetAuxiliaryEffectSlotiv
),
270 DECL(alGetAuxiliaryEffectSlotf
),
271 DECL(alGetAuxiliaryEffectSlotfv
),
273 DECL(alBufferSubDataSOFT
),
275 DECL(alBufferSamplesSOFT
),
276 DECL(alBufferSubSamplesSOFT
),
277 DECL(alGetBufferSamplesSOFT
),
278 DECL(alIsBufferFormatSupportedSOFT
),
280 DECL(alDeferUpdatesSOFT
),
281 DECL(alProcessUpdatesSOFT
),
284 DECL(alSource3dSOFT
),
285 DECL(alSourcedvSOFT
),
286 DECL(alGetSourcedSOFT
),
287 DECL(alGetSource3dSOFT
),
288 DECL(alGetSourcedvSOFT
),
289 DECL(alSourcei64SOFT
),
290 DECL(alSource3i64SOFT
),
291 DECL(alSourcei64vSOFT
),
292 DECL(alGetSourcei64SOFT
),
293 DECL(alGetSource3i64SOFT
),
294 DECL(alGetSourcei64vSOFT
),
296 DECL(alGenSoundfontsSOFT
),
297 DECL(alDeleteSoundfontsSOFT
),
298 DECL(alIsSoundfontSOFT
),
299 DECL(alGetSoundfontivSOFT
),
300 DECL(alSoundfontPresetsSOFT
),
301 DECL(alGenPresetsSOFT
),
302 DECL(alDeletePresetsSOFT
),
303 DECL(alIsPresetSOFT
),
305 DECL(alPresetivSOFT
),
306 DECL(alGetPresetivSOFT
),
307 DECL(alPresetFontsoundsSOFT
),
308 DECL(alGenFontsoundsSOFT
),
309 DECL(alDeleteFontsoundsSOFT
),
310 DECL(alIsFontsoundSOFT
),
311 DECL(alFontsoundiSOFT
),
312 DECL(alFontsound2iSOFT
),
313 DECL(alFontsoundivSOFT
),
314 DECL(alGetFontsoundivSOFT
),
315 DECL(alFontsoundModulatoriSOFT
),
316 DECL(alGetFontsoundModulatorivSOFT
),
317 DECL(alMidiSoundfontSOFT
),
318 DECL(alMidiSoundfontvSOFT
),
319 DECL(alMidiEventSOFT
),
320 DECL(alMidiSysExSOFT
),
321 DECL(alMidiPlaySOFT
),
322 DECL(alMidiPauseSOFT
),
323 DECL(alMidiStopSOFT
),
324 DECL(alMidiResetSOFT
),
325 DECL(alMidiGainSOFT
),
326 DECL(alGetInteger64SOFT
),
327 DECL(alGetInteger64vSOFT
),
328 DECL(alLoadSoundfontSOFT
),
334 #define DECL(x) { #x, (x) }
335 static const ALCenums enumeration
[] = {
340 DECL(ALC_MAJOR_VERSION
),
341 DECL(ALC_MINOR_VERSION
),
342 DECL(ALC_ATTRIBUTES_SIZE
),
343 DECL(ALC_ALL_ATTRIBUTES
),
344 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
345 DECL(ALC_DEVICE_SPECIFIER
),
346 DECL(ALC_ALL_DEVICES_SPECIFIER
),
347 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
348 DECL(ALC_EXTENSIONS
),
352 DECL(ALC_MONO_SOURCES
),
353 DECL(ALC_STEREO_SOURCES
),
354 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
355 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
356 DECL(ALC_CAPTURE_SAMPLES
),
359 DECL(ALC_EFX_MAJOR_VERSION
),
360 DECL(ALC_EFX_MINOR_VERSION
),
361 DECL(ALC_MAX_AUXILIARY_SENDS
),
363 DECL(ALC_FORMAT_CHANNELS_SOFT
),
364 DECL(ALC_FORMAT_TYPE_SOFT
),
367 DECL(ALC_STEREO_SOFT
),
369 DECL(ALC_5POINT1_SOFT
),
370 DECL(ALC_6POINT1_SOFT
),
371 DECL(ALC_7POINT1_SOFT
),
374 DECL(ALC_UNSIGNED_BYTE_SOFT
),
375 DECL(ALC_SHORT_SOFT
),
376 DECL(ALC_UNSIGNED_SHORT_SOFT
),
378 DECL(ALC_UNSIGNED_INT_SOFT
),
379 DECL(ALC_FLOAT_SOFT
),
382 DECL(ALC_INVALID_DEVICE
),
383 DECL(ALC_INVALID_CONTEXT
),
384 DECL(ALC_INVALID_ENUM
),
385 DECL(ALC_INVALID_VALUE
),
386 DECL(ALC_OUT_OF_MEMORY
),
394 DECL(AL_SOURCE_RELATIVE
),
395 DECL(AL_CONE_INNER_ANGLE
),
396 DECL(AL_CONE_OUTER_ANGLE
),
406 DECL(AL_ORIENTATION
),
407 DECL(AL_REFERENCE_DISTANCE
),
408 DECL(AL_ROLLOFF_FACTOR
),
409 DECL(AL_CONE_OUTER_GAIN
),
410 DECL(AL_MAX_DISTANCE
),
412 DECL(AL_SAMPLE_OFFSET
),
413 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
414 DECL(AL_BYTE_OFFSET
),
415 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
416 DECL(AL_SOURCE_TYPE
),
419 DECL(AL_UNDETERMINED
),
420 DECL(AL_METERS_PER_UNIT
),
421 DECL(AL_DIRECT_CHANNELS_SOFT
),
423 DECL(AL_DIRECT_FILTER
),
424 DECL(AL_AUXILIARY_SEND_FILTER
),
425 DECL(AL_AIR_ABSORPTION_FACTOR
),
426 DECL(AL_ROOM_ROLLOFF_FACTOR
),
427 DECL(AL_CONE_OUTER_GAINHF
),
428 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
429 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
430 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
432 DECL(AL_SOURCE_STATE
),
438 DECL(AL_BUFFERS_QUEUED
),
439 DECL(AL_BUFFERS_PROCESSED
),
441 DECL(AL_FORMAT_MONO8
),
442 DECL(AL_FORMAT_MONO16
),
443 DECL(AL_FORMAT_MONO_FLOAT32
),
444 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
445 DECL(AL_FORMAT_STEREO8
),
446 DECL(AL_FORMAT_STEREO16
),
447 DECL(AL_FORMAT_STEREO_FLOAT32
),
448 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
449 DECL(AL_FORMAT_MONO_IMA4
),
450 DECL(AL_FORMAT_STEREO_IMA4
),
451 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
452 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
453 DECL(AL_FORMAT_QUAD8_LOKI
),
454 DECL(AL_FORMAT_QUAD16_LOKI
),
455 DECL(AL_FORMAT_QUAD8
),
456 DECL(AL_FORMAT_QUAD16
),
457 DECL(AL_FORMAT_QUAD32
),
458 DECL(AL_FORMAT_51CHN8
),
459 DECL(AL_FORMAT_51CHN16
),
460 DECL(AL_FORMAT_51CHN32
),
461 DECL(AL_FORMAT_61CHN8
),
462 DECL(AL_FORMAT_61CHN16
),
463 DECL(AL_FORMAT_61CHN32
),
464 DECL(AL_FORMAT_71CHN8
),
465 DECL(AL_FORMAT_71CHN16
),
466 DECL(AL_FORMAT_71CHN32
),
467 DECL(AL_FORMAT_REAR8
),
468 DECL(AL_FORMAT_REAR16
),
469 DECL(AL_FORMAT_REAR32
),
470 DECL(AL_FORMAT_MONO_MULAW
),
471 DECL(AL_FORMAT_MONO_MULAW_EXT
),
472 DECL(AL_FORMAT_STEREO_MULAW
),
473 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
474 DECL(AL_FORMAT_QUAD_MULAW
),
475 DECL(AL_FORMAT_51CHN_MULAW
),
476 DECL(AL_FORMAT_61CHN_MULAW
),
477 DECL(AL_FORMAT_71CHN_MULAW
),
478 DECL(AL_FORMAT_REAR_MULAW
),
479 DECL(AL_FORMAT_MONO_ALAW_EXT
),
480 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
483 DECL(AL_MONO16_SOFT
),
484 DECL(AL_MONO32F_SOFT
),
485 DECL(AL_STEREO8_SOFT
),
486 DECL(AL_STEREO16_SOFT
),
487 DECL(AL_STEREO32F_SOFT
),
489 DECL(AL_QUAD16_SOFT
),
490 DECL(AL_QUAD32F_SOFT
),
492 DECL(AL_REAR16_SOFT
),
493 DECL(AL_REAR32F_SOFT
),
494 DECL(AL_5POINT1_8_SOFT
),
495 DECL(AL_5POINT1_16_SOFT
),
496 DECL(AL_5POINT1_32F_SOFT
),
497 DECL(AL_6POINT1_8_SOFT
),
498 DECL(AL_6POINT1_16_SOFT
),
499 DECL(AL_6POINT1_32F_SOFT
),
500 DECL(AL_7POINT1_8_SOFT
),
501 DECL(AL_7POINT1_16_SOFT
),
502 DECL(AL_7POINT1_32F_SOFT
),
503 DECL(AL_FORMAT_BFORMAT2D_8
),
504 DECL(AL_FORMAT_BFORMAT2D_16
),
505 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
506 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
507 DECL(AL_FORMAT_BFORMAT3D_8
),
508 DECL(AL_FORMAT_BFORMAT3D_16
),
509 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
510 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
513 DECL(AL_STEREO_SOFT
),
516 DECL(AL_5POINT1_SOFT
),
517 DECL(AL_6POINT1_SOFT
),
518 DECL(AL_7POINT1_SOFT
),
521 DECL(AL_UNSIGNED_BYTE_SOFT
),
523 DECL(AL_UNSIGNED_SHORT_SOFT
),
525 DECL(AL_UNSIGNED_INT_SOFT
),
527 DECL(AL_DOUBLE_SOFT
),
529 DECL(AL_UNSIGNED_BYTE3_SOFT
),
535 DECL(AL_INTERNAL_FORMAT_SOFT
),
536 DECL(AL_BYTE_LENGTH_SOFT
),
537 DECL(AL_SAMPLE_LENGTH_SOFT
),
538 DECL(AL_SEC_LENGTH_SOFT
),
539 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
540 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
547 DECL(AL_INVALID_NAME
),
548 DECL(AL_INVALID_ENUM
),
549 DECL(AL_INVALID_VALUE
),
550 DECL(AL_INVALID_OPERATION
),
551 DECL(AL_OUT_OF_MEMORY
),
558 DECL(AL_DOPPLER_FACTOR
),
559 DECL(AL_DOPPLER_VELOCITY
),
560 DECL(AL_DISTANCE_MODEL
),
561 DECL(AL_SPEED_OF_SOUND
),
562 DECL(AL_SOURCE_DISTANCE_MODEL
),
563 DECL(AL_DEFERRED_UPDATES_SOFT
),
565 DECL(AL_INVERSE_DISTANCE
),
566 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
567 DECL(AL_LINEAR_DISTANCE
),
568 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
569 DECL(AL_EXPONENT_DISTANCE
),
570 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
572 DECL(AL_FILTER_TYPE
),
573 DECL(AL_FILTER_NULL
),
574 DECL(AL_FILTER_LOWPASS
),
575 DECL(AL_FILTER_HIGHPASS
),
576 DECL(AL_FILTER_BANDPASS
),
578 DECL(AL_LOWPASS_GAIN
),
579 DECL(AL_LOWPASS_GAINHF
),
581 DECL(AL_HIGHPASS_GAIN
),
582 DECL(AL_HIGHPASS_GAINLF
),
584 DECL(AL_BANDPASS_GAIN
),
585 DECL(AL_BANDPASS_GAINHF
),
586 DECL(AL_BANDPASS_GAINLF
),
588 DECL(AL_EFFECT_TYPE
),
589 DECL(AL_EFFECT_NULL
),
590 DECL(AL_EFFECT_REVERB
),
591 DECL(AL_EFFECT_EAXREVERB
),
592 DECL(AL_EFFECT_CHORUS
),
593 DECL(AL_EFFECT_DISTORTION
),
594 DECL(AL_EFFECT_ECHO
),
595 DECL(AL_EFFECT_FLANGER
),
597 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
598 DECL(AL_EFFECT_VOCAL_MORPHER
),
599 DECL(AL_EFFECT_PITCH_SHIFTER
),
601 DECL(AL_EFFECT_RING_MODULATOR
),
603 DECL(AL_EFFECT_AUTOWAH
),
605 DECL(AL_EFFECT_COMPRESSOR
),
606 DECL(AL_EFFECT_EQUALIZER
),
607 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
608 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
610 DECL(AL_EAXREVERB_DENSITY
),
611 DECL(AL_EAXREVERB_DIFFUSION
),
612 DECL(AL_EAXREVERB_GAIN
),
613 DECL(AL_EAXREVERB_GAINHF
),
614 DECL(AL_EAXREVERB_GAINLF
),
615 DECL(AL_EAXREVERB_DECAY_TIME
),
616 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
617 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
618 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
619 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
620 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
621 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
622 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
623 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
624 DECL(AL_EAXREVERB_ECHO_TIME
),
625 DECL(AL_EAXREVERB_ECHO_DEPTH
),
626 DECL(AL_EAXREVERB_MODULATION_TIME
),
627 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
628 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
629 DECL(AL_EAXREVERB_HFREFERENCE
),
630 DECL(AL_EAXREVERB_LFREFERENCE
),
631 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
632 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
634 DECL(AL_REVERB_DENSITY
),
635 DECL(AL_REVERB_DIFFUSION
),
636 DECL(AL_REVERB_GAIN
),
637 DECL(AL_REVERB_GAINHF
),
638 DECL(AL_REVERB_DECAY_TIME
),
639 DECL(AL_REVERB_DECAY_HFRATIO
),
640 DECL(AL_REVERB_REFLECTIONS_GAIN
),
641 DECL(AL_REVERB_REFLECTIONS_DELAY
),
642 DECL(AL_REVERB_LATE_REVERB_GAIN
),
643 DECL(AL_REVERB_LATE_REVERB_DELAY
),
644 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
645 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
646 DECL(AL_REVERB_DECAY_HFLIMIT
),
648 DECL(AL_CHORUS_WAVEFORM
),
649 DECL(AL_CHORUS_PHASE
),
650 DECL(AL_CHORUS_RATE
),
651 DECL(AL_CHORUS_DEPTH
),
652 DECL(AL_CHORUS_FEEDBACK
),
653 DECL(AL_CHORUS_DELAY
),
655 DECL(AL_DISTORTION_EDGE
),
656 DECL(AL_DISTORTION_GAIN
),
657 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
658 DECL(AL_DISTORTION_EQCENTER
),
659 DECL(AL_DISTORTION_EQBANDWIDTH
),
662 DECL(AL_ECHO_LRDELAY
),
663 DECL(AL_ECHO_DAMPING
),
664 DECL(AL_ECHO_FEEDBACK
),
665 DECL(AL_ECHO_SPREAD
),
667 DECL(AL_FLANGER_WAVEFORM
),
668 DECL(AL_FLANGER_PHASE
),
669 DECL(AL_FLANGER_RATE
),
670 DECL(AL_FLANGER_DEPTH
),
671 DECL(AL_FLANGER_FEEDBACK
),
672 DECL(AL_FLANGER_DELAY
),
674 DECL(AL_RING_MODULATOR_FREQUENCY
),
675 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
676 DECL(AL_RING_MODULATOR_WAVEFORM
),
679 DECL(AL_AUTOWAH_ATTACK_TIME
),
680 DECL(AL_AUTOWAH_PEAK_GAIN
),
681 DECL(AL_AUTOWAH_RELEASE_TIME
),
682 DECL(AL_AUTOWAH_RESONANCE
),
685 DECL(AL_COMPRESSOR_ONOFF
),
687 DECL(AL_EQUALIZER_LOW_GAIN
),
688 DECL(AL_EQUALIZER_LOW_CUTOFF
),
689 DECL(AL_EQUALIZER_MID1_GAIN
),
690 DECL(AL_EQUALIZER_MID1_CENTER
),
691 DECL(AL_EQUALIZER_MID1_WIDTH
),
692 DECL(AL_EQUALIZER_MID2_GAIN
),
693 DECL(AL_EQUALIZER_MID2_CENTER
),
694 DECL(AL_EQUALIZER_MID2_WIDTH
),
695 DECL(AL_EQUALIZER_HIGH_GAIN
),
696 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
698 DECL(AL_DEDICATED_GAIN
),
704 static const ALCchar alcNoError
[] = "No Error";
705 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
706 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
707 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
708 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
709 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
712 /************************************************
714 ************************************************/
716 /* Enumerated device names */
717 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
719 static al_string alcAllDevicesList
;
720 static al_string alcCaptureDeviceList
;
722 /* Default is always the first in the list */
723 static ALCchar
*alcDefaultAllDevicesSpecifier
;
724 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
726 /* Default context extensions */
727 static const ALchar alExtList
[] =
728 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
729 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
730 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
731 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
732 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
733 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
734 "AL_SOFT_source_latency AL_SOFT_source_length";
736 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
738 /* Thread-local current context */
739 static altss_t LocalContext
;
740 /* Process-wide current context */
741 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
743 /* Mixing thread piority level */
748 enum LogLevel LogLevel
= LogWarning
;
750 enum LogLevel LogLevel
= LogError
;
753 /* Flag to trap ALC device errors */
754 static ALCboolean TrapALCError
= ALC_FALSE
;
756 /* One-time configuration init control */
757 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
759 /* Default effect that applies to sources that don't have an effect on send 0 */
760 static ALeffect DefaultEffect
;
762 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
765 static ALCboolean SuspendDefers
= ALC_TRUE
;
768 /************************************************
770 ************************************************/
771 static const ALCchar alcNoDeviceExtList
[] =
772 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
773 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
774 static const ALCchar alcExtensionList
[] =
775 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
776 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
777 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
778 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
779 static const ALCint alcMajorVersion
= 1;
780 static const ALCint alcMinorVersion
= 1;
782 static const ALCint alcEFXMajorVersion
= 1;
783 static const ALCint alcEFXMinorVersion
= 0;
786 /************************************************
788 ************************************************/
789 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
791 static almtx_t ListLock
;
792 static inline void LockLists(void)
794 int lockret
= almtx_lock(&ListLock
);
795 assert(lockret
== althrd_success
);
797 static inline void UnlockLists(void)
799 int unlockret
= almtx_unlock(&ListLock
);
800 assert(unlockret
== althrd_success
);
803 /************************************************
804 * Library initialization
805 ************************************************/
807 static void alc_init(void);
808 static void alc_deinit(void);
809 static void alc_deinit_safe(void);
811 #ifndef AL_LIBTYPE_STATIC
812 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
816 case DLL_PROCESS_ATTACH
:
817 /* Pin the DLL so we won't get unloaded until the process terminates */
818 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
819 (WCHAR
*)hModule
, &hModule
);
823 case DLL_THREAD_DETACH
:
826 case DLL_PROCESS_DETACH
:
835 #elif defined(_MSC_VER)
836 #pragma section(".CRT$XCU",read)
837 static void alc_constructor(void);
838 static void alc_destructor(void);
839 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
841 static void alc_constructor(void)
843 atexit(alc_destructor
);
847 static void alc_destructor(void)
851 #elif defined(HAVE_GCC_DESTRUCTOR)
852 static void alc_init(void) __attribute__((constructor
));
853 static void alc_deinit(void) __attribute__((destructor
));
855 #error "No static initialization available on this platform!"
858 #elif defined(HAVE_GCC_DESTRUCTOR)
860 static void alc_init(void) __attribute__((constructor
));
861 static void alc_deinit(void) __attribute__((destructor
));
864 #error "No global initialization available on this platform!"
867 static void ReleaseThreadCtx(void *ptr
);
868 static void alc_init(void)
875 AL_STRING_INIT(alcAllDevicesList
);
876 AL_STRING_INIT(alcCaptureDeviceList
);
878 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
879 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
882 str
= getenv("__ALSOFT_REVERSE_Z");
883 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
886 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
887 assert(ret
== althrd_success
);
889 ret
= almtx_init(&ListLock
, almtx_recursive
);
890 assert(ret
== althrd_success
);
895 static void alc_initconfig(void)
897 const char *devs
, *str
;
902 str
= getenv("ALSOFT_LOGLEVEL");
905 long lvl
= strtol(str
, NULL
, 0);
906 if(lvl
>= NoLog
&& lvl
<= LogRef
)
910 str
= getenv("ALSOFT_LOGFILE");
913 FILE *logfile
= al_fopen(str
, "wt");
914 if(logfile
) LogFile
= logfile
;
915 else ERR("Failed to open log file '%s'\n", str
);
920 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
921 for(i
= 1;BackendList
[i
].name
;i
++)
922 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
923 TRACE("Supported backends: %s\n", buf
);
927 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
930 if(strcasecmp(str
, "ignore") == 0)
932 SuspendDefers
= ALC_FALSE
;
933 TRACE("Selected context suspend behavior, \"ignore\"\n");
936 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
940 #if defined(HAVE_SSE4_1)
941 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE4_1
;
942 #elif defined(HAVE_SSE2)
943 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
944 #elif defined(HAVE_SSE)
945 capfilter
|= CPU_CAP_SSE
;
948 capfilter
|= CPU_CAP_NEON
;
950 if(ConfigValueStr(NULL
, "disable-cpu-exts", &str
))
952 if(strcasecmp(str
, "all") == 0)
957 const char *next
= str
;
961 while(isspace(str
[0]))
963 next
= strchr(str
, ',');
965 if(!str
[0] || str
[0] == ',')
968 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
969 while(len
> 0 && isspace(str
[len
-1]))
971 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
972 capfilter
&= ~CPU_CAP_SSE
;
973 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
974 capfilter
&= ~CPU_CAP_SSE2
;
975 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
976 capfilter
&= ~CPU_CAP_SSE4_1
;
977 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
978 capfilter
&= ~CPU_CAP_NEON
;
980 WARN("Invalid CPU extension \"%s\"\n", str
);
984 FillCPUCaps(capfilter
);
991 ConfigValueInt(NULL
, "rt-prio", &RTPrioLevel
);
993 if(ConfigValueStr(NULL
, "resampler", &str
))
995 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
996 DefaultResampler
= PointResampler
;
997 else if(strcasecmp(str
, "linear") == 0)
998 DefaultResampler
= LinearResampler
;
999 else if(strcasecmp(str
, "cubic") == 0)
1000 DefaultResampler
= CubicResampler
;
1005 n
= strtol(str
, &end
, 0);
1006 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== CubicResampler
))
1007 DefaultResampler
= n
;
1009 WARN("Invalid resampler: %s\n", str
);
1012 aluInitResamplers();
1014 str
= getenv("ALSOFT_TRAP_ERROR");
1015 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1017 TrapALError
= AL_TRUE
;
1018 TrapALCError
= AL_TRUE
;
1022 str
= getenv("ALSOFT_TRAP_AL_ERROR");
1023 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1024 TrapALError
= AL_TRUE
;
1025 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
1027 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1028 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1029 TrapALCError
= ALC_TRUE
;
1030 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
1033 if(ConfigValueFloat("reverb", "boost", &valf
))
1034 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1036 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
1038 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1039 ConfigValueStr(NULL
, "drivers", &devs
))
1043 const char *next
= devs
;
1044 int endlist
, delitem
;
1049 while(isspace(devs
[0]))
1051 next
= strchr(devs
, ',');
1053 delitem
= (devs
[0] == '-');
1054 if(devs
[0] == '-') devs
++;
1056 if(!devs
[0] || devs
[0] == ',')
1063 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1064 while(len
> 0 && isspace(devs
[len
-1]))
1066 for(n
= i
;BackendList
[n
].name
;n
++)
1068 if(len
== strlen(BackendList
[n
].name
) &&
1069 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1074 BackendList
[n
] = BackendList
[n
+1];
1076 } while(BackendList
[n
].name
);
1080 struct BackendInfo Bkp
= BackendList
[n
];
1083 BackendList
[n
] = BackendList
[n
-1];
1086 BackendList
[n
] = Bkp
;
1097 BackendList
[i
].name
= NULL
;
1098 BackendList
[i
].getFactory
= NULL
;
1099 BackendList
[i
].Init
= NULL
;
1100 BackendList
[i
].Deinit
= NULL
;
1101 BackendList
[i
].Probe
= NULL
;
1105 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1107 if(BackendList
[i
].getFactory
)
1109 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1110 if(!V0(factory
,init
)())
1112 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1116 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1117 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1119 PlaybackBackend
= BackendList
[i
];
1120 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1122 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1124 CaptureBackend
= BackendList
[i
];
1125 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1131 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1133 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1137 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1138 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1140 PlaybackBackend
= BackendList
[i
];
1141 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1143 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1145 CaptureBackend
= BackendList
[i
];
1146 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1150 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1154 if(ConfigValueStr(NULL
, "excludefx", &str
))
1157 const char *next
= str
;
1161 next
= strchr(str
, ',');
1163 if(!str
[0] || next
== str
)
1166 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1167 for(n
= 0;EffectList
[n
].name
;n
++)
1169 if(len
== strlen(EffectList
[n
].name
) &&
1170 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1171 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1176 InitEffectFactoryMap();
1178 InitEffect(&DefaultEffect
);
1179 str
= getenv("ALSOFT_DEFAULT_REVERB");
1180 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1181 LoadReverbPreset(str
, &DefaultEffect
);
1183 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1186 /************************************************
1187 * Library deinitialization
1188 ************************************************/
1189 static void alc_cleanup(void)
1193 AL_STRING_DEINIT(alcAllDevicesList
);
1194 AL_STRING_DEINIT(alcCaptureDeviceList
);
1196 free(alcDefaultAllDevicesSpecifier
);
1197 alcDefaultAllDevicesSpecifier
= NULL
;
1198 free(alcCaptureDefaultDeviceSpecifier
);
1199 alcCaptureDefaultDeviceSpecifier
= NULL
;
1201 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1206 } while((dev
=dev
->next
) != NULL
);
1207 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1210 DeinitEffectFactoryMap();
1213 static void alc_deinit_safe(void)
1221 almtx_destroy(&ListLock
);
1222 altss_delete(LocalContext
);
1224 if(LogFile
!= stderr
)
1229 static void alc_deinit(void)
1235 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1236 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1238 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1240 if(!BackendList
[i
].getFactory
)
1241 BackendList
[i
].Deinit();
1244 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1245 V0(factory
,deinit
)();
1249 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1250 V0(factory
,deinit
)();
1257 /************************************************
1258 * Device enumeration
1259 ************************************************/
1260 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1265 al_string_clear(list
);
1267 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1269 if(!PlaybackBackend
.getFactory
)
1270 PlaybackBackend
.Probe(type
);
1273 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1274 V(factory
,probe
)(type
);
1277 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1279 if(!CaptureBackend
.getFactory
)
1280 CaptureBackend
.Probe(type
);
1283 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1284 V(factory
,probe
)(type
);
1289 static void ProbeAllDevicesList(void)
1290 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1291 static void ProbeCaptureDeviceList(void)
1292 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1294 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1296 size_t len
= strlen(name
);
1298 al_string_append_range(devnames
, name
, name
+len
+1);
1300 void AppendAllDevicesList(const ALCchar
*name
)
1301 { AppendDevice(name
, &alcAllDevicesList
); }
1302 void AppendCaptureDeviceList(const ALCchar
*name
)
1303 { AppendDevice(name
, &alcCaptureDeviceList
); }
1306 /************************************************
1307 * Device format information
1308 ************************************************/
1309 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1313 case DevFmtByte
: return "Signed Byte";
1314 case DevFmtUByte
: return "Unsigned Byte";
1315 case DevFmtShort
: return "Signed Short";
1316 case DevFmtUShort
: return "Unsigned Short";
1317 case DevFmtInt
: return "Signed Int";
1318 case DevFmtUInt
: return "Unsigned Int";
1319 case DevFmtFloat
: return "Float";
1321 return "(unknown type)";
1323 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1327 case DevFmtMono
: return "Mono";
1328 case DevFmtStereo
: return "Stereo";
1329 case DevFmtQuad
: return "Quadraphonic";
1330 case DevFmtX51
: return "5.1 Surround";
1331 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1332 case DevFmtX61
: return "6.1 Surround";
1333 case DevFmtX71
: return "7.1 Surround";
1334 case DevFmtBFormat3D
: return "B-Format 3D";
1336 return "(unknown channels)";
1339 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1340 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1344 case DevFmtByte
: return sizeof(ALbyte
);
1345 case DevFmtUByte
: return sizeof(ALubyte
);
1346 case DevFmtShort
: return sizeof(ALshort
);
1347 case DevFmtUShort
: return sizeof(ALushort
);
1348 case DevFmtInt
: return sizeof(ALint
);
1349 case DevFmtUInt
: return sizeof(ALuint
);
1350 case DevFmtFloat
: return sizeof(ALfloat
);
1354 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1358 case DevFmtMono
: return 1;
1359 case DevFmtStereo
: return 2;
1360 case DevFmtQuad
: return 4;
1361 case DevFmtX51
: return 6;
1362 case DevFmtX51Rear
: return 6;
1363 case DevFmtX61
: return 7;
1364 case DevFmtX71
: return 8;
1365 case DevFmtBFormat3D
: return 4;
1370 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1371 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1373 static const struct {
1375 enum DevFmtChannels channels
;
1376 enum DevFmtType type
;
1378 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1379 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1380 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1382 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1383 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1384 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1386 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1387 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1388 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1390 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1391 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1392 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1394 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1395 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1396 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1398 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1399 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1400 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1404 for(i
= 0;i
< COUNTOF(list
);i
++)
1406 if(list
[i
].format
== format
)
1408 *chans
= list
[i
].channels
;
1409 *type
= list
[i
].type
;
1417 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1422 case ALC_UNSIGNED_BYTE_SOFT
:
1423 case ALC_SHORT_SOFT
:
1424 case ALC_UNSIGNED_SHORT_SOFT
:
1426 case ALC_UNSIGNED_INT_SOFT
:
1427 case ALC_FLOAT_SOFT
:
1433 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1438 case ALC_STEREO_SOFT
:
1440 case ALC_5POINT1_SOFT
:
1441 case ALC_6POINT1_SOFT
:
1442 case ALC_7POINT1_SOFT
:
1449 /************************************************
1450 * Miscellaneous ALC helpers
1451 ************************************************/
1452 extern inline void LockContext(ALCcontext
*context
);
1453 extern inline void UnlockContext(ALCcontext
*context
);
1455 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1457 return V0(device
->Backend
,getLatency
)();
1460 void ALCdevice_Lock(ALCdevice
*device
)
1462 V0(device
->Backend
,lock
)();
1465 void ALCdevice_Unlock(ALCdevice
*device
)
1467 V0(device
->Backend
,unlock
)();
1471 /* SetDefaultWFXChannelOrder
1473 * Sets the default channel order used by WaveFormatEx.
1475 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1479 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1480 device
->ChannelName
[i
] = InvalidChannel
;
1482 switch(device
->FmtChans
)
1485 device
->ChannelName
[0] = FrontCenter
;
1488 device
->ChannelName
[0] = FrontLeft
;
1489 device
->ChannelName
[1] = FrontRight
;
1492 device
->ChannelName
[0] = FrontLeft
;
1493 device
->ChannelName
[1] = FrontRight
;
1494 device
->ChannelName
[2] = BackLeft
;
1495 device
->ChannelName
[3] = BackRight
;
1498 device
->ChannelName
[0] = FrontLeft
;
1499 device
->ChannelName
[1] = FrontRight
;
1500 device
->ChannelName
[2] = FrontCenter
;
1501 device
->ChannelName
[3] = LFE
;
1502 device
->ChannelName
[4] = SideLeft
;
1503 device
->ChannelName
[5] = SideRight
;
1506 device
->ChannelName
[0] = FrontLeft
;
1507 device
->ChannelName
[1] = FrontRight
;
1508 device
->ChannelName
[2] = FrontCenter
;
1509 device
->ChannelName
[3] = LFE
;
1510 device
->ChannelName
[4] = BackLeft
;
1511 device
->ChannelName
[5] = BackRight
;
1514 device
->ChannelName
[0] = FrontLeft
;
1515 device
->ChannelName
[1] = FrontRight
;
1516 device
->ChannelName
[2] = FrontCenter
;
1517 device
->ChannelName
[3] = LFE
;
1518 device
->ChannelName
[4] = BackCenter
;
1519 device
->ChannelName
[5] = SideLeft
;
1520 device
->ChannelName
[6] = SideRight
;
1523 device
->ChannelName
[0] = FrontLeft
;
1524 device
->ChannelName
[1] = FrontRight
;
1525 device
->ChannelName
[2] = FrontCenter
;
1526 device
->ChannelName
[3] = LFE
;
1527 device
->ChannelName
[4] = BackLeft
;
1528 device
->ChannelName
[5] = BackRight
;
1529 device
->ChannelName
[6] = SideLeft
;
1530 device
->ChannelName
[7] = SideRight
;
1532 case DevFmtBFormat3D
:
1533 device
->ChannelName
[0] = Aux0
;
1534 device
->ChannelName
[1] = Aux1
;
1535 device
->ChannelName
[2] = Aux2
;
1536 device
->ChannelName
[3] = Aux3
;
1541 /* SetDefaultChannelOrder
1543 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1545 void SetDefaultChannelOrder(ALCdevice
*device
)
1549 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1550 device
->ChannelName
[i
] = InvalidChannel
;
1552 switch(device
->FmtChans
)
1555 device
->ChannelName
[0] = FrontLeft
;
1556 device
->ChannelName
[1] = FrontRight
;
1557 device
->ChannelName
[2] = BackLeft
;
1558 device
->ChannelName
[3] = BackRight
;
1559 device
->ChannelName
[4] = FrontCenter
;
1560 device
->ChannelName
[5] = LFE
;
1563 device
->ChannelName
[0] = FrontLeft
;
1564 device
->ChannelName
[1] = FrontRight
;
1565 device
->ChannelName
[2] = BackLeft
;
1566 device
->ChannelName
[3] = BackRight
;
1567 device
->ChannelName
[4] = FrontCenter
;
1568 device
->ChannelName
[5] = LFE
;
1569 device
->ChannelName
[6] = SideLeft
;
1570 device
->ChannelName
[7] = SideRight
;
1573 /* Same as WFX order */
1579 case DevFmtBFormat3D
:
1580 SetDefaultWFXChannelOrder(device
);
1585 extern inline ALint
GetChannelIdxByName(const ALCdevice
*device
, enum Channel chan
);
1588 /* ALCcontext_DeferUpdates
1590 * Defers/suspends updates for the given context's listener and sources. This
1591 * does *NOT* stop mixing, but rather prevents certain property changes from
1594 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1596 ALCdevice
*device
= context
->Device
;
1599 SetMixerFPUMode(&oldMode
);
1601 V0(device
->Backend
,lock
)();
1602 if(!context
->DeferUpdates
)
1604 ALboolean UpdateSources
;
1605 ALvoice
*voice
, *voice_end
;
1606 ALeffectslot
**slot
, **slot_end
;
1608 context
->DeferUpdates
= AL_TRUE
;
1610 /* Make sure all pending updates are performed */
1611 UpdateSources
= ATOMIC_EXCHANGE(ALenum
, &context
->UpdateSources
, AL_FALSE
);
1613 voice
= context
->Voices
;
1614 voice_end
= voice
+ context
->VoiceCount
;
1615 while(voice
!= voice_end
)
1617 ALsource
*source
= voice
->Source
;
1618 if(!source
) goto next
;
1620 if(source
->state
!= AL_PLAYING
&& source
->state
!= AL_PAUSED
)
1622 voice
->Source
= NULL
;
1626 if(ATOMIC_EXCHANGE(ALenum
, &source
->NeedsUpdate
, AL_FALSE
) || UpdateSources
)
1627 voice
->Update(voice
, source
, context
);
1632 slot
= VECTOR_ITER_BEGIN(context
->ActiveAuxSlots
);
1633 slot_end
= VECTOR_ITER_END(context
->ActiveAuxSlots
);
1634 while(slot
!= slot_end
)
1636 if(ATOMIC_EXCHANGE(ALenum
, &(*slot
)->NeedsUpdate
, AL_FALSE
))
1637 V((*slot
)->EffectState
,update
)(context
->Device
, *slot
);
1641 V0(device
->Backend
,unlock
)();
1643 RestoreFPUMode(&oldMode
);
1646 /* ALCcontext_ProcessUpdates
1648 * Resumes update processing after being deferred.
1650 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1652 ALCdevice
*device
= context
->Device
;
1654 V0(device
->Backend
,lock
)();
1655 if(context
->DeferUpdates
)
1659 context
->DeferUpdates
= AL_FALSE
;
1661 LockUIntMapRead(&context
->SourceMap
);
1662 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1664 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1667 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1668 Source
->Offset
>= 0.0)
1670 ReadLock(&Source
->queue_lock
);
1671 ApplyOffset(Source
);
1672 ReadUnlock(&Source
->queue_lock
);
1675 new_state
= Source
->new_state
;
1676 Source
->new_state
= AL_NONE
;
1678 SetSourceState(Source
, context
, new_state
);
1680 UnlockUIntMapRead(&context
->SourceMap
);
1682 V0(device
->Backend
,unlock
)();
1688 * Stores the latest ALC device error
1690 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1695 /* DebugBreak() will cause an exception if there is no debugger */
1696 if(IsDebuggerPresent())
1698 #elif defined(SIGTRAP)
1704 ATOMIC_STORE(&device
->LastError
, errorCode
);
1706 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1712 * Updates the device's base clock time with however many samples have been
1713 * done. This is used so frequency changes on the device don't cause the time
1714 * to jump forward or back.
1716 static inline void UpdateClockBase(ALCdevice
*device
)
1718 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1719 device
->SamplesDone
= 0;
1722 /* UpdateDeviceParams
1724 * Updates device parameters according to the attribute list (caller is
1725 * responsible for holding the list lock).
1727 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1729 ALCcontext
*context
;
1730 enum DevFmtChannels oldChans
;
1731 enum DevFmtType oldType
;
1736 // Check for attributes
1737 if(device
->Type
== Loopback
)
1743 GotAll
= GotFreq
|GotChans
|GotType
1745 ALCuint freq
, numMono
, numStereo
, numSends
, flags
;
1746 enum DevFmtChannels schans
;
1747 enum DevFmtType stype
;
1748 ALCuint attrIdx
= 0;
1753 WARN("Missing attributes for loopback device\n");
1754 return ALC_INVALID_VALUE
;
1757 numMono
= device
->NumMonoSources
;
1758 numStereo
= device
->NumStereoSources
;
1759 numSends
= device
->NumAuxSends
;
1760 schans
= device
->FmtChans
;
1761 stype
= device
->FmtType
;
1762 freq
= device
->Frequency
;
1763 flags
= device
->Flags
;
1765 while(attrList
[attrIdx
])
1767 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1769 ALCint val
= attrList
[attrIdx
+ 1];
1770 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1771 return ALC_INVALID_VALUE
;
1776 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1778 ALCint val
= attrList
[attrIdx
+ 1];
1779 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1780 return ALC_INVALID_VALUE
;
1785 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1787 freq
= attrList
[attrIdx
+ 1];
1788 if(freq
< MIN_OUTPUT_RATE
)
1789 return ALC_INVALID_VALUE
;
1793 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1795 numStereo
= attrList
[attrIdx
+ 1];
1796 if(numStereo
> device
->MaxNoOfSources
)
1797 numStereo
= device
->MaxNoOfSources
;
1799 numMono
= device
->MaxNoOfSources
- numStereo
;
1802 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1803 numSends
= attrList
[attrIdx
+ 1];
1805 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1807 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1808 flags
|= DEVICE_HRTF_REQUEST
;
1810 flags
&= ~DEVICE_HRTF_REQUEST
;
1816 if(gotFmt
!= GotAll
)
1818 WARN("Missing format for loopback device\n");
1819 return ALC_INVALID_VALUE
;
1822 ConfigValueUInt(NULL
, "sends", &numSends
);
1823 numSends
= minu(MAX_SENDS
, numSends
);
1825 if((device
->Flags
&DEVICE_RUNNING
))
1826 V0(device
->Backend
,stop
)();
1827 device
->Flags
= (flags
& ~DEVICE_RUNNING
);
1829 UpdateClockBase(device
);
1831 device
->Frequency
= freq
;
1832 device
->FmtChans
= schans
;
1833 device
->FmtType
= stype
;
1834 device
->NumMonoSources
= numMono
;
1835 device
->NumStereoSources
= numStereo
;
1836 device
->NumAuxSends
= numSends
;
1838 else if(attrList
&& attrList
[0])
1840 ALCuint freq
, numMono
, numStereo
, numSends
;
1841 ALCuint attrIdx
= 0;
1843 /* If a context is already running on the device, stop playback so the
1844 * device attributes can be updated. */
1845 if((device
->Flags
&DEVICE_RUNNING
))
1846 V0(device
->Backend
,stop
)();
1847 device
->Flags
&= ~DEVICE_RUNNING
;
1849 freq
= device
->Frequency
;
1850 numMono
= device
->NumMonoSources
;
1851 numStereo
= device
->NumStereoSources
;
1852 numSends
= device
->NumAuxSends
;
1854 while(attrList
[attrIdx
])
1856 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1858 freq
= attrList
[attrIdx
+ 1];
1859 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1862 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1864 numStereo
= attrList
[attrIdx
+ 1];
1865 if(numStereo
> device
->MaxNoOfSources
)
1866 numStereo
= device
->MaxNoOfSources
;
1868 numMono
= device
->MaxNoOfSources
- numStereo
;
1871 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1872 numSends
= attrList
[attrIdx
+ 1];
1874 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1876 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1877 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1879 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1885 ConfigValueUInt(NULL
, "frequency", &freq
);
1886 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1888 ConfigValueUInt(NULL
, "sends", &numSends
);
1889 numSends
= minu(MAX_SENDS
, numSends
);
1891 UpdateClockBase(device
);
1893 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1895 /* SSE and Neon do best with the update size being a multiple of 4 */
1896 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1897 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1899 device
->Frequency
= freq
;
1900 device
->NumMonoSources
= numMono
;
1901 device
->NumStereoSources
= numStereo
;
1902 device
->NumAuxSends
= numSends
;
1905 if((device
->Flags
&DEVICE_RUNNING
))
1906 return ALC_NO_ERROR
;
1908 al_free(device
->DryBuffer
);
1909 device
->DryBuffer
= NULL
;
1911 UpdateClockBase(device
);
1913 if(device
->Type
!= Loopback
&& ((device
->Flags
&DEVICE_HRTF_REQUEST
) || GetConfigValueBool(NULL
, "hrtf", 0)))
1915 if(!FindHrtfFormat(&device
->FmtChans
, &device
->Frequency
))
1916 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1918 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
|
1919 DEVICE_HRTF_REQUEST
;
1921 if(device
->Type
== Loopback
&& (device
->Flags
&DEVICE_HRTF_REQUEST
))
1923 enum DevFmtChannels chans
= device
->FmtChans
;
1924 ALCuint freq
= device
->Frequency
;
1925 if(!FindHrtfFormat(&chans
, &freq
) || chans
!= device
->FmtChans
|| freq
!= device
->Frequency
)
1927 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1928 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1929 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1933 oldFreq
= device
->Frequency
;
1934 oldChans
= device
->FmtChans
;
1935 oldType
= device
->FmtType
;
1937 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1938 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1939 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1940 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1941 device
->UpdateSize
, device
->NumUpdates
1944 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1945 return ALC_INVALID_DEVICE
;
1947 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1949 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1950 DevFmtChannelsString(device
->FmtChans
));
1951 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1953 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1955 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1956 DevFmtTypeString(device
->FmtType
));
1957 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1959 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1961 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1962 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1965 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1966 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1967 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1970 if((device
->UpdateSize
&3) != 0)
1972 if((CPUCapFlags
&CPU_CAP_SSE
))
1973 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1974 if((CPUCapFlags
&CPU_CAP_NEON
))
1975 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1978 device
->Hrtf
= NULL
;
1979 if(device
->FmtChans
!= DevFmtStereo
)
1982 device
->Bs2b
= NULL
;
1986 bool headphones
= device
->IsHeadphones
;
1991 if(device
->Type
!= Loopback
&& ConfigValueStr(NULL
, "stereo-mode", &mode
))
1993 if(strcasecmp(mode
, "headphones") == 0)
1995 else if(strcasecmp(mode
, "speakers") == 0)
1997 else if(strcasecmp(mode
, "auto") != 0)
1998 ERR("Unexpected stereo-mode: %s\n", mode
);
2001 if(device
->Type
== Loopback
|| !ConfigValueBool(NULL
, "hrtf", &usehrtf
))
2002 usehrtf
= ((device
->Flags
&DEVICE_HRTF_REQUEST
) || headphones
);
2005 device
->Hrtf
= GetHrtf(device
->FmtChans
, device
->Frequency
);
2007 TRACE("HRTF enabled\n");
2010 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
2011 TRACE("HRTF disabled\n");
2013 bs2blevel
= (headphones
? 5 : 0);
2014 if(device
->Type
!= Loopback
)
2015 ConfigValueInt(NULL
, "cf_level", &bs2blevel
);
2016 if(bs2blevel
> 0 && bs2blevel
<= 6)
2020 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
2021 bs2b_clear(device
->Bs2b
);
2023 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
2024 bs2b_set_level(device
->Bs2b
, bs2blevel
);
2025 TRACE("BS2B enabled\n");
2030 device
->Bs2b
= NULL
;
2031 TRACE("BS2B disabled\n");
2036 aluInitPanning(device
);
2038 /* With HRTF enabled, virtual channels are allocated for B-Format and
2039 * effects renfering. Two extra channels are allocated for the actual HRTF-
2042 size
= sizeof(device
->DryBuffer
[0]) * (device
->NumChannels
+ (device
->Hrtf
? 2 : 0));
2043 device
->DryBuffer
= al_calloc(16, size
);
2044 if(!device
->DryBuffer
)
2046 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2047 return ALC_INVALID_DEVICE
;
2050 V(device
->Synth
,update
)(device
);
2052 SetMixerFPUMode(&oldMode
);
2053 V0(device
->Backend
,lock
)();
2054 context
= ATOMIC_LOAD(&device
->ContextList
);
2059 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2060 LockUIntMapRead(&context
->EffectSlotMap
);
2061 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2063 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2065 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2067 UnlockUIntMapRead(&context
->EffectSlotMap
);
2068 V0(device
->Backend
,unlock
)();
2069 RestoreFPUMode(&oldMode
);
2070 return ALC_INVALID_DEVICE
;
2072 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2073 V(slot
->EffectState
,update
)(device
, slot
);
2075 UnlockUIntMapRead(&context
->EffectSlotMap
);
2077 LockUIntMapRead(&context
->SourceMap
);
2078 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2080 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2081 ALuint s
= device
->NumAuxSends
;
2082 while(s
< MAX_SENDS
)
2084 if(source
->Send
[s
].Slot
)
2085 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2086 source
->Send
[s
].Slot
= NULL
;
2087 source
->Send
[s
].Gain
= 1.0f
;
2088 source
->Send
[s
].GainHF
= 1.0f
;
2091 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2093 UnlockUIntMapRead(&context
->SourceMap
);
2095 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2097 ALvoice
*voice
= &context
->Voices
[pos
];
2098 ALsource
*source
= voice
->Source
;
2099 ALuint s
= device
->NumAuxSends
;
2101 while(s
< MAX_SENDS
)
2103 voice
->Send
[s
].Moving
= AL_FALSE
;
2104 voice
->Send
[s
].Counter
= 0;
2110 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2111 voice
->Update(voice
, source
, context
);
2115 context
= context
->next
;
2117 if(device
->DefaultSlot
)
2119 ALeffectslot
*slot
= device
->DefaultSlot
;
2121 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2123 V0(device
->Backend
,unlock
)();
2124 RestoreFPUMode(&oldMode
);
2125 return ALC_INVALID_DEVICE
;
2127 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2128 V(slot
->EffectState
,update
)(device
, slot
);
2130 V0(device
->Backend
,unlock
)();
2131 RestoreFPUMode(&oldMode
);
2133 if(!(device
->Flags
&DEVICE_PAUSED
))
2135 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2136 return ALC_INVALID_DEVICE
;
2137 device
->Flags
|= DEVICE_RUNNING
;
2140 return ALC_NO_ERROR
;
2145 * Frees the device structure, and destroys any objects the app failed to
2146 * delete. Called once there's no more references on the device.
2148 static ALCvoid
FreeDevice(ALCdevice
*device
)
2150 TRACE("%p\n", device
);
2152 V0(device
->Backend
,close
)();
2153 DELETE_OBJ(device
->Backend
);
2154 device
->Backend
= NULL
;
2156 DELETE_OBJ(device
->Synth
);
2157 device
->Synth
= NULL
;
2159 if(device
->DefaultSlot
)
2161 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2162 device
->DefaultSlot
= NULL
;
2166 if(device
->DefaultSfont
)
2167 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
2168 device
->DefaultSfont
= NULL
;
2170 if(device
->BufferMap
.size
> 0)
2172 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2173 ReleaseALBuffers(device
);
2175 ResetUIntMap(&device
->BufferMap
);
2177 if(device
->EffectMap
.size
> 0)
2179 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2180 ReleaseALEffects(device
);
2182 ResetUIntMap(&device
->EffectMap
);
2184 if(device
->FilterMap
.size
> 0)
2186 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2187 ReleaseALFilters(device
);
2189 ResetUIntMap(&device
->FilterMap
);
2191 if(device
->SfontMap
.size
> 0)
2193 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2194 ReleaseALSoundfonts(device
);
2196 ResetUIntMap(&device
->SfontMap
);
2198 if(device
->PresetMap
.size
> 0)
2200 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2201 ReleaseALPresets(device
);
2203 ResetUIntMap(&device
->PresetMap
);
2205 if(device
->FontsoundMap
.size
> 0)
2207 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2208 ReleaseALFontsounds(device
);
2210 ResetUIntMap(&device
->FontsoundMap
);
2213 device
->Bs2b
= NULL
;
2215 AL_STRING_DEINIT(device
->DeviceName
);
2217 al_free(device
->DryBuffer
);
2218 device
->DryBuffer
= NULL
;
2224 void ALCdevice_IncRef(ALCdevice
*device
)
2227 ref
= IncrementRef(&device
->ref
);
2228 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2231 void ALCdevice_DecRef(ALCdevice
*device
)
2234 ref
= DecrementRef(&device
->ref
);
2235 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2236 if(ref
== 0) FreeDevice(device
);
2241 * Checks if the device handle is valid, and increments its ref count if so.
2243 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2245 ALCdevice
*tmpDevice
;
2251 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2252 while(tmpDevice
&& tmpDevice
!= device
)
2253 tmpDevice
= tmpDevice
->next
;
2256 ALCdevice_IncRef(tmpDevice
);
2264 * Initializes context fields
2266 static ALvoid
InitContext(ALCcontext
*Context
)
2268 //Initialise listener
2269 Context
->Listener
->Gain
= 1.0f
;
2270 Context
->Listener
->MetersPerUnit
= 1.0f
;
2271 aluVectorSet(&Context
->Listener
->Position
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
2272 aluVectorSet(&Context
->Listener
->Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2273 Context
->Listener
->Forward
[0] = 0.0f
;
2274 Context
->Listener
->Forward
[1] = 0.0f
;
2275 Context
->Listener
->Forward
[2] = -1.0f
;
2276 Context
->Listener
->Up
[0] = 0.0f
;
2277 Context
->Listener
->Up
[1] = 1.0f
;
2278 Context
->Listener
->Up
[2] = 0.0f
;
2279 aluMatrixSet(&Context
->Listener
->Params
.Matrix
,
2280 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2281 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2282 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2283 0.0f
, 0.0f
, 0.0f
, 1.0f
2285 aluVectorSet(&Context
->Listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2288 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2289 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2290 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2291 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2294 Context
->DistanceModel
= DefaultDistanceModel
;
2295 Context
->SourceDistanceModel
= AL_FALSE
;
2296 Context
->DopplerFactor
= 1.0f
;
2297 Context
->DopplerVelocity
= 1.0f
;
2298 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2299 Context
->DeferUpdates
= AL_FALSE
;
2301 Context
->ExtensionList
= alExtList
;
2307 * Cleans up the context, and destroys any remaining objects the app failed to
2308 * delete. Called once there's no more references on the context.
2310 static void FreeContext(ALCcontext
*context
)
2312 TRACE("%p\n", context
);
2314 if(context
->SourceMap
.size
> 0)
2316 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2317 ReleaseALSources(context
);
2319 ResetUIntMap(&context
->SourceMap
);
2321 if(context
->EffectSlotMap
.size
> 0)
2323 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2324 ReleaseALAuxiliaryEffectSlots(context
);
2326 ResetUIntMap(&context
->EffectSlotMap
);
2328 al_free(context
->Voices
);
2329 context
->Voices
= NULL
;
2330 context
->VoiceCount
= 0;
2331 context
->MaxVoices
= 0;
2333 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2335 ALCdevice_DecRef(context
->Device
);
2336 context
->Device
= NULL
;
2338 //Invalidate context
2339 memset(context
, 0, sizeof(ALCcontext
));
2345 * Removes the context reference from the given device and removes it from
2346 * being current on the running thread or globally.
2348 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2350 ALCcontext
*nextctx
;
2351 ALCcontext
*origctx
;
2353 if(altss_get(LocalContext
) == context
)
2355 WARN("%p released while current on thread\n", context
);
2356 altss_set(LocalContext
, NULL
);
2357 ALCcontext_DecRef(context
);
2361 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2362 ALCcontext_DecRef(context
);
2364 ALCdevice_Lock(device
);
2366 nextctx
= context
->next
;
2367 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2373 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2375 ALCdevice_Unlock(device
);
2377 ALCcontext_DecRef(context
);
2380 void ALCcontext_IncRef(ALCcontext
*context
)
2383 ref
= IncrementRef(&context
->ref
);
2384 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2387 void ALCcontext_DecRef(ALCcontext
*context
)
2390 ref
= DecrementRef(&context
->ref
);
2391 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2392 if(ref
== 0) FreeContext(context
);
2395 static void ReleaseThreadCtx(void *ptr
)
2397 WARN("%p current for thread being destroyed\n", ptr
);
2398 ALCcontext_DecRef(ptr
);
2403 * Checks that the given context is valid, and increments its reference count.
2405 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2410 dev
= ATOMIC_LOAD(&DeviceList
);
2413 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2418 ALCcontext_IncRef(ctx
);
2434 * Returns the currently active context for this thread, and adds a reference
2435 * without locking it.
2437 ALCcontext
*GetContextRef(void)
2439 ALCcontext
*context
;
2441 context
= altss_get(LocalContext
);
2443 ALCcontext_IncRef(context
);
2447 context
= ATOMIC_LOAD(&GlobalContext
);
2449 ALCcontext_IncRef(context
);
2457 /************************************************
2458 * Standard ALC functions
2459 ************************************************/
2463 * Return last ALC generated error code for the given device
2465 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2469 if(VerifyDevice(device
))
2471 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2472 ALCdevice_DecRef(device
);
2475 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2481 /* alcSuspendContext
2483 * Suspends updates for the given context
2485 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2490 context
= VerifyContext(context
);
2492 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2495 ALCcontext_DeferUpdates(context
);
2496 ALCcontext_DecRef(context
);
2500 /* alcProcessContext
2502 * Resumes processing updates for the given context
2504 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2509 context
= VerifyContext(context
);
2511 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2514 ALCcontext_ProcessUpdates(context
);
2515 ALCcontext_DecRef(context
);
2522 * Returns information about the device, and error strings
2524 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2526 const ALCchar
*value
= NULL
;
2534 case ALC_INVALID_ENUM
:
2535 value
= alcErrInvalidEnum
;
2538 case ALC_INVALID_VALUE
:
2539 value
= alcErrInvalidValue
;
2542 case ALC_INVALID_DEVICE
:
2543 value
= alcErrInvalidDevice
;
2546 case ALC_INVALID_CONTEXT
:
2547 value
= alcErrInvalidContext
;
2550 case ALC_OUT_OF_MEMORY
:
2551 value
= alcErrOutOfMemory
;
2554 case ALC_DEVICE_SPECIFIER
:
2555 value
= alcDefaultName
;
2558 case ALC_ALL_DEVICES_SPECIFIER
:
2559 if(VerifyDevice(Device
))
2561 value
= al_string_get_cstr(Device
->DeviceName
);
2562 ALCdevice_DecRef(Device
);
2566 ProbeAllDevicesList();
2567 value
= al_string_get_cstr(alcAllDevicesList
);
2571 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2572 if(VerifyDevice(Device
))
2574 value
= al_string_get_cstr(Device
->DeviceName
);
2575 ALCdevice_DecRef(Device
);
2579 ProbeCaptureDeviceList();
2580 value
= al_string_get_cstr(alcCaptureDeviceList
);
2584 /* Default devices are always first in the list */
2585 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2586 value
= alcDefaultName
;
2589 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2590 if(al_string_empty(alcAllDevicesList
))
2591 ProbeAllDevicesList();
2593 Device
= VerifyDevice(Device
);
2595 free(alcDefaultAllDevicesSpecifier
);
2596 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2597 if(!alcDefaultAllDevicesSpecifier
)
2598 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2600 value
= alcDefaultAllDevicesSpecifier
;
2601 if(Device
) ALCdevice_DecRef(Device
);
2604 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2605 if(al_string_empty(alcCaptureDeviceList
))
2606 ProbeCaptureDeviceList();
2608 Device
= VerifyDevice(Device
);
2610 free(alcCaptureDefaultDeviceSpecifier
);
2611 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2612 if(!alcCaptureDefaultDeviceSpecifier
)
2613 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2615 value
= alcCaptureDefaultDeviceSpecifier
;
2616 if(Device
) ALCdevice_DecRef(Device
);
2619 case ALC_EXTENSIONS
:
2620 if(!VerifyDevice(Device
))
2621 value
= alcNoDeviceExtList
;
2624 value
= alcExtensionList
;
2625 ALCdevice_DecRef(Device
);
2630 Device
= VerifyDevice(Device
);
2631 alcSetError(Device
, ALC_INVALID_ENUM
);
2632 if(Device
) ALCdevice_DecRef(Device
);
2640 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2644 if(size
<= 0 || values
== NULL
)
2646 alcSetError(device
, ALC_INVALID_VALUE
);
2654 case ALC_MAJOR_VERSION
:
2655 values
[0] = alcMajorVersion
;
2657 case ALC_MINOR_VERSION
:
2658 values
[0] = alcMinorVersion
;
2661 case ALC_ATTRIBUTES_SIZE
:
2662 case ALC_ALL_ATTRIBUTES
:
2666 case ALC_MONO_SOURCES
:
2667 case ALC_STEREO_SOURCES
:
2668 case ALC_CAPTURE_SAMPLES
:
2669 case ALC_FORMAT_CHANNELS_SOFT
:
2670 case ALC_FORMAT_TYPE_SOFT
:
2671 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2675 alcSetError(NULL
, ALC_INVALID_ENUM
);
2681 if(device
->Type
== Capture
)
2685 case ALC_CAPTURE_SAMPLES
:
2686 V0(device
->Backend
,lock
)();
2687 values
[0] = V0(device
->Backend
,availableSamples
)();
2688 V0(device
->Backend
,unlock
)();
2692 values
[0] = device
->Connected
;
2696 alcSetError(device
, ALC_INVALID_ENUM
);
2705 case ALC_MAJOR_VERSION
:
2706 values
[0] = alcMajorVersion
;
2709 case ALC_MINOR_VERSION
:
2710 values
[0] = alcMinorVersion
;
2713 case ALC_EFX_MAJOR_VERSION
:
2714 values
[0] = alcEFXMajorVersion
;
2717 case ALC_EFX_MINOR_VERSION
:
2718 values
[0] = alcEFXMinorVersion
;
2721 case ALC_ATTRIBUTES_SIZE
:
2725 case ALC_ALL_ATTRIBUTES
:
2728 alcSetError(device
, ALC_INVALID_VALUE
);
2733 values
[i
++] = ALC_FREQUENCY
;
2734 values
[i
++] = device
->Frequency
;
2736 if(device
->Type
!= Loopback
)
2738 values
[i
++] = ALC_REFRESH
;
2739 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2741 values
[i
++] = ALC_SYNC
;
2742 values
[i
++] = ALC_FALSE
;
2746 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2747 values
[i
++] = device
->FmtChans
;
2749 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2750 values
[i
++] = device
->FmtType
;
2753 values
[i
++] = ALC_MONO_SOURCES
;
2754 values
[i
++] = device
->NumMonoSources
;
2756 values
[i
++] = ALC_STEREO_SOURCES
;
2757 values
[i
++] = device
->NumStereoSources
;
2759 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2760 values
[i
++] = device
->NumAuxSends
;
2762 values
[i
++] = ALC_HRTF_SOFT
;
2763 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2769 values
[0] = device
->Frequency
;
2773 if(device
->Type
== Loopback
)
2775 alcSetError(device
, ALC_INVALID_DEVICE
);
2778 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2782 if(device
->Type
== Loopback
)
2784 alcSetError(device
, ALC_INVALID_DEVICE
);
2787 values
[0] = ALC_FALSE
;
2790 case ALC_FORMAT_CHANNELS_SOFT
:
2791 if(device
->Type
!= Loopback
)
2793 alcSetError(device
, ALC_INVALID_DEVICE
);
2796 values
[0] = device
->FmtChans
;
2799 case ALC_FORMAT_TYPE_SOFT
:
2800 if(device
->Type
!= Loopback
)
2802 alcSetError(device
, ALC_INVALID_DEVICE
);
2805 values
[0] = device
->FmtType
;
2808 case ALC_MONO_SOURCES
:
2809 values
[0] = device
->NumMonoSources
;
2812 case ALC_STEREO_SOURCES
:
2813 values
[0] = device
->NumStereoSources
;
2816 case ALC_MAX_AUXILIARY_SENDS
:
2817 values
[0] = device
->NumAuxSends
;
2821 values
[0] = device
->Connected
;
2825 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2829 alcSetError(device
, ALC_INVALID_ENUM
);
2837 * Returns information about the device and the version of OpenAL
2839 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2841 device
= VerifyDevice(device
);
2842 if(size
<= 0 || values
== NULL
)
2843 alcSetError(device
, ALC_INVALID_VALUE
);
2845 GetIntegerv(device
, param
, size
, values
);
2846 if(device
) ALCdevice_DecRef(device
);
2849 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2854 device
= VerifyDevice(device
);
2855 if(size
<= 0 || values
== NULL
)
2856 alcSetError(device
, ALC_INVALID_VALUE
);
2857 else if(!device
|| device
->Type
== Capture
)
2859 ivals
= malloc(size
* sizeof(ALCint
));
2860 size
= GetIntegerv(device
, pname
, size
, ivals
);
2861 for(i
= 0;i
< size
;i
++)
2862 values
[i
] = ivals
[i
];
2865 else /* render device */
2869 case ALC_ATTRIBUTES_SIZE
:
2873 case ALC_ALL_ATTRIBUTES
:
2875 alcSetError(device
, ALC_INVALID_VALUE
);
2880 V0(device
->Backend
,lock
)();
2881 values
[i
++] = ALC_FREQUENCY
;
2882 values
[i
++] = device
->Frequency
;
2884 if(device
->Type
!= Loopback
)
2886 values
[i
++] = ALC_REFRESH
;
2887 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2889 values
[i
++] = ALC_SYNC
;
2890 values
[i
++] = ALC_FALSE
;
2894 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2895 values
[i
++] = device
->FmtChans
;
2897 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2898 values
[i
++] = device
->FmtType
;
2901 values
[i
++] = ALC_MONO_SOURCES
;
2902 values
[i
++] = device
->NumMonoSources
;
2904 values
[i
++] = ALC_STEREO_SOURCES
;
2905 values
[i
++] = device
->NumStereoSources
;
2907 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2908 values
[i
++] = device
->NumAuxSends
;
2910 values
[i
++] = ALC_HRTF_SOFT
;
2911 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2913 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2914 values
[i
++] = device
->ClockBase
+
2915 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2918 V0(device
->Backend
,unlock
)();
2922 case ALC_DEVICE_CLOCK_SOFT
:
2923 V0(device
->Backend
,lock
)();
2924 *values
= device
->ClockBase
+
2925 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2926 V0(device
->Backend
,unlock
)();
2930 ivals
= malloc(size
* sizeof(ALCint
));
2931 size
= GetIntegerv(device
, pname
, size
, ivals
);
2932 for(i
= 0;i
< size
;i
++)
2933 values
[i
] = ivals
[i
];
2939 ALCdevice_DecRef(device
);
2943 /* alcIsExtensionPresent
2945 * Determines if there is support for a particular extension
2947 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2949 ALCboolean bResult
= ALC_FALSE
;
2951 device
= VerifyDevice(device
);
2954 alcSetError(device
, ALC_INVALID_VALUE
);
2957 size_t len
= strlen(extName
);
2958 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2961 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2962 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2967 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2971 } while(isspace(*ptr
));
2976 ALCdevice_DecRef(device
);
2981 /* alcGetProcAddress
2983 * Retrieves the function address for a particular extension function
2985 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2987 ALCvoid
*ptr
= NULL
;
2991 device
= VerifyDevice(device
);
2992 alcSetError(device
, ALC_INVALID_VALUE
);
2993 if(device
) ALCdevice_DecRef(device
);
2998 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3000 ptr
= alcFunctions
[i
].address
;
3009 * Get the value for a particular ALC enumeration name
3011 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3017 device
= VerifyDevice(device
);
3018 alcSetError(device
, ALC_INVALID_VALUE
);
3019 if(device
) ALCdevice_DecRef(device
);
3024 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3026 val
= enumeration
[i
].value
;
3035 * Create and attach a context to the given device.
3037 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3039 ALCcontext
*ALContext
;
3043 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
3046 alcSetError(device
, ALC_INVALID_DEVICE
);
3047 if(device
) ALCdevice_DecRef(device
);
3051 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3053 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3056 alcSetError(device
, err
);
3057 if(err
== ALC_INVALID_DEVICE
)
3059 V0(device
->Backend
,lock
)();
3060 aluHandleDisconnect(device
);
3061 V0(device
->Backend
,unlock
)();
3063 ALCdevice_DecRef(device
);
3067 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3070 InitRef(&ALContext
->ref
, 1);
3071 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3073 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3075 ALContext
->VoiceCount
= 0;
3076 ALContext
->MaxVoices
= 256;
3077 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3079 if(!ALContext
|| !ALContext
->Voices
)
3081 if(!ATOMIC_LOAD(&device
->ContextList
))
3083 V0(device
->Backend
,stop
)();
3084 device
->Flags
&= ~DEVICE_RUNNING
;
3090 al_free(ALContext
->Voices
);
3091 ALContext
->Voices
= NULL
;
3093 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3099 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3100 ALCdevice_DecRef(device
);
3104 ALContext
->Device
= device
;
3105 ALCdevice_IncRef(device
);
3106 InitContext(ALContext
);
3109 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3111 ALContext
->next
= head
;
3112 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3116 ALCdevice_DecRef(device
);
3118 TRACE("Created context %p\n", ALContext
);
3122 /* alcDestroyContext
3124 * Remove a context from its device
3126 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3131 /* alcGetContextsDevice sets an error for invalid contexts */
3132 Device
= alcGetContextsDevice(context
);
3135 ReleaseContext(context
, Device
);
3136 if(!ATOMIC_LOAD(&Device
->ContextList
))
3138 V0(Device
->Backend
,stop
)();
3139 Device
->Flags
&= ~DEVICE_RUNNING
;
3146 /* alcGetCurrentContext
3148 * Returns the currently active context on the calling thread
3150 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3152 ALCcontext
*Context
= altss_get(LocalContext
);
3153 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3157 /* alcGetThreadContext
3159 * Returns the currently active thread-local context
3161 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3163 return altss_get(LocalContext
);
3167 /* alcMakeContextCurrent
3169 * Makes the given context the active process-wide context, and removes the
3170 * thread-local context for the calling thread.
3172 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3174 /* context must be valid or NULL */
3175 if(context
&& !(context
=VerifyContext(context
)))
3177 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3180 /* context's reference count is already incremented */
3181 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3182 if(context
) ALCcontext_DecRef(context
);
3184 if((context
=altss_get(LocalContext
)) != NULL
)
3186 altss_set(LocalContext
, NULL
);
3187 ALCcontext_DecRef(context
);
3193 /* alcSetThreadContext
3195 * Makes the given context the active context for the current thread
3197 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3201 /* context must be valid or NULL */
3202 if(context
&& !(context
=VerifyContext(context
)))
3204 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3207 /* context's reference count is already incremented */
3208 old
= altss_get(LocalContext
);
3209 altss_set(LocalContext
, context
);
3210 if(old
) ALCcontext_DecRef(old
);
3216 /* alcGetContextsDevice
3218 * Returns the device that a particular context is attached to
3220 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3224 if(!(Context
=VerifyContext(Context
)))
3226 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3229 Device
= Context
->Device
;
3230 ALCcontext_DecRef(Context
);
3238 * Opens the named device.
3240 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3248 if(!PlaybackBackend
.name
)
3250 alcSetError(NULL
, ALC_INVALID_VALUE
);
3254 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3257 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3260 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3265 InitRef(&device
->ref
, 1);
3266 device
->Connected
= ALC_TRUE
;
3267 device
->Type
= Playback
;
3268 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3271 device
->Bs2b
= NULL
;
3272 AL_STRING_INIT(device
->DeviceName
);
3273 device
->DryBuffer
= NULL
;
3275 ATOMIC_INIT(&device
->ContextList
, NULL
);
3277 device
->ClockBase
= 0;
3278 device
->SamplesDone
= 0;
3280 device
->MaxNoOfSources
= 256;
3281 device
->AuxiliaryEffectSlotMax
= 4;
3282 device
->NumAuxSends
= MAX_SENDS
;
3284 InitUIntMap(&device
->BufferMap
, ~0);
3285 InitUIntMap(&device
->EffectMap
, ~0);
3286 InitUIntMap(&device
->FilterMap
, ~0);
3287 InitUIntMap(&device
->SfontMap
, ~0);
3288 InitUIntMap(&device
->PresetMap
, ~0);
3289 InitUIntMap(&device
->FontsoundMap
, ~0);
3292 device
->FmtChans
= DevFmtChannelsDefault
;
3293 device
->FmtType
= DevFmtTypeDefault
;
3294 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3295 device
->IsHeadphones
= AL_FALSE
;
3296 device
->NumUpdates
= 4;
3297 device
->UpdateSize
= 1024;
3299 if(!PlaybackBackend
.getFactory
)
3300 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3301 ALCbackend_Playback
);
3304 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3305 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3307 if(!device
->Backend
)
3310 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3315 if(ConfigValueStr(NULL
, "channels", &fmt
))
3317 static const struct {
3318 const char name
[16];
3319 enum DevFmtChannels chans
;
3321 { "mono", DevFmtMono
},
3322 { "stereo", DevFmtStereo
},
3323 { "quad", DevFmtQuad
},
3324 { "surround51", DevFmtX51
},
3325 { "surround61", DevFmtX61
},
3326 { "surround71", DevFmtX71
},
3327 { "surround51rear", DevFmtX51Rear
},
3331 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3333 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3335 device
->FmtChans
= chanlist
[i
].chans
;
3336 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3340 if(i
== COUNTOF(chanlist
))
3341 ERR("Unsupported channels: %s\n", fmt
);
3343 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3345 static const struct {
3346 const char name
[16];
3347 enum DevFmtType type
;
3349 { "int8", DevFmtByte
},
3350 { "uint8", DevFmtUByte
},
3351 { "int16", DevFmtShort
},
3352 { "uint16", DevFmtUShort
},
3353 { "int32", DevFmtInt
},
3354 { "uint32", DevFmtUInt
},
3355 { "float32", DevFmtFloat
},
3359 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3361 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3363 device
->FmtType
= typelist
[i
].type
;
3364 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3368 if(i
== COUNTOF(typelist
))
3369 ERR("Unsupported sample-type: %s\n", fmt
);
3372 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3374 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3375 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3376 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3377 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3380 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3381 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3383 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3384 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3385 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3386 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3388 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3389 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3391 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3392 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3394 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3395 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3397 device
->NumStereoSources
= 1;
3398 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3400 device
->Synth
= SynthCreate(device
);
3403 DELETE_OBJ(device
->Backend
);
3405 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3409 // Find a playback device to open
3410 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3412 DELETE_OBJ(device
->Synth
);
3413 DELETE_OBJ(device
->Backend
);
3415 alcSetError(NULL
, err
);
3419 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3421 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3422 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3424 device
->DefaultSlot
= NULL
;
3425 ERR("Failed to initialize the default effect slot\n");
3427 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3429 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3430 device
->DefaultSlot
= NULL
;
3432 ERR("Failed to initialize the default effect\n");
3437 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3439 device
->next
= head
;
3440 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3443 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3449 * Closes the given device.
3451 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3453 ALCdevice
*list
, *origdev
, *nextdev
;
3457 list
= ATOMIC_LOAD(&DeviceList
);
3461 } while((list
=list
->next
) != NULL
);
3462 if(!list
|| list
->Type
== Capture
)
3464 alcSetError(list
, ALC_INVALID_DEVICE
);
3470 nextdev
= device
->next
;
3471 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3476 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3480 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3483 ALCcontext
*next
= ctx
->next
;
3484 WARN("Releasing context %p\n", ctx
);
3485 ReleaseContext(ctx
, device
);
3488 if((device
->Flags
&DEVICE_RUNNING
))
3489 V0(device
->Backend
,stop
)();
3490 device
->Flags
&= ~DEVICE_RUNNING
;
3492 ALCdevice_DecRef(device
);
3498 /************************************************
3499 * ALC capture functions
3500 ************************************************/
3501 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3503 ALCdevice
*device
= NULL
;
3508 if(!CaptureBackend
.name
)
3510 alcSetError(NULL
, ALC_INVALID_VALUE
);
3516 alcSetError(NULL
, ALC_INVALID_VALUE
);
3520 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3523 device
= al_calloc(16, sizeof(ALCdevice
));
3526 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3531 InitRef(&device
->ref
, 1);
3532 device
->Connected
= ALC_TRUE
;
3533 device
->Type
= Capture
;
3535 AL_STRING_INIT(device
->DeviceName
);
3536 device
->DryBuffer
= NULL
;
3538 InitUIntMap(&device
->BufferMap
, ~0);
3539 InitUIntMap(&device
->EffectMap
, ~0);
3540 InitUIntMap(&device
->FilterMap
, ~0);
3541 InitUIntMap(&device
->SfontMap
, ~0);
3542 InitUIntMap(&device
->PresetMap
, ~0);
3543 InitUIntMap(&device
->FontsoundMap
, ~0);
3545 if(!CaptureBackend
.getFactory
)
3546 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3547 ALCbackend_Capture
);
3550 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3551 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3553 if(!device
->Backend
)
3556 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3560 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3561 device
->Frequency
= frequency
;
3563 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3564 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3567 alcSetError(NULL
, ALC_INVALID_ENUM
);
3570 device
->IsHeadphones
= AL_FALSE
;
3572 device
->UpdateSize
= samples
;
3573 device
->NumUpdates
= 1;
3575 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3578 alcSetError(NULL
, err
);
3583 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3585 device
->next
= head
;
3586 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3589 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3593 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3595 ALCdevice
*list
, *next
, *nextdev
;
3598 list
= ATOMIC_LOAD(&DeviceList
);
3602 } while((list
=list
->next
) != NULL
);
3603 if(!list
|| list
->Type
!= Capture
)
3605 alcSetError(list
, ALC_INVALID_DEVICE
);
3611 nextdev
= device
->next
;
3612 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3617 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3621 ALCdevice_DecRef(device
);
3626 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3628 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3629 alcSetError(device
, ALC_INVALID_DEVICE
);
3632 V0(device
->Backend
,lock
)();
3633 if(!device
->Connected
)
3634 alcSetError(device
, ALC_INVALID_DEVICE
);
3635 else if(!(device
->Flags
&DEVICE_RUNNING
))
3637 if(V0(device
->Backend
,start
)())
3638 device
->Flags
|= DEVICE_RUNNING
;
3641 aluHandleDisconnect(device
);
3642 alcSetError(device
, ALC_INVALID_DEVICE
);
3645 V0(device
->Backend
,unlock
)();
3648 if(device
) ALCdevice_DecRef(device
);
3651 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3653 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3654 alcSetError(device
, ALC_INVALID_DEVICE
);
3657 V0(device
->Backend
,lock
)();
3658 if((device
->Flags
&DEVICE_RUNNING
))
3659 V0(device
->Backend
,stop
)();
3660 device
->Flags
&= ~DEVICE_RUNNING
;
3661 V0(device
->Backend
,unlock
)();
3664 if(device
) ALCdevice_DecRef(device
);
3667 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3669 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3670 alcSetError(device
, ALC_INVALID_DEVICE
);
3673 ALCenum err
= ALC_INVALID_VALUE
;
3675 V0(device
->Backend
,lock
)();
3676 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3677 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3678 V0(device
->Backend
,unlock
)();
3680 if(err
!= ALC_NO_ERROR
)
3681 alcSetError(device
, err
);
3683 if(device
) ALCdevice_DecRef(device
);
3687 /************************************************
3688 * ALC loopback functions
3689 ************************************************/
3691 /* alcLoopbackOpenDeviceSOFT
3693 * Open a loopback device, for manual rendering.
3695 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3697 ALCbackendFactory
*factory
;
3702 /* Make sure the device name, if specified, is us. */
3703 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3705 alcSetError(NULL
, ALC_INVALID_VALUE
);
3709 device
= al_calloc(16, sizeof(ALCdevice
));
3712 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3717 InitRef(&device
->ref
, 1);
3718 device
->Connected
= ALC_TRUE
;
3719 device
->Type
= Loopback
;
3720 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3723 device
->Bs2b
= NULL
;
3724 AL_STRING_INIT(device
->DeviceName
);
3725 device
->DryBuffer
= NULL
;
3727 ATOMIC_INIT(&device
->ContextList
, NULL
);
3729 device
->ClockBase
= 0;
3730 device
->SamplesDone
= 0;
3732 device
->MaxNoOfSources
= 256;
3733 device
->AuxiliaryEffectSlotMax
= 4;
3734 device
->NumAuxSends
= MAX_SENDS
;
3736 InitUIntMap(&device
->BufferMap
, ~0);
3737 InitUIntMap(&device
->EffectMap
, ~0);
3738 InitUIntMap(&device
->FilterMap
, ~0);
3739 InitUIntMap(&device
->SfontMap
, ~0);
3740 InitUIntMap(&device
->PresetMap
, ~0);
3741 InitUIntMap(&device
->FontsoundMap
, ~0);
3743 factory
= ALCloopbackFactory_getFactory();
3744 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3745 if(!device
->Backend
)
3748 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3753 device
->NumUpdates
= 0;
3754 device
->UpdateSize
= 0;
3756 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3757 device
->FmtChans
= DevFmtChannelsDefault
;
3758 device
->FmtType
= DevFmtTypeDefault
;
3759 device
->IsHeadphones
= AL_FALSE
;
3761 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3762 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3764 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3765 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3767 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3768 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3770 device
->NumStereoSources
= 1;
3771 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3773 device
->Synth
= SynthCreate(device
);
3776 DELETE_OBJ(device
->Backend
);
3778 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3782 // Open the "backend"
3783 V(device
->Backend
,open
)("Loopback");
3786 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3788 device
->next
= head
;
3789 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3792 TRACE("Created device %p\n", device
);
3796 /* alcIsRenderFormatSupportedSOFT
3798 * Determines if the loopback device supports the given format for rendering.
3800 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3802 ALCboolean ret
= ALC_FALSE
;
3804 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3805 alcSetError(device
, ALC_INVALID_DEVICE
);
3807 alcSetError(device
, ALC_INVALID_VALUE
);
3810 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3811 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3812 freq
>= MIN_OUTPUT_RATE
)
3815 if(device
) ALCdevice_DecRef(device
);
3820 /* alcRenderSamplesSOFT
3822 * Renders some samples into a buffer, using the format last set by the
3823 * attributes given to alcCreateContext.
3825 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3827 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3828 alcSetError(device
, ALC_INVALID_DEVICE
);
3829 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3830 alcSetError(device
, ALC_INVALID_VALUE
);
3832 aluMixData(device
, buffer
, samples
);
3833 if(device
) ALCdevice_DecRef(device
);
3837 /************************************************
3838 * ALC DSP pause/resume functions
3839 ************************************************/
3841 /* alcDevicePauseSOFT
3843 * Pause the DSP to stop audio processing.
3845 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3847 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3848 alcSetError(device
, ALC_INVALID_DEVICE
);
3852 if((device
->Flags
&DEVICE_RUNNING
))
3853 V0(device
->Backend
,stop
)();
3854 device
->Flags
&= ~DEVICE_RUNNING
;
3855 device
->Flags
|= DEVICE_PAUSED
;
3858 if(device
) ALCdevice_DecRef(device
);
3861 /* alcDeviceResumeSOFT
3863 * Resume the DSP to restart audio processing.
3865 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3867 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3868 alcSetError(device
, ALC_INVALID_DEVICE
);
3872 if((device
->Flags
&DEVICE_PAUSED
))
3874 device
->Flags
&= ~DEVICE_PAUSED
;
3875 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3877 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3878 device
->Flags
|= DEVICE_RUNNING
;
3881 alcSetError(device
, ALC_INVALID_DEVICE
);
3882 V0(device
->Backend
,lock
)();
3883 aluHandleDisconnect(device
);
3884 V0(device
->Backend
,unlock
)();
3890 if(device
) ALCdevice_DecRef(device
);