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
),
500 DECL(AL_FORMAT_BFORMAT2D_8
),
501 DECL(AL_FORMAT_BFORMAT2D_16
),
502 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
503 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
504 DECL(AL_FORMAT_BFORMAT3D_8
),
505 DECL(AL_FORMAT_BFORMAT3D_16
),
506 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
507 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
510 DECL(AL_STEREO_SOFT
),
513 DECL(AL_5POINT1_SOFT
),
514 DECL(AL_6POINT1_SOFT
),
515 DECL(AL_7POINT1_SOFT
),
518 DECL(AL_UNSIGNED_BYTE_SOFT
),
520 DECL(AL_UNSIGNED_SHORT_SOFT
),
522 DECL(AL_UNSIGNED_INT_SOFT
),
524 DECL(AL_DOUBLE_SOFT
),
526 DECL(AL_UNSIGNED_BYTE3_SOFT
),
532 DECL(AL_INTERNAL_FORMAT_SOFT
),
533 DECL(AL_BYTE_LENGTH_SOFT
),
534 DECL(AL_SAMPLE_LENGTH_SOFT
),
535 DECL(AL_SEC_LENGTH_SOFT
),
536 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
537 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
544 DECL(AL_INVALID_NAME
),
545 DECL(AL_INVALID_ENUM
),
546 DECL(AL_INVALID_VALUE
),
547 DECL(AL_INVALID_OPERATION
),
548 DECL(AL_OUT_OF_MEMORY
),
555 DECL(AL_DOPPLER_FACTOR
),
556 DECL(AL_DOPPLER_VELOCITY
),
557 DECL(AL_DISTANCE_MODEL
),
558 DECL(AL_SPEED_OF_SOUND
),
559 DECL(AL_SOURCE_DISTANCE_MODEL
),
560 DECL(AL_DEFERRED_UPDATES_SOFT
),
562 DECL(AL_INVERSE_DISTANCE
),
563 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
564 DECL(AL_LINEAR_DISTANCE
),
565 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
566 DECL(AL_EXPONENT_DISTANCE
),
567 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
569 DECL(AL_FILTER_TYPE
),
570 DECL(AL_FILTER_NULL
),
571 DECL(AL_FILTER_LOWPASS
),
572 DECL(AL_FILTER_HIGHPASS
),
573 DECL(AL_FILTER_BANDPASS
),
575 DECL(AL_LOWPASS_GAIN
),
576 DECL(AL_LOWPASS_GAINHF
),
578 DECL(AL_HIGHPASS_GAIN
),
579 DECL(AL_HIGHPASS_GAINLF
),
581 DECL(AL_BANDPASS_GAIN
),
582 DECL(AL_BANDPASS_GAINHF
),
583 DECL(AL_BANDPASS_GAINLF
),
585 DECL(AL_EFFECT_TYPE
),
586 DECL(AL_EFFECT_NULL
),
587 DECL(AL_EFFECT_REVERB
),
588 DECL(AL_EFFECT_EAXREVERB
),
589 DECL(AL_EFFECT_CHORUS
),
590 DECL(AL_EFFECT_DISTORTION
),
591 DECL(AL_EFFECT_ECHO
),
592 DECL(AL_EFFECT_FLANGER
),
594 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
595 DECL(AL_EFFECT_VOCAL_MORPHER
),
596 DECL(AL_EFFECT_PITCH_SHIFTER
),
598 DECL(AL_EFFECT_RING_MODULATOR
),
600 DECL(AL_EFFECT_AUTOWAH
),
602 DECL(AL_EFFECT_COMPRESSOR
),
603 DECL(AL_EFFECT_EQUALIZER
),
604 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
605 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
607 DECL(AL_EAXREVERB_DENSITY
),
608 DECL(AL_EAXREVERB_DIFFUSION
),
609 DECL(AL_EAXREVERB_GAIN
),
610 DECL(AL_EAXREVERB_GAINHF
),
611 DECL(AL_EAXREVERB_GAINLF
),
612 DECL(AL_EAXREVERB_DECAY_TIME
),
613 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
614 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
615 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
616 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
617 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
618 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
619 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
620 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
621 DECL(AL_EAXREVERB_ECHO_TIME
),
622 DECL(AL_EAXREVERB_ECHO_DEPTH
),
623 DECL(AL_EAXREVERB_MODULATION_TIME
),
624 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
625 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
626 DECL(AL_EAXREVERB_HFREFERENCE
),
627 DECL(AL_EAXREVERB_LFREFERENCE
),
628 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
629 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
631 DECL(AL_REVERB_DENSITY
),
632 DECL(AL_REVERB_DIFFUSION
),
633 DECL(AL_REVERB_GAIN
),
634 DECL(AL_REVERB_GAINHF
),
635 DECL(AL_REVERB_DECAY_TIME
),
636 DECL(AL_REVERB_DECAY_HFRATIO
),
637 DECL(AL_REVERB_REFLECTIONS_GAIN
),
638 DECL(AL_REVERB_REFLECTIONS_DELAY
),
639 DECL(AL_REVERB_LATE_REVERB_GAIN
),
640 DECL(AL_REVERB_LATE_REVERB_DELAY
),
641 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
642 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
643 DECL(AL_REVERB_DECAY_HFLIMIT
),
645 DECL(AL_CHORUS_WAVEFORM
),
646 DECL(AL_CHORUS_PHASE
),
647 DECL(AL_CHORUS_RATE
),
648 DECL(AL_CHORUS_DEPTH
),
649 DECL(AL_CHORUS_FEEDBACK
),
650 DECL(AL_CHORUS_DELAY
),
652 DECL(AL_DISTORTION_EDGE
),
653 DECL(AL_DISTORTION_GAIN
),
654 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
655 DECL(AL_DISTORTION_EQCENTER
),
656 DECL(AL_DISTORTION_EQBANDWIDTH
),
659 DECL(AL_ECHO_LRDELAY
),
660 DECL(AL_ECHO_DAMPING
),
661 DECL(AL_ECHO_FEEDBACK
),
662 DECL(AL_ECHO_SPREAD
),
664 DECL(AL_FLANGER_WAVEFORM
),
665 DECL(AL_FLANGER_PHASE
),
666 DECL(AL_FLANGER_RATE
),
667 DECL(AL_FLANGER_DEPTH
),
668 DECL(AL_FLANGER_FEEDBACK
),
669 DECL(AL_FLANGER_DELAY
),
671 DECL(AL_RING_MODULATOR_FREQUENCY
),
672 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
673 DECL(AL_RING_MODULATOR_WAVEFORM
),
676 DECL(AL_AUTOWAH_ATTACK_TIME
),
677 DECL(AL_AUTOWAH_PEAK_GAIN
),
678 DECL(AL_AUTOWAH_RELEASE_TIME
),
679 DECL(AL_AUTOWAH_RESONANCE
),
682 DECL(AL_COMPRESSOR_ONOFF
),
684 DECL(AL_EQUALIZER_LOW_GAIN
),
685 DECL(AL_EQUALIZER_LOW_CUTOFF
),
686 DECL(AL_EQUALIZER_MID1_GAIN
),
687 DECL(AL_EQUALIZER_MID1_CENTER
),
688 DECL(AL_EQUALIZER_MID1_WIDTH
),
689 DECL(AL_EQUALIZER_MID2_GAIN
),
690 DECL(AL_EQUALIZER_MID2_CENTER
),
691 DECL(AL_EQUALIZER_MID2_WIDTH
),
692 DECL(AL_EQUALIZER_HIGH_GAIN
),
693 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
695 DECL(AL_DEDICATED_GAIN
),
701 static const ALCchar alcNoError
[] = "No Error";
702 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
703 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
704 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
705 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
706 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
709 /************************************************
711 ************************************************/
713 /* Enumerated device names */
714 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
716 static al_string alcAllDevicesList
;
717 static al_string alcCaptureDeviceList
;
719 /* Default is always the first in the list */
720 static ALCchar
*alcDefaultAllDevicesSpecifier
;
721 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
723 /* Default context extensions */
724 static const ALchar alExtList
[] =
725 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
726 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
727 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
728 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
729 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
730 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
731 "AL_SOFT_source_latency AL_SOFT_source_length";
733 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
735 /* Thread-local current context */
736 static altss_t LocalContext
;
737 /* Process-wide current context */
738 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
740 /* Mixing thread piority level */
745 enum LogLevel LogLevel
= LogWarning
;
747 enum LogLevel LogLevel
= LogError
;
750 /* Flag to trap ALC device errors */
751 static ALCboolean TrapALCError
= ALC_FALSE
;
753 /* One-time configuration init control */
754 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
756 /* Default effect that applies to sources that don't have an effect on send 0 */
757 static ALeffect DefaultEffect
;
759 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
762 static ALCboolean SuspendDefers
= ALC_TRUE
;
765 /************************************************
767 ************************************************/
768 static const ALCchar alcNoDeviceExtList
[] =
769 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
770 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
771 static const ALCchar alcExtensionList
[] =
772 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
773 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
774 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
775 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
776 static const ALCint alcMajorVersion
= 1;
777 static const ALCint alcMinorVersion
= 1;
779 static const ALCint alcEFXMajorVersion
= 1;
780 static const ALCint alcEFXMinorVersion
= 0;
783 /************************************************
785 ************************************************/
786 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
788 static almtx_t ListLock
;
789 static inline void LockLists(void)
791 int lockret
= almtx_lock(&ListLock
);
792 assert(lockret
== althrd_success
);
794 static inline void UnlockLists(void)
796 int unlockret
= almtx_unlock(&ListLock
);
797 assert(unlockret
== althrd_success
);
800 /************************************************
801 * Library initialization
802 ************************************************/
804 static void alc_init(void);
805 static void alc_deinit(void);
806 static void alc_deinit_safe(void);
808 #ifndef AL_LIBTYPE_STATIC
809 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
813 case DLL_PROCESS_ATTACH
:
814 /* Pin the DLL so we won't get unloaded until the process terminates */
815 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
816 (WCHAR
*)hModule
, &hModule
);
820 case DLL_THREAD_DETACH
:
823 case DLL_PROCESS_DETACH
:
832 #elif defined(_MSC_VER)
833 #pragma section(".CRT$XCU",read)
834 static void alc_constructor(void);
835 static void alc_destructor(void);
836 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
838 static void alc_constructor(void)
840 atexit(alc_destructor
);
844 static void alc_destructor(void)
848 #elif defined(HAVE_GCC_DESTRUCTOR)
849 static void alc_init(void) __attribute__((constructor
));
850 static void alc_deinit(void) __attribute__((destructor
));
852 #error "No static initialization available on this platform!"
855 #elif defined(HAVE_GCC_DESTRUCTOR)
857 static void alc_init(void) __attribute__((constructor
));
858 static void alc_deinit(void) __attribute__((destructor
));
861 #error "No global initialization available on this platform!"
864 static void ReleaseThreadCtx(void *ptr
);
865 static void alc_init(void)
872 AL_STRING_INIT(alcAllDevicesList
);
873 AL_STRING_INIT(alcCaptureDeviceList
);
875 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
876 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
879 str
= getenv("__ALSOFT_REVERSE_Z");
880 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
883 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
884 assert(ret
== althrd_success
);
886 ret
= almtx_init(&ListLock
, almtx_recursive
);
887 assert(ret
== althrd_success
);
892 static void alc_initconfig(void)
894 const char *devs
, *str
;
899 str
= getenv("ALSOFT_LOGLEVEL");
902 long lvl
= strtol(str
, NULL
, 0);
903 if(lvl
>= NoLog
&& lvl
<= LogRef
)
907 str
= getenv("ALSOFT_LOGFILE");
910 FILE *logfile
= al_fopen(str
, "wt");
911 if(logfile
) LogFile
= logfile
;
912 else ERR("Failed to open log file '%s'\n", str
);
917 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
918 for(i
= 1;BackendList
[i
].name
;i
++)
919 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
920 TRACE("Supported backends: %s\n", buf
);
924 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
927 if(strcasecmp(str
, "ignore") == 0)
929 SuspendDefers
= ALC_FALSE
;
930 TRACE("Selected context suspend behavior, \"ignore\"\n");
933 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
937 #if defined(HAVE_SSE4_1)
938 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE4_1
;
939 #elif defined(HAVE_SSE2)
940 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
941 #elif defined(HAVE_SSE)
942 capfilter
|= CPU_CAP_SSE
;
945 capfilter
|= CPU_CAP_NEON
;
947 if(ConfigValueStr(NULL
, "disable-cpu-exts", &str
))
949 if(strcasecmp(str
, "all") == 0)
954 const char *next
= str
;
958 while(isspace(str
[0]))
960 next
= strchr(str
, ',');
962 if(!str
[0] || str
[0] == ',')
965 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
966 while(len
> 0 && isspace(str
[len
-1]))
968 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
969 capfilter
&= ~CPU_CAP_SSE
;
970 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
971 capfilter
&= ~CPU_CAP_SSE2
;
972 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
973 capfilter
&= ~CPU_CAP_SSE4_1
;
974 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
975 capfilter
&= ~CPU_CAP_NEON
;
977 WARN("Invalid CPU extension \"%s\"\n", str
);
981 FillCPUCaps(capfilter
);
988 ConfigValueInt(NULL
, "rt-prio", &RTPrioLevel
);
990 if(ConfigValueStr(NULL
, "resampler", &str
))
992 if(strcasecmp(str
, "point") == 0 || strcasecmp(str
, "none") == 0)
993 DefaultResampler
= PointResampler
;
994 else if(strcasecmp(str
, "linear") == 0)
995 DefaultResampler
= LinearResampler
;
996 else if(strcasecmp(str
, "cubic") == 0)
997 DefaultResampler
= CubicResampler
;
1002 n
= strtol(str
, &end
, 0);
1003 if(*end
== '\0' && (n
== PointResampler
|| n
== LinearResampler
|| n
== CubicResampler
))
1004 DefaultResampler
= n
;
1006 WARN("Invalid resampler: %s\n", str
);
1009 aluInitResamplers();
1011 str
= getenv("ALSOFT_TRAP_ERROR");
1012 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1014 TrapALError
= AL_TRUE
;
1015 TrapALCError
= AL_TRUE
;
1019 str
= getenv("ALSOFT_TRAP_AL_ERROR");
1020 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1021 TrapALError
= AL_TRUE
;
1022 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
1024 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1025 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1026 TrapALCError
= ALC_TRUE
;
1027 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
1030 if(ConfigValueFloat("reverb", "boost", &valf
))
1031 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1033 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
1035 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1036 ConfigValueStr(NULL
, "drivers", &devs
))
1040 const char *next
= devs
;
1041 int endlist
, delitem
;
1046 while(isspace(devs
[0]))
1048 next
= strchr(devs
, ',');
1050 delitem
= (devs
[0] == '-');
1051 if(devs
[0] == '-') devs
++;
1053 if(!devs
[0] || devs
[0] == ',')
1060 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1061 while(len
> 0 && isspace(devs
[len
-1]))
1063 for(n
= i
;BackendList
[n
].name
;n
++)
1065 if(len
== strlen(BackendList
[n
].name
) &&
1066 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1071 BackendList
[n
] = BackendList
[n
+1];
1073 } while(BackendList
[n
].name
);
1077 struct BackendInfo Bkp
= BackendList
[n
];
1080 BackendList
[n
] = BackendList
[n
-1];
1083 BackendList
[n
] = Bkp
;
1094 BackendList
[i
].name
= NULL
;
1095 BackendList
[i
].getFactory
= NULL
;
1096 BackendList
[i
].Init
= NULL
;
1097 BackendList
[i
].Deinit
= NULL
;
1098 BackendList
[i
].Probe
= NULL
;
1102 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1104 if(BackendList
[i
].getFactory
)
1106 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1107 if(!V0(factory
,init
)())
1109 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1113 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1114 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1116 PlaybackBackend
= BackendList
[i
];
1117 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1119 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1121 CaptureBackend
= BackendList
[i
];
1122 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1128 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1130 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1134 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1135 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1137 PlaybackBackend
= BackendList
[i
];
1138 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1140 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1142 CaptureBackend
= BackendList
[i
];
1143 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1147 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1151 if(ConfigValueStr(NULL
, "excludefx", &str
))
1154 const char *next
= str
;
1158 next
= strchr(str
, ',');
1160 if(!str
[0] || next
== str
)
1163 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1164 for(n
= 0;EffectList
[n
].name
;n
++)
1166 if(len
== strlen(EffectList
[n
].name
) &&
1167 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1168 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1173 InitEffectFactoryMap();
1175 InitEffect(&DefaultEffect
);
1176 str
= getenv("ALSOFT_DEFAULT_REVERB");
1177 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1178 LoadReverbPreset(str
, &DefaultEffect
);
1180 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1183 /************************************************
1184 * Library deinitialization
1185 ************************************************/
1186 static void alc_cleanup(void)
1190 AL_STRING_DEINIT(alcAllDevicesList
);
1191 AL_STRING_DEINIT(alcCaptureDeviceList
);
1193 free(alcDefaultAllDevicesSpecifier
);
1194 alcDefaultAllDevicesSpecifier
= NULL
;
1195 free(alcCaptureDefaultDeviceSpecifier
);
1196 alcCaptureDefaultDeviceSpecifier
= NULL
;
1198 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1203 } while((dev
=dev
->next
) != NULL
);
1204 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1207 DeinitEffectFactoryMap();
1210 static void alc_deinit_safe(void)
1218 almtx_destroy(&ListLock
);
1219 altss_delete(LocalContext
);
1221 if(LogFile
!= stderr
)
1226 static void alc_deinit(void)
1232 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1233 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1235 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1237 if(!BackendList
[i
].getFactory
)
1238 BackendList
[i
].Deinit();
1241 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1242 V0(factory
,deinit
)();
1246 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1247 V0(factory
,deinit
)();
1254 /************************************************
1255 * Device enumeration
1256 ************************************************/
1257 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1262 al_string_clear(list
);
1264 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1266 if(!PlaybackBackend
.getFactory
)
1267 PlaybackBackend
.Probe(type
);
1270 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1271 V(factory
,probe
)(type
);
1274 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1276 if(!CaptureBackend
.getFactory
)
1277 CaptureBackend
.Probe(type
);
1280 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1281 V(factory
,probe
)(type
);
1286 static void ProbeAllDevicesList(void)
1287 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1288 static void ProbeCaptureDeviceList(void)
1289 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1291 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1293 size_t len
= strlen(name
);
1295 al_string_append_range(devnames
, name
, name
+len
+1);
1297 void AppendAllDevicesList(const ALCchar
*name
)
1298 { AppendDevice(name
, &alcAllDevicesList
); }
1299 void AppendCaptureDeviceList(const ALCchar
*name
)
1300 { AppendDevice(name
, &alcCaptureDeviceList
); }
1303 /************************************************
1304 * Device format information
1305 ************************************************/
1306 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1310 case DevFmtByte
: return "Signed Byte";
1311 case DevFmtUByte
: return "Unsigned Byte";
1312 case DevFmtShort
: return "Signed Short";
1313 case DevFmtUShort
: return "Unsigned Short";
1314 case DevFmtInt
: return "Signed Int";
1315 case DevFmtUInt
: return "Unsigned Int";
1316 case DevFmtFloat
: return "Float";
1318 return "(unknown type)";
1320 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1324 case DevFmtMono
: return "Mono";
1325 case DevFmtStereo
: return "Stereo";
1326 case DevFmtQuad
: return "Quadraphonic";
1327 case DevFmtX51
: return "5.1 Surround";
1328 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1329 case DevFmtX61
: return "6.1 Surround";
1330 case DevFmtX71
: return "7.1 Surround";
1331 case DevFmtBFormat3D
: return "B-Format 3D";
1333 return "(unknown channels)";
1336 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1337 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1341 case DevFmtByte
: return sizeof(ALbyte
);
1342 case DevFmtUByte
: return sizeof(ALubyte
);
1343 case DevFmtShort
: return sizeof(ALshort
);
1344 case DevFmtUShort
: return sizeof(ALushort
);
1345 case DevFmtInt
: return sizeof(ALint
);
1346 case DevFmtUInt
: return sizeof(ALuint
);
1347 case DevFmtFloat
: return sizeof(ALfloat
);
1351 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1355 case DevFmtMono
: return 1;
1356 case DevFmtStereo
: return 2;
1357 case DevFmtQuad
: return 4;
1358 case DevFmtX51
: return 6;
1359 case DevFmtX51Rear
: return 6;
1360 case DevFmtX61
: return 7;
1361 case DevFmtX71
: return 8;
1362 case DevFmtBFormat3D
: return 4;
1367 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1368 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1370 static const struct {
1372 enum DevFmtChannels channels
;
1373 enum DevFmtType type
;
1375 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1376 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1377 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1379 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1380 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1381 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1383 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1384 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1385 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1387 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1388 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1389 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1391 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1392 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1393 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1395 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1396 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1397 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1401 for(i
= 0;i
< COUNTOF(list
);i
++)
1403 if(list
[i
].format
== format
)
1405 *chans
= list
[i
].channels
;
1406 *type
= list
[i
].type
;
1414 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1419 case ALC_UNSIGNED_BYTE_SOFT
:
1420 case ALC_SHORT_SOFT
:
1421 case ALC_UNSIGNED_SHORT_SOFT
:
1423 case ALC_UNSIGNED_INT_SOFT
:
1424 case ALC_FLOAT_SOFT
:
1430 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1435 case ALC_STEREO_SOFT
:
1437 case ALC_5POINT1_SOFT
:
1438 case ALC_6POINT1_SOFT
:
1439 case ALC_7POINT1_SOFT
:
1446 /************************************************
1447 * Miscellaneous ALC helpers
1448 ************************************************/
1449 extern inline void LockContext(ALCcontext
*context
);
1450 extern inline void UnlockContext(ALCcontext
*context
);
1452 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1454 return V0(device
->Backend
,getLatency
)();
1457 void ALCdevice_Lock(ALCdevice
*device
)
1459 V0(device
->Backend
,lock
)();
1462 void ALCdevice_Unlock(ALCdevice
*device
)
1464 V0(device
->Backend
,unlock
)();
1468 /* SetDefaultWFXChannelOrder
1470 * Sets the default channel order used by WaveFormatEx.
1472 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1476 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1477 device
->ChannelName
[i
] = InvalidChannel
;
1479 switch(device
->FmtChans
)
1482 device
->ChannelName
[0] = FrontCenter
;
1485 device
->ChannelName
[0] = FrontLeft
;
1486 device
->ChannelName
[1] = FrontRight
;
1489 device
->ChannelName
[0] = FrontLeft
;
1490 device
->ChannelName
[1] = FrontRight
;
1491 device
->ChannelName
[2] = BackLeft
;
1492 device
->ChannelName
[3] = BackRight
;
1495 device
->ChannelName
[0] = FrontLeft
;
1496 device
->ChannelName
[1] = FrontRight
;
1497 device
->ChannelName
[2] = FrontCenter
;
1498 device
->ChannelName
[3] = LFE
;
1499 device
->ChannelName
[4] = SideLeft
;
1500 device
->ChannelName
[5] = SideRight
;
1503 device
->ChannelName
[0] = FrontLeft
;
1504 device
->ChannelName
[1] = FrontRight
;
1505 device
->ChannelName
[2] = FrontCenter
;
1506 device
->ChannelName
[3] = LFE
;
1507 device
->ChannelName
[4] = BackLeft
;
1508 device
->ChannelName
[5] = BackRight
;
1511 device
->ChannelName
[0] = FrontLeft
;
1512 device
->ChannelName
[1] = FrontRight
;
1513 device
->ChannelName
[2] = FrontCenter
;
1514 device
->ChannelName
[3] = LFE
;
1515 device
->ChannelName
[4] = BackCenter
;
1516 device
->ChannelName
[5] = SideLeft
;
1517 device
->ChannelName
[6] = SideRight
;
1520 device
->ChannelName
[0] = FrontLeft
;
1521 device
->ChannelName
[1] = FrontRight
;
1522 device
->ChannelName
[2] = FrontCenter
;
1523 device
->ChannelName
[3] = LFE
;
1524 device
->ChannelName
[4] = BackLeft
;
1525 device
->ChannelName
[5] = BackRight
;
1526 device
->ChannelName
[6] = SideLeft
;
1527 device
->ChannelName
[7] = SideRight
;
1529 case DevFmtBFormat3D
:
1530 device
->ChannelName
[0] = Aux0
;
1531 device
->ChannelName
[1] = Aux1
;
1532 device
->ChannelName
[2] = Aux2
;
1533 device
->ChannelName
[3] = Aux3
;
1538 /* SetDefaultChannelOrder
1540 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1542 void SetDefaultChannelOrder(ALCdevice
*device
)
1546 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1547 device
->ChannelName
[i
] = InvalidChannel
;
1549 switch(device
->FmtChans
)
1552 device
->ChannelName
[0] = FrontLeft
;
1553 device
->ChannelName
[1] = FrontRight
;
1554 device
->ChannelName
[2] = BackLeft
;
1555 device
->ChannelName
[3] = BackRight
;
1556 device
->ChannelName
[4] = FrontCenter
;
1557 device
->ChannelName
[5] = LFE
;
1560 device
->ChannelName
[0] = FrontLeft
;
1561 device
->ChannelName
[1] = FrontRight
;
1562 device
->ChannelName
[2] = BackLeft
;
1563 device
->ChannelName
[3] = BackRight
;
1564 device
->ChannelName
[4] = FrontCenter
;
1565 device
->ChannelName
[5] = LFE
;
1566 device
->ChannelName
[6] = SideLeft
;
1567 device
->ChannelName
[7] = SideRight
;
1570 /* Same as WFX order */
1576 case DevFmtBFormat3D
:
1577 SetDefaultWFXChannelOrder(device
);
1582 extern inline ALint
GetChannelIdxByName(const ALCdevice
*device
, enum Channel chan
);
1585 /* ALCcontext_DeferUpdates
1587 * Defers/suspends updates for the given context's listener and sources. This
1588 * does *NOT* stop mixing, but rather prevents certain property changes from
1591 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1593 ALCdevice
*device
= context
->Device
;
1596 SetMixerFPUMode(&oldMode
);
1598 V0(device
->Backend
,lock
)();
1599 if(!ExchangeInt(&context
->DeferUpdates
, AL_TRUE
))
1601 ALboolean UpdateSources
;
1602 ALvoice
*voice
, *voice_end
;
1603 ALeffectslot
**slot
, **slot_end
;
1604 /* Make sure all pending updates are performed */
1605 UpdateSources
= ATOMIC_EXCHANGE(ALenum
, &context
->UpdateSources
, AL_FALSE
);
1607 voice
= context
->Voices
;
1608 voice_end
= voice
+ context
->VoiceCount
;
1609 while(voice
!= voice_end
)
1611 ALsource
*source
= voice
->Source
;
1612 if(!source
) goto next
;
1614 if(source
->state
!= AL_PLAYING
&& source
->state
!= AL_PAUSED
)
1616 voice
->Source
= NULL
;
1620 if(ATOMIC_EXCHANGE(ALenum
, &source
->NeedsUpdate
, AL_FALSE
) || UpdateSources
)
1621 voice
->Update(voice
, source
, context
);
1626 slot
= VECTOR_ITER_BEGIN(context
->ActiveAuxSlots
);
1627 slot_end
= VECTOR_ITER_END(context
->ActiveAuxSlots
);
1628 while(slot
!= slot_end
)
1630 if(ATOMIC_EXCHANGE(ALenum
, &(*slot
)->NeedsUpdate
, AL_FALSE
))
1631 V((*slot
)->EffectState
,update
)(context
->Device
, *slot
);
1635 V0(device
->Backend
,unlock
)();
1637 RestoreFPUMode(&oldMode
);
1640 /* ALCcontext_ProcessUpdates
1642 * Resumes update processing after being deferred.
1644 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1646 ALCdevice
*device
= context
->Device
;
1648 V0(device
->Backend
,lock
)();
1649 if(ExchangeInt(&context
->DeferUpdates
, AL_FALSE
))
1653 LockUIntMapRead(&context
->SourceMap
);
1654 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1656 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1659 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1660 Source
->Offset
>= 0.0)
1662 ReadLock(&Source
->queue_lock
);
1663 ApplyOffset(Source
);
1664 ReadUnlock(&Source
->queue_lock
);
1667 new_state
= ExchangeInt(&Source
->new_state
, AL_NONE
);
1669 SetSourceState(Source
, context
, new_state
);
1671 UnlockUIntMapRead(&context
->SourceMap
);
1673 V0(device
->Backend
,unlock
)();
1679 * Stores the latest ALC device error
1681 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1686 /* DebugBreak() will cause an exception if there is no debugger */
1687 if(IsDebuggerPresent())
1689 #elif defined(SIGTRAP)
1695 ATOMIC_STORE(&device
->LastError
, errorCode
);
1697 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1703 * Updates the device's base clock time with however many samples have been
1704 * done. This is used so frequency changes on the device don't cause the time
1705 * to jump forward or back.
1707 static inline void UpdateClockBase(ALCdevice
*device
)
1709 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1710 device
->SamplesDone
= 0;
1713 /* UpdateDeviceParams
1715 * Updates device parameters according to the attribute list (caller is
1716 * responsible for holding the list lock).
1718 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1720 ALCcontext
*context
;
1721 enum DevFmtChannels oldChans
;
1722 enum DevFmtType oldType
;
1727 // Check for attributes
1728 if(device
->Type
== Loopback
)
1734 GotAll
= GotFreq
|GotChans
|GotType
1736 ALCuint freq
, numMono
, numStereo
, numSends
, flags
;
1737 enum DevFmtChannels schans
;
1738 enum DevFmtType stype
;
1739 ALCuint attrIdx
= 0;
1744 WARN("Missing attributes for loopback device\n");
1745 return ALC_INVALID_VALUE
;
1748 numMono
= device
->NumMonoSources
;
1749 numStereo
= device
->NumStereoSources
;
1750 numSends
= device
->NumAuxSends
;
1751 schans
= device
->FmtChans
;
1752 stype
= device
->FmtType
;
1753 freq
= device
->Frequency
;
1754 flags
= device
->Flags
;
1756 while(attrList
[attrIdx
])
1758 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1760 ALCint val
= attrList
[attrIdx
+ 1];
1761 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1762 return ALC_INVALID_VALUE
;
1767 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1769 ALCint val
= attrList
[attrIdx
+ 1];
1770 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1771 return ALC_INVALID_VALUE
;
1776 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1778 freq
= attrList
[attrIdx
+ 1];
1779 if(freq
< MIN_OUTPUT_RATE
)
1780 return ALC_INVALID_VALUE
;
1784 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1786 numStereo
= attrList
[attrIdx
+ 1];
1787 if(numStereo
> device
->MaxNoOfSources
)
1788 numStereo
= device
->MaxNoOfSources
;
1790 numMono
= device
->MaxNoOfSources
- numStereo
;
1793 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1794 numSends
= attrList
[attrIdx
+ 1];
1796 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1798 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1799 flags
|= DEVICE_HRTF_REQUEST
;
1801 flags
&= ~DEVICE_HRTF_REQUEST
;
1807 if(gotFmt
!= GotAll
)
1809 WARN("Missing format for loopback device\n");
1810 return ALC_INVALID_VALUE
;
1813 ConfigValueUInt(NULL
, "sends", &numSends
);
1814 numSends
= minu(MAX_SENDS
, numSends
);
1816 if((device
->Flags
&DEVICE_RUNNING
))
1817 V0(device
->Backend
,stop
)();
1818 device
->Flags
= (flags
& ~DEVICE_RUNNING
);
1820 UpdateClockBase(device
);
1822 device
->Frequency
= freq
;
1823 device
->FmtChans
= schans
;
1824 device
->FmtType
= stype
;
1825 device
->NumMonoSources
= numMono
;
1826 device
->NumStereoSources
= numStereo
;
1827 device
->NumAuxSends
= numSends
;
1829 else if(attrList
&& attrList
[0])
1831 ALCuint freq
, numMono
, numStereo
, numSends
;
1832 ALCuint attrIdx
= 0;
1834 /* If a context is already running on the device, stop playback so the
1835 * device attributes can be updated. */
1836 if((device
->Flags
&DEVICE_RUNNING
))
1837 V0(device
->Backend
,stop
)();
1838 device
->Flags
&= ~DEVICE_RUNNING
;
1840 freq
= device
->Frequency
;
1841 numMono
= device
->NumMonoSources
;
1842 numStereo
= device
->NumStereoSources
;
1843 numSends
= device
->NumAuxSends
;
1845 while(attrList
[attrIdx
])
1847 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1849 freq
= attrList
[attrIdx
+ 1];
1850 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1853 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1855 numStereo
= attrList
[attrIdx
+ 1];
1856 if(numStereo
> device
->MaxNoOfSources
)
1857 numStereo
= device
->MaxNoOfSources
;
1859 numMono
= device
->MaxNoOfSources
- numStereo
;
1862 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1863 numSends
= attrList
[attrIdx
+ 1];
1865 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1867 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1868 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1870 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1876 ConfigValueUInt(NULL
, "frequency", &freq
);
1877 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1879 ConfigValueUInt(NULL
, "sends", &numSends
);
1880 numSends
= minu(MAX_SENDS
, numSends
);
1882 UpdateClockBase(device
);
1884 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1886 /* SSE and Neon do best with the update size being a multiple of 4 */
1887 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1888 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1890 device
->Frequency
= freq
;
1891 device
->NumMonoSources
= numMono
;
1892 device
->NumStereoSources
= numStereo
;
1893 device
->NumAuxSends
= numSends
;
1896 if((device
->Flags
&DEVICE_RUNNING
))
1897 return ALC_NO_ERROR
;
1899 al_free(device
->DryBuffer
);
1900 device
->DryBuffer
= NULL
;
1902 UpdateClockBase(device
);
1904 if(device
->Type
!= Loopback
&& ((device
->Flags
&DEVICE_HRTF_REQUEST
) || GetConfigValueBool(NULL
, "hrtf", 0)))
1906 if(!FindHrtfFormat(&device
->FmtChans
, &device
->Frequency
))
1907 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1909 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
|
1910 DEVICE_HRTF_REQUEST
;
1912 if(device
->Type
== Loopback
&& (device
->Flags
&DEVICE_HRTF_REQUEST
))
1914 enum DevFmtChannels chans
= device
->FmtChans
;
1915 ALCuint freq
= device
->Frequency
;
1916 if(!FindHrtfFormat(&chans
, &freq
) || chans
!= device
->FmtChans
|| freq
!= device
->Frequency
)
1918 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1919 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1920 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1924 oldFreq
= device
->Frequency
;
1925 oldChans
= device
->FmtChans
;
1926 oldType
= device
->FmtType
;
1928 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1929 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1930 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1931 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1932 device
->UpdateSize
, device
->NumUpdates
1935 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1936 return ALC_INVALID_DEVICE
;
1938 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1940 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1941 DevFmtChannelsString(device
->FmtChans
));
1942 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1944 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1946 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1947 DevFmtTypeString(device
->FmtType
));
1948 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1950 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1952 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1953 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1956 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1957 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1958 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1961 if((device
->UpdateSize
&3) != 0)
1963 if((CPUCapFlags
&CPU_CAP_SSE
))
1964 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1965 if((CPUCapFlags
&CPU_CAP_NEON
))
1966 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1969 device
->Hrtf
= NULL
;
1970 if(device
->FmtChans
!= DevFmtStereo
)
1973 device
->Bs2b
= NULL
;
1977 bool headphones
= device
->IsHeadphones
;
1982 if(device
->Type
!= Loopback
&& ConfigValueStr(NULL
, "stereo-mode", &mode
))
1984 if(strcasecmp(mode
, "headphones") == 0)
1986 else if(strcasecmp(mode
, "speakers") == 0)
1988 else if(strcasecmp(mode
, "auto") != 0)
1989 ERR("Unexpected stereo-mode: %s\n", mode
);
1992 if(device
->Type
== Loopback
|| !ConfigValueBool(NULL
, "hrtf", &usehrtf
))
1993 usehrtf
= ((device
->Flags
&DEVICE_HRTF_REQUEST
) || headphones
);
1996 device
->Hrtf
= GetHrtf(device
->FmtChans
, device
->Frequency
);
1998 TRACE("HRTF enabled\n");
2001 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
2002 TRACE("HRTF disabled\n");
2004 bs2blevel
= (headphones
? 5 : 0);
2005 if(device
->Type
!= Loopback
)
2006 ConfigValueInt(NULL
, "cf_level", &bs2blevel
);
2007 if(bs2blevel
> 0 && bs2blevel
<= 6)
2011 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
2012 bs2b_clear(device
->Bs2b
);
2014 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
2015 bs2b_set_level(device
->Bs2b
, bs2blevel
);
2016 TRACE("BS2B enabled\n");
2021 device
->Bs2b
= NULL
;
2022 TRACE("BS2B disabled\n");
2027 aluInitPanning(device
);
2029 /* With HRTF enabled, virtual channels are allocated for B-Format and
2030 * effects renfering. Two extra channels are allocated for the actual HRTF-
2033 size
= sizeof(device
->DryBuffer
[0]) * (device
->NumChannels
+ (device
->Hrtf
? 2 : 0));
2034 device
->DryBuffer
= al_calloc(16, size
);
2035 if(!device
->DryBuffer
)
2037 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2038 return ALC_INVALID_DEVICE
;
2041 V(device
->Synth
,update
)(device
);
2043 SetMixerFPUMode(&oldMode
);
2044 V0(device
->Backend
,lock
)();
2045 context
= ATOMIC_LOAD(&device
->ContextList
);
2050 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2051 LockUIntMapRead(&context
->EffectSlotMap
);
2052 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2054 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2056 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2058 UnlockUIntMapRead(&context
->EffectSlotMap
);
2059 V0(device
->Backend
,unlock
)();
2060 RestoreFPUMode(&oldMode
);
2061 return ALC_INVALID_DEVICE
;
2063 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2064 V(slot
->EffectState
,update
)(device
, slot
);
2066 UnlockUIntMapRead(&context
->EffectSlotMap
);
2068 LockUIntMapRead(&context
->SourceMap
);
2069 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2071 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2072 ALuint s
= device
->NumAuxSends
;
2073 while(s
< MAX_SENDS
)
2075 if(source
->Send
[s
].Slot
)
2076 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2077 source
->Send
[s
].Slot
= NULL
;
2078 source
->Send
[s
].Gain
= 1.0f
;
2079 source
->Send
[s
].GainHF
= 1.0f
;
2082 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2084 UnlockUIntMapRead(&context
->SourceMap
);
2086 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2088 ALvoice
*voice
= &context
->Voices
[pos
];
2089 ALsource
*source
= voice
->Source
;
2090 ALuint s
= device
->NumAuxSends
;
2092 while(s
< MAX_SENDS
)
2094 voice
->Send
[s
].Moving
= AL_FALSE
;
2095 voice
->Send
[s
].Counter
= 0;
2101 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2102 voice
->Update(voice
, source
, context
);
2106 context
= context
->next
;
2108 if(device
->DefaultSlot
)
2110 ALeffectslot
*slot
= device
->DefaultSlot
;
2112 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2114 V0(device
->Backend
,unlock
)();
2115 RestoreFPUMode(&oldMode
);
2116 return ALC_INVALID_DEVICE
;
2118 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2119 V(slot
->EffectState
,update
)(device
, slot
);
2121 V0(device
->Backend
,unlock
)();
2122 RestoreFPUMode(&oldMode
);
2124 if(!(device
->Flags
&DEVICE_PAUSED
))
2126 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2127 return ALC_INVALID_DEVICE
;
2128 device
->Flags
|= DEVICE_RUNNING
;
2131 return ALC_NO_ERROR
;
2136 * Frees the device structure, and destroys any objects the app failed to
2137 * delete. Called once there's no more references on the device.
2139 static ALCvoid
FreeDevice(ALCdevice
*device
)
2141 TRACE("%p\n", device
);
2143 V0(device
->Backend
,close
)();
2144 DELETE_OBJ(device
->Backend
);
2145 device
->Backend
= NULL
;
2147 DELETE_OBJ(device
->Synth
);
2148 device
->Synth
= NULL
;
2150 if(device
->DefaultSlot
)
2152 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2153 device
->DefaultSlot
= NULL
;
2157 if(device
->DefaultSfont
)
2158 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
2159 device
->DefaultSfont
= NULL
;
2161 if(device
->BufferMap
.size
> 0)
2163 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2164 ReleaseALBuffers(device
);
2166 ResetUIntMap(&device
->BufferMap
);
2168 if(device
->EffectMap
.size
> 0)
2170 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2171 ReleaseALEffects(device
);
2173 ResetUIntMap(&device
->EffectMap
);
2175 if(device
->FilterMap
.size
> 0)
2177 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2178 ReleaseALFilters(device
);
2180 ResetUIntMap(&device
->FilterMap
);
2182 if(device
->SfontMap
.size
> 0)
2184 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2185 ReleaseALSoundfonts(device
);
2187 ResetUIntMap(&device
->SfontMap
);
2189 if(device
->PresetMap
.size
> 0)
2191 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2192 ReleaseALPresets(device
);
2194 ResetUIntMap(&device
->PresetMap
);
2196 if(device
->FontsoundMap
.size
> 0)
2198 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2199 ReleaseALFontsounds(device
);
2201 ResetUIntMap(&device
->FontsoundMap
);
2204 device
->Bs2b
= NULL
;
2206 AL_STRING_DEINIT(device
->DeviceName
);
2208 al_free(device
->DryBuffer
);
2209 device
->DryBuffer
= NULL
;
2215 void ALCdevice_IncRef(ALCdevice
*device
)
2218 ref
= IncrementRef(&device
->ref
);
2219 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2222 void ALCdevice_DecRef(ALCdevice
*device
)
2225 ref
= DecrementRef(&device
->ref
);
2226 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2227 if(ref
== 0) FreeDevice(device
);
2232 * Checks if the device handle is valid, and increments its ref count if so.
2234 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2236 ALCdevice
*tmpDevice
;
2242 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2243 while(tmpDevice
&& tmpDevice
!= device
)
2244 tmpDevice
= tmpDevice
->next
;
2247 ALCdevice_IncRef(tmpDevice
);
2255 * Initializes context fields
2257 static ALvoid
InitContext(ALCcontext
*Context
)
2259 //Initialise listener
2260 Context
->Listener
->Gain
= 1.0f
;
2261 Context
->Listener
->MetersPerUnit
= 1.0f
;
2262 aluVectorSet(&Context
->Listener
->Position
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
2263 aluVectorSet(&Context
->Listener
->Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2264 Context
->Listener
->Forward
[0] = 0.0f
;
2265 Context
->Listener
->Forward
[1] = 0.0f
;
2266 Context
->Listener
->Forward
[2] = -1.0f
;
2267 Context
->Listener
->Up
[0] = 0.0f
;
2268 Context
->Listener
->Up
[1] = 1.0f
;
2269 Context
->Listener
->Up
[2] = 0.0f
;
2270 aluMatrixSet(&Context
->Listener
->Params
.Matrix
,
2271 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2272 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2273 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2274 0.0f
, 0.0f
, 0.0f
, 1.0f
2276 aluVectorSet(&Context
->Listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2279 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2280 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2281 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2282 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2285 Context
->DistanceModel
= DefaultDistanceModel
;
2286 Context
->SourceDistanceModel
= AL_FALSE
;
2287 Context
->DopplerFactor
= 1.0f
;
2288 Context
->DopplerVelocity
= 1.0f
;
2289 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2290 Context
->DeferUpdates
= AL_FALSE
;
2292 Context
->ExtensionList
= alExtList
;
2298 * Cleans up the context, and destroys any remaining objects the app failed to
2299 * delete. Called once there's no more references on the context.
2301 static void FreeContext(ALCcontext
*context
)
2303 TRACE("%p\n", context
);
2305 if(context
->SourceMap
.size
> 0)
2307 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2308 ReleaseALSources(context
);
2310 ResetUIntMap(&context
->SourceMap
);
2312 if(context
->EffectSlotMap
.size
> 0)
2314 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2315 ReleaseALAuxiliaryEffectSlots(context
);
2317 ResetUIntMap(&context
->EffectSlotMap
);
2319 al_free(context
->Voices
);
2320 context
->Voices
= NULL
;
2321 context
->VoiceCount
= 0;
2322 context
->MaxVoices
= 0;
2324 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2326 ALCdevice_DecRef(context
->Device
);
2327 context
->Device
= NULL
;
2329 //Invalidate context
2330 memset(context
, 0, sizeof(ALCcontext
));
2336 * Removes the context reference from the given device and removes it from
2337 * being current on the running thread or globally.
2339 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2341 ALCcontext
*nextctx
;
2342 ALCcontext
*origctx
;
2344 if(altss_get(LocalContext
) == context
)
2346 WARN("%p released while current on thread\n", context
);
2347 altss_set(LocalContext
, NULL
);
2348 ALCcontext_DecRef(context
);
2352 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2353 ALCcontext_DecRef(context
);
2355 ALCdevice_Lock(device
);
2357 nextctx
= context
->next
;
2358 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2364 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2366 ALCdevice_Unlock(device
);
2368 ALCcontext_DecRef(context
);
2371 void ALCcontext_IncRef(ALCcontext
*context
)
2374 ref
= IncrementRef(&context
->ref
);
2375 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2378 void ALCcontext_DecRef(ALCcontext
*context
)
2381 ref
= DecrementRef(&context
->ref
);
2382 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2383 if(ref
== 0) FreeContext(context
);
2386 static void ReleaseThreadCtx(void *ptr
)
2388 WARN("%p current for thread being destroyed\n", ptr
);
2389 ALCcontext_DecRef(ptr
);
2394 * Checks that the given context is valid, and increments its reference count.
2396 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2401 dev
= ATOMIC_LOAD(&DeviceList
);
2404 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2409 ALCcontext_IncRef(ctx
);
2425 * Returns the currently active context for this thread, and adds a reference
2426 * without locking it.
2428 ALCcontext
*GetContextRef(void)
2430 ALCcontext
*context
;
2432 context
= altss_get(LocalContext
);
2434 ALCcontext_IncRef(context
);
2438 context
= ATOMIC_LOAD(&GlobalContext
);
2440 ALCcontext_IncRef(context
);
2448 /************************************************
2449 * Standard ALC functions
2450 ************************************************/
2454 * Return last ALC generated error code for the given device
2456 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2460 if(VerifyDevice(device
))
2462 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2463 ALCdevice_DecRef(device
);
2466 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2472 /* alcSuspendContext
2474 * Suspends updates for the given context
2476 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2481 context
= VerifyContext(context
);
2483 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2486 ALCcontext_DeferUpdates(context
);
2487 ALCcontext_DecRef(context
);
2491 /* alcProcessContext
2493 * Resumes processing updates for the given context
2495 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2500 context
= VerifyContext(context
);
2502 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2505 ALCcontext_ProcessUpdates(context
);
2506 ALCcontext_DecRef(context
);
2513 * Returns information about the device, and error strings
2515 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2517 const ALCchar
*value
= NULL
;
2525 case ALC_INVALID_ENUM
:
2526 value
= alcErrInvalidEnum
;
2529 case ALC_INVALID_VALUE
:
2530 value
= alcErrInvalidValue
;
2533 case ALC_INVALID_DEVICE
:
2534 value
= alcErrInvalidDevice
;
2537 case ALC_INVALID_CONTEXT
:
2538 value
= alcErrInvalidContext
;
2541 case ALC_OUT_OF_MEMORY
:
2542 value
= alcErrOutOfMemory
;
2545 case ALC_DEVICE_SPECIFIER
:
2546 value
= alcDefaultName
;
2549 case ALC_ALL_DEVICES_SPECIFIER
:
2550 if(VerifyDevice(Device
))
2552 value
= al_string_get_cstr(Device
->DeviceName
);
2553 ALCdevice_DecRef(Device
);
2557 ProbeAllDevicesList();
2558 value
= al_string_get_cstr(alcAllDevicesList
);
2562 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2563 if(VerifyDevice(Device
))
2565 value
= al_string_get_cstr(Device
->DeviceName
);
2566 ALCdevice_DecRef(Device
);
2570 ProbeCaptureDeviceList();
2571 value
= al_string_get_cstr(alcCaptureDeviceList
);
2575 /* Default devices are always first in the list */
2576 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2577 value
= alcDefaultName
;
2580 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2581 if(al_string_empty(alcAllDevicesList
))
2582 ProbeAllDevicesList();
2584 Device
= VerifyDevice(Device
);
2586 free(alcDefaultAllDevicesSpecifier
);
2587 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2588 if(!alcDefaultAllDevicesSpecifier
)
2589 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2591 value
= alcDefaultAllDevicesSpecifier
;
2592 if(Device
) ALCdevice_DecRef(Device
);
2595 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2596 if(al_string_empty(alcCaptureDeviceList
))
2597 ProbeCaptureDeviceList();
2599 Device
= VerifyDevice(Device
);
2601 free(alcCaptureDefaultDeviceSpecifier
);
2602 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2603 if(!alcCaptureDefaultDeviceSpecifier
)
2604 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2606 value
= alcCaptureDefaultDeviceSpecifier
;
2607 if(Device
) ALCdevice_DecRef(Device
);
2610 case ALC_EXTENSIONS
:
2611 if(!VerifyDevice(Device
))
2612 value
= alcNoDeviceExtList
;
2615 value
= alcExtensionList
;
2616 ALCdevice_DecRef(Device
);
2621 Device
= VerifyDevice(Device
);
2622 alcSetError(Device
, ALC_INVALID_ENUM
);
2623 if(Device
) ALCdevice_DecRef(Device
);
2631 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2635 if(size
<= 0 || values
== NULL
)
2637 alcSetError(device
, ALC_INVALID_VALUE
);
2645 case ALC_MAJOR_VERSION
:
2646 values
[0] = alcMajorVersion
;
2648 case ALC_MINOR_VERSION
:
2649 values
[0] = alcMinorVersion
;
2652 case ALC_ATTRIBUTES_SIZE
:
2653 case ALC_ALL_ATTRIBUTES
:
2657 case ALC_MONO_SOURCES
:
2658 case ALC_STEREO_SOURCES
:
2659 case ALC_CAPTURE_SAMPLES
:
2660 case ALC_FORMAT_CHANNELS_SOFT
:
2661 case ALC_FORMAT_TYPE_SOFT
:
2662 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2666 alcSetError(NULL
, ALC_INVALID_ENUM
);
2672 if(device
->Type
== Capture
)
2676 case ALC_CAPTURE_SAMPLES
:
2677 V0(device
->Backend
,lock
)();
2678 values
[0] = V0(device
->Backend
,availableSamples
)();
2679 V0(device
->Backend
,unlock
)();
2683 values
[0] = device
->Connected
;
2687 alcSetError(device
, ALC_INVALID_ENUM
);
2696 case ALC_MAJOR_VERSION
:
2697 values
[0] = alcMajorVersion
;
2700 case ALC_MINOR_VERSION
:
2701 values
[0] = alcMinorVersion
;
2704 case ALC_EFX_MAJOR_VERSION
:
2705 values
[0] = alcEFXMajorVersion
;
2708 case ALC_EFX_MINOR_VERSION
:
2709 values
[0] = alcEFXMinorVersion
;
2712 case ALC_ATTRIBUTES_SIZE
:
2716 case ALC_ALL_ATTRIBUTES
:
2719 alcSetError(device
, ALC_INVALID_VALUE
);
2724 values
[i
++] = ALC_FREQUENCY
;
2725 values
[i
++] = device
->Frequency
;
2727 if(device
->Type
!= Loopback
)
2729 values
[i
++] = ALC_REFRESH
;
2730 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2732 values
[i
++] = ALC_SYNC
;
2733 values
[i
++] = ALC_FALSE
;
2737 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2738 values
[i
++] = device
->FmtChans
;
2740 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2741 values
[i
++] = device
->FmtType
;
2744 values
[i
++] = ALC_MONO_SOURCES
;
2745 values
[i
++] = device
->NumMonoSources
;
2747 values
[i
++] = ALC_STEREO_SOURCES
;
2748 values
[i
++] = device
->NumStereoSources
;
2750 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2751 values
[i
++] = device
->NumAuxSends
;
2753 values
[i
++] = ALC_HRTF_SOFT
;
2754 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2760 values
[0] = device
->Frequency
;
2764 if(device
->Type
== Loopback
)
2766 alcSetError(device
, ALC_INVALID_DEVICE
);
2769 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2773 if(device
->Type
== Loopback
)
2775 alcSetError(device
, ALC_INVALID_DEVICE
);
2778 values
[0] = ALC_FALSE
;
2781 case ALC_FORMAT_CHANNELS_SOFT
:
2782 if(device
->Type
!= Loopback
)
2784 alcSetError(device
, ALC_INVALID_DEVICE
);
2787 values
[0] = device
->FmtChans
;
2790 case ALC_FORMAT_TYPE_SOFT
:
2791 if(device
->Type
!= Loopback
)
2793 alcSetError(device
, ALC_INVALID_DEVICE
);
2796 values
[0] = device
->FmtType
;
2799 case ALC_MONO_SOURCES
:
2800 values
[0] = device
->NumMonoSources
;
2803 case ALC_STEREO_SOURCES
:
2804 values
[0] = device
->NumStereoSources
;
2807 case ALC_MAX_AUXILIARY_SENDS
:
2808 values
[0] = device
->NumAuxSends
;
2812 values
[0] = device
->Connected
;
2816 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2820 alcSetError(device
, ALC_INVALID_ENUM
);
2828 * Returns information about the device and the version of OpenAL
2830 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2832 device
= VerifyDevice(device
);
2833 if(size
<= 0 || values
== NULL
)
2834 alcSetError(device
, ALC_INVALID_VALUE
);
2836 GetIntegerv(device
, param
, size
, values
);
2837 if(device
) ALCdevice_DecRef(device
);
2840 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2845 device
= VerifyDevice(device
);
2846 if(size
<= 0 || values
== NULL
)
2847 alcSetError(device
, ALC_INVALID_VALUE
);
2848 else if(!device
|| device
->Type
== Capture
)
2850 ivals
= malloc(size
* sizeof(ALCint
));
2851 size
= GetIntegerv(device
, pname
, size
, ivals
);
2852 for(i
= 0;i
< size
;i
++)
2853 values
[i
] = ivals
[i
];
2856 else /* render device */
2860 case ALC_ATTRIBUTES_SIZE
:
2864 case ALC_ALL_ATTRIBUTES
:
2866 alcSetError(device
, ALC_INVALID_VALUE
);
2871 V0(device
->Backend
,lock
)();
2872 values
[i
++] = ALC_FREQUENCY
;
2873 values
[i
++] = device
->Frequency
;
2875 if(device
->Type
!= Loopback
)
2877 values
[i
++] = ALC_REFRESH
;
2878 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2880 values
[i
++] = ALC_SYNC
;
2881 values
[i
++] = ALC_FALSE
;
2885 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2886 values
[i
++] = device
->FmtChans
;
2888 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2889 values
[i
++] = device
->FmtType
;
2892 values
[i
++] = ALC_MONO_SOURCES
;
2893 values
[i
++] = device
->NumMonoSources
;
2895 values
[i
++] = ALC_STEREO_SOURCES
;
2896 values
[i
++] = device
->NumStereoSources
;
2898 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2899 values
[i
++] = device
->NumAuxSends
;
2901 values
[i
++] = ALC_HRTF_SOFT
;
2902 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2904 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2905 values
[i
++] = device
->ClockBase
+
2906 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2909 V0(device
->Backend
,unlock
)();
2913 case ALC_DEVICE_CLOCK_SOFT
:
2914 V0(device
->Backend
,lock
)();
2915 *values
= device
->ClockBase
+
2916 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2917 V0(device
->Backend
,unlock
)();
2921 ivals
= malloc(size
* sizeof(ALCint
));
2922 size
= GetIntegerv(device
, pname
, size
, ivals
);
2923 for(i
= 0;i
< size
;i
++)
2924 values
[i
] = ivals
[i
];
2930 ALCdevice_DecRef(device
);
2934 /* alcIsExtensionPresent
2936 * Determines if there is support for a particular extension
2938 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2940 ALCboolean bResult
= ALC_FALSE
;
2942 device
= VerifyDevice(device
);
2945 alcSetError(device
, ALC_INVALID_VALUE
);
2948 size_t len
= strlen(extName
);
2949 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2952 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2953 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2958 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2962 } while(isspace(*ptr
));
2967 ALCdevice_DecRef(device
);
2972 /* alcGetProcAddress
2974 * Retrieves the function address for a particular extension function
2976 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2978 ALCvoid
*ptr
= NULL
;
2982 device
= VerifyDevice(device
);
2983 alcSetError(device
, ALC_INVALID_VALUE
);
2984 if(device
) ALCdevice_DecRef(device
);
2989 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2991 ptr
= alcFunctions
[i
].address
;
3000 * Get the value for a particular ALC enumeration name
3002 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3008 device
= VerifyDevice(device
);
3009 alcSetError(device
, ALC_INVALID_VALUE
);
3010 if(device
) ALCdevice_DecRef(device
);
3015 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3017 val
= enumeration
[i
].value
;
3026 * Create and attach a context to the given device.
3028 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3030 ALCcontext
*ALContext
;
3034 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
3037 alcSetError(device
, ALC_INVALID_DEVICE
);
3038 if(device
) ALCdevice_DecRef(device
);
3042 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3044 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3047 alcSetError(device
, err
);
3048 if(err
== ALC_INVALID_DEVICE
)
3050 V0(device
->Backend
,lock
)();
3051 aluHandleDisconnect(device
);
3052 V0(device
->Backend
,unlock
)();
3054 ALCdevice_DecRef(device
);
3058 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3061 InitRef(&ALContext
->ref
, 1);
3062 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3064 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3066 ALContext
->VoiceCount
= 0;
3067 ALContext
->MaxVoices
= 256;
3068 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3070 if(!ALContext
|| !ALContext
->Voices
)
3072 if(!ATOMIC_LOAD(&device
->ContextList
))
3074 V0(device
->Backend
,stop
)();
3075 device
->Flags
&= ~DEVICE_RUNNING
;
3081 al_free(ALContext
->Voices
);
3082 ALContext
->Voices
= NULL
;
3084 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3090 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3091 ALCdevice_DecRef(device
);
3095 ALContext
->Device
= device
;
3096 ALCdevice_IncRef(device
);
3097 InitContext(ALContext
);
3100 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3102 ALContext
->next
= head
;
3103 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3107 ALCdevice_DecRef(device
);
3109 TRACE("Created context %p\n", ALContext
);
3113 /* alcDestroyContext
3115 * Remove a context from its device
3117 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3122 /* alcGetContextsDevice sets an error for invalid contexts */
3123 Device
= alcGetContextsDevice(context
);
3126 ReleaseContext(context
, Device
);
3127 if(!ATOMIC_LOAD(&Device
->ContextList
))
3129 V0(Device
->Backend
,stop
)();
3130 Device
->Flags
&= ~DEVICE_RUNNING
;
3137 /* alcGetCurrentContext
3139 * Returns the currently active context on the calling thread
3141 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3143 ALCcontext
*Context
= altss_get(LocalContext
);
3144 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3148 /* alcGetThreadContext
3150 * Returns the currently active thread-local context
3152 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3154 return altss_get(LocalContext
);
3158 /* alcMakeContextCurrent
3160 * Makes the given context the active process-wide context, and removes the
3161 * thread-local context for the calling thread.
3163 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3165 /* context must be valid or NULL */
3166 if(context
&& !(context
=VerifyContext(context
)))
3168 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3171 /* context's reference count is already incremented */
3172 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3173 if(context
) ALCcontext_DecRef(context
);
3175 if((context
=altss_get(LocalContext
)) != NULL
)
3177 altss_set(LocalContext
, NULL
);
3178 ALCcontext_DecRef(context
);
3184 /* alcSetThreadContext
3186 * Makes the given context the active context for the current thread
3188 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3192 /* context must be valid or NULL */
3193 if(context
&& !(context
=VerifyContext(context
)))
3195 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3198 /* context's reference count is already incremented */
3199 old
= altss_get(LocalContext
);
3200 altss_set(LocalContext
, context
);
3201 if(old
) ALCcontext_DecRef(old
);
3207 /* alcGetContextsDevice
3209 * Returns the device that a particular context is attached to
3211 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3215 if(!(Context
=VerifyContext(Context
)))
3217 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3220 Device
= Context
->Device
;
3221 ALCcontext_DecRef(Context
);
3229 * Opens the named device.
3231 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3239 if(!PlaybackBackend
.name
)
3241 alcSetError(NULL
, ALC_INVALID_VALUE
);
3245 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3248 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3251 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3256 InitRef(&device
->ref
, 1);
3257 device
->Connected
= ALC_TRUE
;
3258 device
->Type
= Playback
;
3259 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3262 device
->Bs2b
= NULL
;
3263 AL_STRING_INIT(device
->DeviceName
);
3264 device
->DryBuffer
= NULL
;
3266 ATOMIC_INIT(&device
->ContextList
, NULL
);
3268 device
->ClockBase
= 0;
3269 device
->SamplesDone
= 0;
3271 device
->MaxNoOfSources
= 256;
3272 device
->AuxiliaryEffectSlotMax
= 4;
3273 device
->NumAuxSends
= MAX_SENDS
;
3275 InitUIntMap(&device
->BufferMap
, ~0);
3276 InitUIntMap(&device
->EffectMap
, ~0);
3277 InitUIntMap(&device
->FilterMap
, ~0);
3278 InitUIntMap(&device
->SfontMap
, ~0);
3279 InitUIntMap(&device
->PresetMap
, ~0);
3280 InitUIntMap(&device
->FontsoundMap
, ~0);
3283 device
->FmtChans
= DevFmtChannelsDefault
;
3284 device
->FmtType
= DevFmtTypeDefault
;
3285 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3286 device
->IsHeadphones
= AL_FALSE
;
3287 device
->NumUpdates
= 4;
3288 device
->UpdateSize
= 1024;
3290 if(!PlaybackBackend
.getFactory
)
3291 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3292 ALCbackend_Playback
);
3295 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3296 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3298 if(!device
->Backend
)
3301 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3306 if(ConfigValueStr(NULL
, "channels", &fmt
))
3308 static const struct {
3309 const char name
[16];
3310 enum DevFmtChannels chans
;
3312 { "mono", DevFmtMono
},
3313 { "stereo", DevFmtStereo
},
3314 { "quad", DevFmtQuad
},
3315 { "surround51", DevFmtX51
},
3316 { "surround61", DevFmtX61
},
3317 { "surround71", DevFmtX71
},
3318 { "surround51rear", DevFmtX51Rear
},
3322 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3324 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3326 device
->FmtChans
= chanlist
[i
].chans
;
3327 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3331 if(i
== COUNTOF(chanlist
))
3332 ERR("Unsupported channels: %s\n", fmt
);
3334 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3336 static const struct {
3337 const char name
[16];
3338 enum DevFmtType type
;
3340 { "int8", DevFmtByte
},
3341 { "uint8", DevFmtUByte
},
3342 { "int16", DevFmtShort
},
3343 { "uint16", DevFmtUShort
},
3344 { "int32", DevFmtInt
},
3345 { "uint32", DevFmtUInt
},
3346 { "float32", DevFmtFloat
},
3350 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3352 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3354 device
->FmtType
= typelist
[i
].type
;
3355 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3359 if(i
== COUNTOF(typelist
))
3360 ERR("Unsupported sample-type: %s\n", fmt
);
3363 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3365 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3366 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3367 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3368 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3371 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3372 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3374 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3375 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3376 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3377 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3379 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3380 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3382 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3383 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3385 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3386 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3388 device
->NumStereoSources
= 1;
3389 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3391 device
->Synth
= SynthCreate(device
);
3394 DELETE_OBJ(device
->Backend
);
3396 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3400 // Find a playback device to open
3401 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3403 DELETE_OBJ(device
->Synth
);
3404 DELETE_OBJ(device
->Backend
);
3406 alcSetError(NULL
, err
);
3410 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3412 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3413 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3415 device
->DefaultSlot
= NULL
;
3416 ERR("Failed to initialize the default effect slot\n");
3418 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3420 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3421 device
->DefaultSlot
= NULL
;
3423 ERR("Failed to initialize the default effect\n");
3428 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3430 device
->next
= head
;
3431 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3434 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3440 * Closes the given device.
3442 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3444 ALCdevice
*list
, *origdev
, *nextdev
;
3448 list
= ATOMIC_LOAD(&DeviceList
);
3452 } while((list
=list
->next
) != NULL
);
3453 if(!list
|| list
->Type
== Capture
)
3455 alcSetError(list
, ALC_INVALID_DEVICE
);
3461 nextdev
= device
->next
;
3462 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3467 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3471 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3474 ALCcontext
*next
= ctx
->next
;
3475 WARN("Releasing context %p\n", ctx
);
3476 ReleaseContext(ctx
, device
);
3479 if((device
->Flags
&DEVICE_RUNNING
))
3480 V0(device
->Backend
,stop
)();
3481 device
->Flags
&= ~DEVICE_RUNNING
;
3483 ALCdevice_DecRef(device
);
3489 /************************************************
3490 * ALC capture functions
3491 ************************************************/
3492 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3494 ALCdevice
*device
= NULL
;
3499 if(!CaptureBackend
.name
)
3501 alcSetError(NULL
, ALC_INVALID_VALUE
);
3507 alcSetError(NULL
, ALC_INVALID_VALUE
);
3511 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3514 device
= al_calloc(16, sizeof(ALCdevice
));
3517 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3522 InitRef(&device
->ref
, 1);
3523 device
->Connected
= ALC_TRUE
;
3524 device
->Type
= Capture
;
3526 AL_STRING_INIT(device
->DeviceName
);
3527 device
->DryBuffer
= NULL
;
3529 InitUIntMap(&device
->BufferMap
, ~0);
3530 InitUIntMap(&device
->EffectMap
, ~0);
3531 InitUIntMap(&device
->FilterMap
, ~0);
3532 InitUIntMap(&device
->SfontMap
, ~0);
3533 InitUIntMap(&device
->PresetMap
, ~0);
3534 InitUIntMap(&device
->FontsoundMap
, ~0);
3536 if(!CaptureBackend
.getFactory
)
3537 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3538 ALCbackend_Capture
);
3541 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3542 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3544 if(!device
->Backend
)
3547 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3551 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3552 device
->Frequency
= frequency
;
3554 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3555 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3558 alcSetError(NULL
, ALC_INVALID_ENUM
);
3561 device
->IsHeadphones
= AL_FALSE
;
3563 device
->UpdateSize
= samples
;
3564 device
->NumUpdates
= 1;
3566 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3569 alcSetError(NULL
, err
);
3574 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3576 device
->next
= head
;
3577 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3580 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3584 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3586 ALCdevice
*list
, *next
, *nextdev
;
3589 list
= ATOMIC_LOAD(&DeviceList
);
3593 } while((list
=list
->next
) != NULL
);
3594 if(!list
|| list
->Type
!= Capture
)
3596 alcSetError(list
, ALC_INVALID_DEVICE
);
3602 nextdev
= device
->next
;
3603 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3608 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3612 ALCdevice_DecRef(device
);
3617 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3619 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3620 alcSetError(device
, ALC_INVALID_DEVICE
);
3623 V0(device
->Backend
,lock
)();
3624 if(device
->Connected
)
3626 if(!(device
->Flags
&DEVICE_RUNNING
))
3627 V0(device
->Backend
,start
)();
3628 device
->Flags
|= DEVICE_RUNNING
;
3630 V0(device
->Backend
,unlock
)();
3633 if(device
) ALCdevice_DecRef(device
);
3636 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3638 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3639 alcSetError(device
, ALC_INVALID_DEVICE
);
3642 V0(device
->Backend
,lock
)();
3643 if((device
->Flags
&DEVICE_RUNNING
))
3644 V0(device
->Backend
,stop
)();
3645 device
->Flags
&= ~DEVICE_RUNNING
;
3646 V0(device
->Backend
,unlock
)();
3649 if(device
) ALCdevice_DecRef(device
);
3652 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3654 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3655 alcSetError(device
, ALC_INVALID_DEVICE
);
3658 ALCenum err
= ALC_INVALID_VALUE
;
3660 V0(device
->Backend
,lock
)();
3661 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3662 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3663 V0(device
->Backend
,unlock
)();
3665 if(err
!= ALC_NO_ERROR
)
3666 alcSetError(device
, err
);
3668 if(device
) ALCdevice_DecRef(device
);
3672 /************************************************
3673 * ALC loopback functions
3674 ************************************************/
3676 /* alcLoopbackOpenDeviceSOFT
3678 * Open a loopback device, for manual rendering.
3680 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3682 ALCbackendFactory
*factory
;
3687 /* Make sure the device name, if specified, is us. */
3688 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3690 alcSetError(NULL
, ALC_INVALID_VALUE
);
3694 device
= al_calloc(16, sizeof(ALCdevice
));
3697 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3702 InitRef(&device
->ref
, 1);
3703 device
->Connected
= ALC_TRUE
;
3704 device
->Type
= Loopback
;
3705 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3708 device
->Bs2b
= NULL
;
3709 AL_STRING_INIT(device
->DeviceName
);
3710 device
->DryBuffer
= NULL
;
3712 ATOMIC_INIT(&device
->ContextList
, NULL
);
3714 device
->ClockBase
= 0;
3715 device
->SamplesDone
= 0;
3717 device
->MaxNoOfSources
= 256;
3718 device
->AuxiliaryEffectSlotMax
= 4;
3719 device
->NumAuxSends
= MAX_SENDS
;
3721 InitUIntMap(&device
->BufferMap
, ~0);
3722 InitUIntMap(&device
->EffectMap
, ~0);
3723 InitUIntMap(&device
->FilterMap
, ~0);
3724 InitUIntMap(&device
->SfontMap
, ~0);
3725 InitUIntMap(&device
->PresetMap
, ~0);
3726 InitUIntMap(&device
->FontsoundMap
, ~0);
3728 factory
= ALCloopbackFactory_getFactory();
3729 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3730 if(!device
->Backend
)
3733 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3738 device
->NumUpdates
= 0;
3739 device
->UpdateSize
= 0;
3741 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3742 device
->FmtChans
= DevFmtChannelsDefault
;
3743 device
->FmtType
= DevFmtTypeDefault
;
3744 device
->IsHeadphones
= AL_FALSE
;
3746 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3747 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3749 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3750 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3752 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3753 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3755 device
->NumStereoSources
= 1;
3756 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3758 device
->Synth
= SynthCreate(device
);
3761 DELETE_OBJ(device
->Backend
);
3763 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3767 // Open the "backend"
3768 V(device
->Backend
,open
)("Loopback");
3771 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3773 device
->next
= head
;
3774 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3777 TRACE("Created device %p\n", device
);
3781 /* alcIsRenderFormatSupportedSOFT
3783 * Determines if the loopback device supports the given format for rendering.
3785 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3787 ALCboolean ret
= ALC_FALSE
;
3789 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3790 alcSetError(device
, ALC_INVALID_DEVICE
);
3792 alcSetError(device
, ALC_INVALID_VALUE
);
3795 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3796 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3797 freq
>= MIN_OUTPUT_RATE
)
3800 if(device
) ALCdevice_DecRef(device
);
3805 /* alcRenderSamplesSOFT
3807 * Renders some samples into a buffer, using the format last set by the
3808 * attributes given to alcCreateContext.
3810 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3812 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3813 alcSetError(device
, ALC_INVALID_DEVICE
);
3814 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3815 alcSetError(device
, ALC_INVALID_VALUE
);
3817 aluMixData(device
, buffer
, samples
);
3818 if(device
) ALCdevice_DecRef(device
);
3822 /************************************************
3823 * ALC DSP pause/resume functions
3824 ************************************************/
3826 /* alcDevicePauseSOFT
3828 * Pause the DSP to stop audio processing.
3830 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3832 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3833 alcSetError(device
, ALC_INVALID_DEVICE
);
3837 if((device
->Flags
&DEVICE_RUNNING
))
3838 V0(device
->Backend
,stop
)();
3839 device
->Flags
&= ~DEVICE_RUNNING
;
3840 device
->Flags
|= DEVICE_PAUSED
;
3843 if(device
) ALCdevice_DecRef(device
);
3846 /* alcDeviceResumeSOFT
3848 * Resume the DSP to restart audio processing.
3850 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3852 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3853 alcSetError(device
, ALC_INVALID_DEVICE
);
3857 if((device
->Flags
&DEVICE_PAUSED
))
3859 device
->Flags
&= ~DEVICE_PAUSED
;
3860 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3862 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3863 device
->Flags
|= DEVICE_RUNNING
;
3866 alcSetError(device
, ALC_INVALID_DEVICE
);
3867 V0(device
->Backend
,lock
)();
3868 aluHandleDisconnect(device
);
3869 V0(device
->Backend
,unlock
)();
3875 if(device
) ALCdevice_DecRef(device
);