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
);
1010 str
= getenv("ALSOFT_TRAP_ERROR");
1011 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1013 TrapALError
= AL_TRUE
;
1014 TrapALCError
= AL_TRUE
;
1018 str
= getenv("ALSOFT_TRAP_AL_ERROR");
1019 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1020 TrapALError
= AL_TRUE
;
1021 TrapALError
= GetConfigValueBool(NULL
, "trap-al-error", TrapALError
);
1023 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1024 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1025 TrapALCError
= ALC_TRUE
;
1026 TrapALCError
= GetConfigValueBool(NULL
, "trap-alc-error", TrapALCError
);
1029 if(ConfigValueFloat("reverb", "boost", &valf
))
1030 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1032 EmulateEAXReverb
= GetConfigValueBool("reverb", "emulate-eax", AL_FALSE
);
1034 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1035 ConfigValueStr(NULL
, "drivers", &devs
))
1039 const char *next
= devs
;
1040 int endlist
, delitem
;
1045 while(isspace(devs
[0]))
1047 next
= strchr(devs
, ',');
1049 delitem
= (devs
[0] == '-');
1050 if(devs
[0] == '-') devs
++;
1052 if(!devs
[0] || devs
[0] == ',')
1059 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1060 while(len
> 0 && isspace(devs
[len
-1]))
1062 for(n
= i
;BackendList
[n
].name
;n
++)
1064 if(len
== strlen(BackendList
[n
].name
) &&
1065 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1070 BackendList
[n
] = BackendList
[n
+1];
1072 } while(BackendList
[n
].name
);
1076 struct BackendInfo Bkp
= BackendList
[n
];
1079 BackendList
[n
] = BackendList
[n
-1];
1082 BackendList
[n
] = Bkp
;
1093 BackendList
[i
].name
= NULL
;
1094 BackendList
[i
].getFactory
= NULL
;
1095 BackendList
[i
].Init
= NULL
;
1096 BackendList
[i
].Deinit
= NULL
;
1097 BackendList
[i
].Probe
= NULL
;
1101 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1103 if(BackendList
[i
].getFactory
)
1105 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1106 if(!V0(factory
,init
)())
1108 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1112 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1113 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1115 PlaybackBackend
= BackendList
[i
];
1116 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1118 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1120 CaptureBackend
= BackendList
[i
];
1121 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1127 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1129 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1133 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1134 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1136 PlaybackBackend
= BackendList
[i
];
1137 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1139 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1141 CaptureBackend
= BackendList
[i
];
1142 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1146 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1150 if(ConfigValueStr(NULL
, "excludefx", &str
))
1153 const char *next
= str
;
1157 next
= strchr(str
, ',');
1159 if(!str
[0] || next
== str
)
1162 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1163 for(n
= 0;EffectList
[n
].name
;n
++)
1165 if(len
== strlen(EffectList
[n
].name
) &&
1166 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1167 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1172 InitEffectFactoryMap();
1174 InitEffect(&DefaultEffect
);
1175 str
= getenv("ALSOFT_DEFAULT_REVERB");
1176 if((str
&& str
[0]) || ConfigValueStr(NULL
, "default-reverb", &str
))
1177 LoadReverbPreset(str
, &DefaultEffect
);
1179 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1182 /************************************************
1183 * Library deinitialization
1184 ************************************************/
1185 static void alc_cleanup(void)
1189 AL_STRING_DEINIT(alcAllDevicesList
);
1190 AL_STRING_DEINIT(alcCaptureDeviceList
);
1192 free(alcDefaultAllDevicesSpecifier
);
1193 alcDefaultAllDevicesSpecifier
= NULL
;
1194 free(alcCaptureDefaultDeviceSpecifier
);
1195 alcCaptureDefaultDeviceSpecifier
= NULL
;
1197 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1202 } while((dev
=dev
->next
) != NULL
);
1203 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1206 DeinitEffectFactoryMap();
1209 static void alc_deinit_safe(void)
1217 almtx_destroy(&ListLock
);
1218 altss_delete(LocalContext
);
1220 if(LogFile
!= stderr
)
1225 static void alc_deinit(void)
1231 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1232 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1234 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1236 if(!BackendList
[i
].getFactory
)
1237 BackendList
[i
].Deinit();
1240 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1241 V0(factory
,deinit
)();
1245 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1246 V0(factory
,deinit
)();
1253 /************************************************
1254 * Device enumeration
1255 ************************************************/
1256 static void ProbeDevices(al_string
*list
, enum DevProbe type
)
1261 al_string_clear(list
);
1263 if(type
== ALL_DEVICE_PROBE
&& (PlaybackBackend
.Probe
|| PlaybackBackend
.getFactory
))
1265 if(!PlaybackBackend
.getFactory
)
1266 PlaybackBackend
.Probe(type
);
1269 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
1270 V(factory
,probe
)(type
);
1273 else if(type
== CAPTURE_DEVICE_PROBE
&& (CaptureBackend
.Probe
|| CaptureBackend
.getFactory
))
1275 if(!CaptureBackend
.getFactory
)
1276 CaptureBackend
.Probe(type
);
1279 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
1280 V(factory
,probe
)(type
);
1285 static void ProbeAllDevicesList(void)
1286 { ProbeDevices(&alcAllDevicesList
, ALL_DEVICE_PROBE
); }
1287 static void ProbeCaptureDeviceList(void)
1288 { ProbeDevices(&alcCaptureDeviceList
, CAPTURE_DEVICE_PROBE
); }
1290 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1292 size_t len
= strlen(name
);
1294 al_string_append_range(devnames
, name
, name
+len
+1);
1296 void AppendAllDevicesList(const ALCchar
*name
)
1297 { AppendDevice(name
, &alcAllDevicesList
); }
1298 void AppendCaptureDeviceList(const ALCchar
*name
)
1299 { AppendDevice(name
, &alcCaptureDeviceList
); }
1302 /************************************************
1303 * Device format information
1304 ************************************************/
1305 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1309 case DevFmtByte
: return "Signed Byte";
1310 case DevFmtUByte
: return "Unsigned Byte";
1311 case DevFmtShort
: return "Signed Short";
1312 case DevFmtUShort
: return "Unsigned Short";
1313 case DevFmtInt
: return "Signed Int";
1314 case DevFmtUInt
: return "Unsigned Int";
1315 case DevFmtFloat
: return "Float";
1317 return "(unknown type)";
1319 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1323 case DevFmtMono
: return "Mono";
1324 case DevFmtStereo
: return "Stereo";
1325 case DevFmtQuad
: return "Quadraphonic";
1326 case DevFmtX51
: return "5.1 Surround";
1327 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1328 case DevFmtX61
: return "6.1 Surround";
1329 case DevFmtX71
: return "7.1 Surround";
1331 return "(unknown channels)";
1334 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1335 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1339 case DevFmtByte
: return sizeof(ALbyte
);
1340 case DevFmtUByte
: return sizeof(ALubyte
);
1341 case DevFmtShort
: return sizeof(ALshort
);
1342 case DevFmtUShort
: return sizeof(ALushort
);
1343 case DevFmtInt
: return sizeof(ALint
);
1344 case DevFmtUInt
: return sizeof(ALuint
);
1345 case DevFmtFloat
: return sizeof(ALfloat
);
1349 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1353 case DevFmtMono
: return 1;
1354 case DevFmtStereo
: return 2;
1355 case DevFmtQuad
: return 4;
1356 case DevFmtX51
: return 6;
1357 case DevFmtX51Rear
: return 6;
1358 case DevFmtX61
: return 7;
1359 case DevFmtX71
: return 8;
1364 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1365 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1367 static const struct {
1369 enum DevFmtChannels channels
;
1370 enum DevFmtType type
;
1372 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1373 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1374 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1376 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1377 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1378 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1380 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1381 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1382 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1384 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1385 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1386 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1388 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1389 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1390 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1392 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1393 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1394 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1398 for(i
= 0;i
< COUNTOF(list
);i
++)
1400 if(list
[i
].format
== format
)
1402 *chans
= list
[i
].channels
;
1403 *type
= list
[i
].type
;
1411 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1416 case ALC_UNSIGNED_BYTE_SOFT
:
1417 case ALC_SHORT_SOFT
:
1418 case ALC_UNSIGNED_SHORT_SOFT
:
1420 case ALC_UNSIGNED_INT_SOFT
:
1421 case ALC_FLOAT_SOFT
:
1427 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1432 case ALC_STEREO_SOFT
:
1434 case ALC_5POINT1_SOFT
:
1435 case ALC_6POINT1_SOFT
:
1436 case ALC_7POINT1_SOFT
:
1443 /************************************************
1444 * Miscellaneous ALC helpers
1445 ************************************************/
1446 extern inline void LockContext(ALCcontext
*context
);
1447 extern inline void UnlockContext(ALCcontext
*context
);
1449 ALint64
ALCdevice_GetLatency(ALCdevice
*device
)
1451 return V0(device
->Backend
,getLatency
)();
1454 void ALCdevice_Lock(ALCdevice
*device
)
1456 V0(device
->Backend
,lock
)();
1459 void ALCdevice_Unlock(ALCdevice
*device
)
1461 V0(device
->Backend
,unlock
)();
1465 /* SetDefaultWFXChannelOrder
1467 * Sets the default channel order used by WaveFormatEx.
1469 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1473 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1474 device
->ChannelName
[i
] = InvalidChannel
;
1476 switch(device
->FmtChans
)
1479 device
->ChannelName
[0] = FrontCenter
;
1482 device
->ChannelName
[0] = FrontLeft
;
1483 device
->ChannelName
[1] = FrontRight
;
1486 device
->ChannelName
[0] = FrontLeft
;
1487 device
->ChannelName
[1] = FrontRight
;
1488 device
->ChannelName
[2] = BackLeft
;
1489 device
->ChannelName
[3] = BackRight
;
1492 device
->ChannelName
[0] = FrontLeft
;
1493 device
->ChannelName
[1] = FrontRight
;
1494 device
->ChannelName
[2] = FrontCenter
;
1495 device
->ChannelName
[3] = LFE
;
1496 device
->ChannelName
[4] = SideLeft
;
1497 device
->ChannelName
[5] = SideRight
;
1500 device
->ChannelName
[0] = FrontLeft
;
1501 device
->ChannelName
[1] = FrontRight
;
1502 device
->ChannelName
[2] = FrontCenter
;
1503 device
->ChannelName
[3] = LFE
;
1504 device
->ChannelName
[4] = BackLeft
;
1505 device
->ChannelName
[5] = BackRight
;
1508 device
->ChannelName
[0] = FrontLeft
;
1509 device
->ChannelName
[1] = FrontRight
;
1510 device
->ChannelName
[2] = FrontCenter
;
1511 device
->ChannelName
[3] = LFE
;
1512 device
->ChannelName
[4] = BackCenter
;
1513 device
->ChannelName
[5] = SideLeft
;
1514 device
->ChannelName
[6] = SideRight
;
1517 device
->ChannelName
[0] = FrontLeft
;
1518 device
->ChannelName
[1] = FrontRight
;
1519 device
->ChannelName
[2] = FrontCenter
;
1520 device
->ChannelName
[3] = LFE
;
1521 device
->ChannelName
[4] = BackLeft
;
1522 device
->ChannelName
[5] = BackRight
;
1523 device
->ChannelName
[6] = SideLeft
;
1524 device
->ChannelName
[7] = SideRight
;
1529 /* SetDefaultChannelOrder
1531 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1533 void SetDefaultChannelOrder(ALCdevice
*device
)
1537 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1538 device
->ChannelName
[i
] = InvalidChannel
;
1540 switch(device
->FmtChans
)
1543 device
->ChannelName
[0] = FrontLeft
;
1544 device
->ChannelName
[1] = FrontRight
;
1545 device
->ChannelName
[2] = BackLeft
;
1546 device
->ChannelName
[3] = BackRight
;
1547 device
->ChannelName
[4] = FrontCenter
;
1548 device
->ChannelName
[5] = LFE
;
1551 device
->ChannelName
[0] = FrontLeft
;
1552 device
->ChannelName
[1] = FrontRight
;
1553 device
->ChannelName
[2] = BackLeft
;
1554 device
->ChannelName
[3] = BackRight
;
1555 device
->ChannelName
[4] = FrontCenter
;
1556 device
->ChannelName
[5] = LFE
;
1557 device
->ChannelName
[6] = SideLeft
;
1558 device
->ChannelName
[7] = SideRight
;
1561 /* Same as WFX order */
1567 SetDefaultWFXChannelOrder(device
);
1572 extern inline ALint
GetChannelIdxByName(const ALCdevice
*device
, enum Channel chan
);
1575 /* ALCcontext_DeferUpdates
1577 * Defers/suspends updates for the given context's listener and sources. This
1578 * does *NOT* stop mixing, but rather prevents certain property changes from
1581 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1583 ALCdevice
*device
= context
->Device
;
1586 SetMixerFPUMode(&oldMode
);
1588 V0(device
->Backend
,lock
)();
1589 if(!ExchangeInt(&context
->DeferUpdates
, AL_TRUE
))
1591 ALboolean UpdateSources
;
1592 ALvoice
*voice
, *voice_end
;
1593 ALeffectslot
**slot
, **slot_end
;
1594 /* Make sure all pending updates are performed */
1595 UpdateSources
= ATOMIC_EXCHANGE(ALenum
, &context
->UpdateSources
, AL_FALSE
);
1597 voice
= context
->Voices
;
1598 voice_end
= voice
+ context
->VoiceCount
;
1599 while(voice
!= voice_end
)
1601 ALsource
*source
= voice
->Source
;
1602 if(!source
) goto next
;
1604 if(source
->state
!= AL_PLAYING
&& source
->state
!= AL_PAUSED
)
1606 voice
->Source
= NULL
;
1610 if(ATOMIC_EXCHANGE(ALenum
, &source
->NeedsUpdate
, AL_FALSE
) || UpdateSources
)
1611 voice
->Update(voice
, source
, context
);
1616 slot
= VECTOR_ITER_BEGIN(context
->ActiveAuxSlots
);
1617 slot_end
= VECTOR_ITER_END(context
->ActiveAuxSlots
);
1618 while(slot
!= slot_end
)
1620 if(ATOMIC_EXCHANGE(ALenum
, &(*slot
)->NeedsUpdate
, AL_FALSE
))
1621 V((*slot
)->EffectState
,update
)(context
->Device
, *slot
);
1625 V0(device
->Backend
,unlock
)();
1627 RestoreFPUMode(&oldMode
);
1630 /* ALCcontext_ProcessUpdates
1632 * Resumes update processing after being deferred.
1634 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1636 ALCdevice
*device
= context
->Device
;
1638 V0(device
->Backend
,lock
)();
1639 if(ExchangeInt(&context
->DeferUpdates
, AL_FALSE
))
1643 LockUIntMapRead(&context
->SourceMap
);
1644 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1646 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1649 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1650 Source
->Offset
>= 0.0)
1652 ReadLock(&Source
->queue_lock
);
1653 ApplyOffset(Source
);
1654 ReadUnlock(&Source
->queue_lock
);
1657 new_state
= ExchangeInt(&Source
->new_state
, AL_NONE
);
1659 SetSourceState(Source
, context
, new_state
);
1661 UnlockUIntMapRead(&context
->SourceMap
);
1663 V0(device
->Backend
,unlock
)();
1669 * Stores the latest ALC device error
1671 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1676 /* DebugBreak() will cause an exception if there is no debugger */
1677 if(IsDebuggerPresent())
1679 #elif defined(SIGTRAP)
1685 ATOMIC_STORE(&device
->LastError
, errorCode
);
1687 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1693 * Updates the device's base clock time with however many samples have been
1694 * done. This is used so frequency changes on the device don't cause the time
1695 * to jump forward or back.
1697 static inline void UpdateClockBase(ALCdevice
*device
)
1699 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1700 device
->SamplesDone
= 0;
1703 /* UpdateDeviceParams
1705 * Updates device parameters according to the attribute list (caller is
1706 * responsible for holding the list lock).
1708 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1710 ALCcontext
*context
;
1711 enum DevFmtChannels oldChans
;
1712 enum DevFmtType oldType
;
1717 // Check for attributes
1718 if(device
->Type
== Loopback
)
1724 GotAll
= GotFreq
|GotChans
|GotType
1726 ALCuint freq
, numMono
, numStereo
, numSends
, flags
;
1727 enum DevFmtChannels schans
;
1728 enum DevFmtType stype
;
1729 ALCuint attrIdx
= 0;
1734 WARN("Missing attributes for loopback device\n");
1735 return ALC_INVALID_VALUE
;
1738 numMono
= device
->NumMonoSources
;
1739 numStereo
= device
->NumStereoSources
;
1740 numSends
= device
->NumAuxSends
;
1741 schans
= device
->FmtChans
;
1742 stype
= device
->FmtType
;
1743 freq
= device
->Frequency
;
1744 flags
= device
->Flags
;
1746 while(attrList
[attrIdx
])
1748 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1750 ALCint val
= attrList
[attrIdx
+ 1];
1751 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1752 return ALC_INVALID_VALUE
;
1757 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1759 ALCint val
= attrList
[attrIdx
+ 1];
1760 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1761 return ALC_INVALID_VALUE
;
1766 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1768 freq
= attrList
[attrIdx
+ 1];
1769 if(freq
< MIN_OUTPUT_RATE
)
1770 return ALC_INVALID_VALUE
;
1774 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1776 numStereo
= attrList
[attrIdx
+ 1];
1777 if(numStereo
> device
->MaxNoOfSources
)
1778 numStereo
= device
->MaxNoOfSources
;
1780 numMono
= device
->MaxNoOfSources
- numStereo
;
1783 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1784 numSends
= attrList
[attrIdx
+ 1];
1786 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1788 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1789 flags
|= DEVICE_HRTF_REQUEST
;
1791 flags
&= ~DEVICE_HRTF_REQUEST
;
1797 if(gotFmt
!= GotAll
)
1799 WARN("Missing format for loopback device\n");
1800 return ALC_INVALID_VALUE
;
1803 ConfigValueUInt(NULL
, "sends", &numSends
);
1804 numSends
= minu(MAX_SENDS
, numSends
);
1806 if((device
->Flags
&DEVICE_RUNNING
))
1807 V0(device
->Backend
,stop
)();
1808 device
->Flags
= (flags
& ~DEVICE_RUNNING
);
1810 UpdateClockBase(device
);
1812 device
->Frequency
= freq
;
1813 device
->FmtChans
= schans
;
1814 device
->FmtType
= stype
;
1815 device
->NumMonoSources
= numMono
;
1816 device
->NumStereoSources
= numStereo
;
1817 device
->NumAuxSends
= numSends
;
1819 else if(attrList
&& attrList
[0])
1821 ALCuint freq
, numMono
, numStereo
, numSends
;
1822 ALCuint attrIdx
= 0;
1824 /* If a context is already running on the device, stop playback so the
1825 * device attributes can be updated. */
1826 if((device
->Flags
&DEVICE_RUNNING
))
1827 V0(device
->Backend
,stop
)();
1828 device
->Flags
&= ~DEVICE_RUNNING
;
1830 freq
= device
->Frequency
;
1831 numMono
= device
->NumMonoSources
;
1832 numStereo
= device
->NumStereoSources
;
1833 numSends
= device
->NumAuxSends
;
1835 while(attrList
[attrIdx
])
1837 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1839 freq
= attrList
[attrIdx
+ 1];
1840 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1843 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1845 numStereo
= attrList
[attrIdx
+ 1];
1846 if(numStereo
> device
->MaxNoOfSources
)
1847 numStereo
= device
->MaxNoOfSources
;
1849 numMono
= device
->MaxNoOfSources
- numStereo
;
1852 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1853 numSends
= attrList
[attrIdx
+ 1];
1855 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1857 if(attrList
[attrIdx
+ 1] != ALC_FALSE
)
1858 device
->Flags
|= DEVICE_HRTF_REQUEST
;
1860 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1866 ConfigValueUInt(NULL
, "frequency", &freq
);
1867 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1869 ConfigValueUInt(NULL
, "sends", &numSends
);
1870 numSends
= minu(MAX_SENDS
, numSends
);
1872 UpdateClockBase(device
);
1874 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1876 /* SSE and Neon do best with the update size being a multiple of 4 */
1877 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1878 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1880 device
->Frequency
= freq
;
1881 device
->NumMonoSources
= numMono
;
1882 device
->NumStereoSources
= numStereo
;
1883 device
->NumAuxSends
= numSends
;
1886 if((device
->Flags
&DEVICE_RUNNING
))
1887 return ALC_NO_ERROR
;
1889 al_free(device
->DryBuffer
);
1890 device
->DryBuffer
= NULL
;
1892 UpdateClockBase(device
);
1894 if(device
->Type
!= Loopback
&& ((device
->Flags
&DEVICE_HRTF_REQUEST
) || GetConfigValueBool(NULL
, "hrtf", 0)))
1896 if(!FindHrtfFormat(&device
->FmtChans
, &device
->Frequency
))
1897 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1899 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
|
1900 DEVICE_HRTF_REQUEST
;
1902 if(device
->Type
== Loopback
&& (device
->Flags
&DEVICE_HRTF_REQUEST
))
1904 enum DevFmtChannels chans
= device
->FmtChans
;
1905 ALCuint freq
= device
->Frequency
;
1906 if(!FindHrtfFormat(&chans
, &freq
) || chans
!= device
->FmtChans
|| freq
!= device
->Frequency
)
1908 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1909 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1910 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1914 oldFreq
= device
->Frequency
;
1915 oldChans
= device
->FmtChans
;
1916 oldType
= device
->FmtType
;
1918 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1919 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1920 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1921 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1922 device
->UpdateSize
, device
->NumUpdates
1925 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1926 return ALC_INVALID_DEVICE
;
1928 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1930 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1931 DevFmtChannelsString(device
->FmtChans
));
1932 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1934 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1936 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1937 DevFmtTypeString(device
->FmtType
));
1938 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1940 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1942 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1943 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1946 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1947 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1948 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1951 if((device
->UpdateSize
&3) != 0)
1953 if((CPUCapFlags
&CPU_CAP_SSE
))
1954 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1955 if((CPUCapFlags
&CPU_CAP_NEON
))
1956 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1959 device
->Hrtf
= NULL
;
1960 if(device
->FmtChans
!= DevFmtStereo
)
1963 device
->Bs2b
= NULL
;
1967 bool headphones
= device
->IsHeadphones
;
1972 if(device
->Type
!= Loopback
&& ConfigValueStr(NULL
, "stereo-mode", &mode
))
1974 if(strcasecmp(mode
, "headphones") == 0)
1976 else if(strcasecmp(mode
, "speakers") == 0)
1978 else if(strcasecmp(mode
, "auto") != 0)
1979 ERR("Unexpected stereo-mode: %s\n", mode
);
1982 if(device
->Type
== Loopback
|| !ConfigValueBool(NULL
, "hrtf", &usehrtf
))
1983 usehrtf
= ((device
->Flags
&DEVICE_HRTF_REQUEST
) || headphones
);
1986 device
->Hrtf
= GetHrtf(device
->FmtChans
, device
->Frequency
);
1988 TRACE("HRTF enabled\n");
1991 device
->Flags
&= ~DEVICE_HRTF_REQUEST
;
1992 TRACE("HRTF disabled\n");
1994 bs2blevel
= (headphones
? 5 : 0);
1995 if(device
->Type
!= Loopback
)
1996 ConfigValueInt(NULL
, "cf_level", &bs2blevel
);
1997 if(bs2blevel
> 0 && bs2blevel
<= 6)
2001 device
->Bs2b
= calloc(1, sizeof(*device
->Bs2b
));
2002 bs2b_clear(device
->Bs2b
);
2004 bs2b_set_srate(device
->Bs2b
, device
->Frequency
);
2005 bs2b_set_level(device
->Bs2b
, bs2blevel
);
2006 TRACE("BS2B enabled\n");
2011 device
->Bs2b
= NULL
;
2012 TRACE("BS2B disabled\n");
2017 aluInitPanning(device
);
2019 /* With HRTF enabled, virtual channels are allocated for B-Format and
2020 * effects renfering. Two extra channels are allocated for the actual HRTF-
2023 size
= sizeof(device
->DryBuffer
[0]) * (device
->NumChannels
+ (device
->Hrtf
? 2 : 0));
2024 device
->DryBuffer
= al_calloc(16, size
);
2025 if(!device
->DryBuffer
)
2027 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2028 return ALC_INVALID_DEVICE
;
2031 V(device
->Synth
,update
)(device
);
2033 SetMixerFPUMode(&oldMode
);
2034 V0(device
->Backend
,lock
)();
2035 context
= ATOMIC_LOAD(&device
->ContextList
);
2040 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2041 LockUIntMapRead(&context
->EffectSlotMap
);
2042 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2044 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2046 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2048 UnlockUIntMapRead(&context
->EffectSlotMap
);
2049 V0(device
->Backend
,unlock
)();
2050 RestoreFPUMode(&oldMode
);
2051 return ALC_INVALID_DEVICE
;
2053 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2054 V(slot
->EffectState
,update
)(device
, slot
);
2056 UnlockUIntMapRead(&context
->EffectSlotMap
);
2058 LockUIntMapRead(&context
->SourceMap
);
2059 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2061 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2062 ALuint s
= device
->NumAuxSends
;
2063 while(s
< MAX_SENDS
)
2065 if(source
->Send
[s
].Slot
)
2066 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2067 source
->Send
[s
].Slot
= NULL
;
2068 source
->Send
[s
].Gain
= 1.0f
;
2069 source
->Send
[s
].GainHF
= 1.0f
;
2072 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2074 UnlockUIntMapRead(&context
->SourceMap
);
2076 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2078 ALvoice
*voice
= &context
->Voices
[pos
];
2079 ALsource
*source
= voice
->Source
;
2080 ALuint s
= device
->NumAuxSends
;
2082 while(s
< MAX_SENDS
)
2084 voice
->Send
[s
].Moving
= AL_FALSE
;
2085 voice
->Send
[s
].Counter
= 0;
2091 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2092 voice
->Update(voice
, source
, context
);
2096 context
= context
->next
;
2098 if(device
->DefaultSlot
)
2100 ALeffectslot
*slot
= device
->DefaultSlot
;
2102 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2104 V0(device
->Backend
,unlock
)();
2105 RestoreFPUMode(&oldMode
);
2106 return ALC_INVALID_DEVICE
;
2108 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2109 V(slot
->EffectState
,update
)(device
, slot
);
2111 V0(device
->Backend
,unlock
)();
2112 RestoreFPUMode(&oldMode
);
2114 if(!(device
->Flags
&DEVICE_PAUSED
))
2116 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2117 return ALC_INVALID_DEVICE
;
2118 device
->Flags
|= DEVICE_RUNNING
;
2121 return ALC_NO_ERROR
;
2126 * Frees the device structure, and destroys any objects the app failed to
2127 * delete. Called once there's no more references on the device.
2129 static ALCvoid
FreeDevice(ALCdevice
*device
)
2131 TRACE("%p\n", device
);
2133 V0(device
->Backend
,close
)();
2134 DELETE_OBJ(device
->Backend
);
2135 device
->Backend
= NULL
;
2137 DELETE_OBJ(device
->Synth
);
2138 device
->Synth
= NULL
;
2140 if(device
->DefaultSlot
)
2142 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2143 device
->DefaultSlot
= NULL
;
2147 if(device
->DefaultSfont
)
2148 ALsoundfont_deleteSoundfont(device
->DefaultSfont
, device
);
2149 device
->DefaultSfont
= NULL
;
2151 if(device
->BufferMap
.size
> 0)
2153 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2154 ReleaseALBuffers(device
);
2156 ResetUIntMap(&device
->BufferMap
);
2158 if(device
->EffectMap
.size
> 0)
2160 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2161 ReleaseALEffects(device
);
2163 ResetUIntMap(&device
->EffectMap
);
2165 if(device
->FilterMap
.size
> 0)
2167 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2168 ReleaseALFilters(device
);
2170 ResetUIntMap(&device
->FilterMap
);
2172 if(device
->SfontMap
.size
> 0)
2174 WARN("(%p) Deleting %d Soundfont(s)\n", device
, device
->SfontMap
.size
);
2175 ReleaseALSoundfonts(device
);
2177 ResetUIntMap(&device
->SfontMap
);
2179 if(device
->PresetMap
.size
> 0)
2181 WARN("(%p) Deleting %d Preset(s)\n", device
, device
->PresetMap
.size
);
2182 ReleaseALPresets(device
);
2184 ResetUIntMap(&device
->PresetMap
);
2186 if(device
->FontsoundMap
.size
> 0)
2188 WARN("(%p) Deleting %d Fontsound(s)\n", device
, device
->FontsoundMap
.size
);
2189 ReleaseALFontsounds(device
);
2191 ResetUIntMap(&device
->FontsoundMap
);
2194 device
->Bs2b
= NULL
;
2196 AL_STRING_DEINIT(device
->DeviceName
);
2198 al_free(device
->DryBuffer
);
2199 device
->DryBuffer
= NULL
;
2205 void ALCdevice_IncRef(ALCdevice
*device
)
2208 ref
= IncrementRef(&device
->ref
);
2209 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2212 void ALCdevice_DecRef(ALCdevice
*device
)
2215 ref
= DecrementRef(&device
->ref
);
2216 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2217 if(ref
== 0) FreeDevice(device
);
2222 * Checks if the device handle is valid, and increments its ref count if so.
2224 static ALCdevice
*VerifyDevice(ALCdevice
*device
)
2226 ALCdevice
*tmpDevice
;
2232 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2233 while(tmpDevice
&& tmpDevice
!= device
)
2234 tmpDevice
= tmpDevice
->next
;
2237 ALCdevice_IncRef(tmpDevice
);
2245 * Initializes context fields
2247 static ALvoid
InitContext(ALCcontext
*Context
)
2251 //Initialise listener
2252 Context
->Listener
->Gain
= 1.0f
;
2253 Context
->Listener
->MetersPerUnit
= 1.0f
;
2254 Context
->Listener
->Position
[0] = 0.0f
;
2255 Context
->Listener
->Position
[1] = 0.0f
;
2256 Context
->Listener
->Position
[2] = 0.0f
;
2257 Context
->Listener
->Velocity
[0] = 0.0f
;
2258 Context
->Listener
->Velocity
[1] = 0.0f
;
2259 Context
->Listener
->Velocity
[2] = 0.0f
;
2260 Context
->Listener
->Forward
[0] = 0.0f
;
2261 Context
->Listener
->Forward
[1] = 0.0f
;
2262 Context
->Listener
->Forward
[2] = -1.0f
;
2263 Context
->Listener
->Up
[0] = 0.0f
;
2264 Context
->Listener
->Up
[1] = 1.0f
;
2265 Context
->Listener
->Up
[2] = 0.0f
;
2266 for(i
= 0;i
< 4;i
++)
2268 for(j
= 0;j
< 4;j
++)
2269 Context
->Listener
->Params
.Matrix
[i
][j
] = ((i
==j
) ? 1.0f
: 0.0f
);
2271 for(i
= 0;i
< 3;i
++)
2272 Context
->Listener
->Params
.Velocity
[i
] = 0.0f
;
2275 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2276 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2277 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2278 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2281 Context
->DistanceModel
= DefaultDistanceModel
;
2282 Context
->SourceDistanceModel
= AL_FALSE
;
2283 Context
->DopplerFactor
= 1.0f
;
2284 Context
->DopplerVelocity
= 1.0f
;
2285 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2286 Context
->DeferUpdates
= AL_FALSE
;
2288 Context
->ExtensionList
= alExtList
;
2294 * Cleans up the context, and destroys any remaining objects the app failed to
2295 * delete. Called once there's no more references on the context.
2297 static void FreeContext(ALCcontext
*context
)
2299 TRACE("%p\n", context
);
2301 if(context
->SourceMap
.size
> 0)
2303 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2304 ReleaseALSources(context
);
2306 ResetUIntMap(&context
->SourceMap
);
2308 if(context
->EffectSlotMap
.size
> 0)
2310 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2311 ReleaseALAuxiliaryEffectSlots(context
);
2313 ResetUIntMap(&context
->EffectSlotMap
);
2315 al_free(context
->Voices
);
2316 context
->Voices
= NULL
;
2317 context
->VoiceCount
= 0;
2318 context
->MaxVoices
= 0;
2320 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2322 ALCdevice_DecRef(context
->Device
);
2323 context
->Device
= NULL
;
2325 //Invalidate context
2326 memset(context
, 0, sizeof(ALCcontext
));
2332 * Removes the context reference from the given device and removes it from
2333 * being current on the running thread or globally.
2335 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2337 ALCcontext
*nextctx
;
2338 ALCcontext
*origctx
;
2340 if(altss_get(LocalContext
) == context
)
2342 WARN("%p released while current on thread\n", context
);
2343 altss_set(LocalContext
, NULL
);
2344 ALCcontext_DecRef(context
);
2348 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2349 ALCcontext_DecRef(context
);
2351 ALCdevice_Lock(device
);
2353 nextctx
= context
->next
;
2354 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2360 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2362 ALCdevice_Unlock(device
);
2364 ALCcontext_DecRef(context
);
2367 void ALCcontext_IncRef(ALCcontext
*context
)
2370 ref
= IncrementRef(&context
->ref
);
2371 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2374 void ALCcontext_DecRef(ALCcontext
*context
)
2377 ref
= DecrementRef(&context
->ref
);
2378 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2379 if(ref
== 0) FreeContext(context
);
2382 static void ReleaseThreadCtx(void *ptr
)
2384 WARN("%p current for thread being destroyed\n", ptr
);
2385 ALCcontext_DecRef(ptr
);
2390 * Checks that the given context is valid, and increments its reference count.
2392 static ALCcontext
*VerifyContext(ALCcontext
*context
)
2397 dev
= ATOMIC_LOAD(&DeviceList
);
2400 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2405 ALCcontext_IncRef(ctx
);
2421 * Returns the currently active context for this thread, and adds a reference
2422 * without locking it.
2424 ALCcontext
*GetContextRef(void)
2426 ALCcontext
*context
;
2428 context
= altss_get(LocalContext
);
2430 ALCcontext_IncRef(context
);
2434 context
= ATOMIC_LOAD(&GlobalContext
);
2436 ALCcontext_IncRef(context
);
2444 /************************************************
2445 * Standard ALC functions
2446 ************************************************/
2450 * Return last ALC generated error code for the given device
2452 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2456 if(VerifyDevice(device
))
2458 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2459 ALCdevice_DecRef(device
);
2462 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2468 /* alcSuspendContext
2470 * Suspends updates for the given context
2472 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2477 context
= VerifyContext(context
);
2479 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2482 ALCcontext_DeferUpdates(context
);
2483 ALCcontext_DecRef(context
);
2487 /* alcProcessContext
2489 * Resumes processing updates for the given context
2491 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2496 context
= VerifyContext(context
);
2498 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2501 ALCcontext_ProcessUpdates(context
);
2502 ALCcontext_DecRef(context
);
2509 * Returns information about the device, and error strings
2511 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2513 const ALCchar
*value
= NULL
;
2521 case ALC_INVALID_ENUM
:
2522 value
= alcErrInvalidEnum
;
2525 case ALC_INVALID_VALUE
:
2526 value
= alcErrInvalidValue
;
2529 case ALC_INVALID_DEVICE
:
2530 value
= alcErrInvalidDevice
;
2533 case ALC_INVALID_CONTEXT
:
2534 value
= alcErrInvalidContext
;
2537 case ALC_OUT_OF_MEMORY
:
2538 value
= alcErrOutOfMemory
;
2541 case ALC_DEVICE_SPECIFIER
:
2542 value
= alcDefaultName
;
2545 case ALC_ALL_DEVICES_SPECIFIER
:
2546 if(VerifyDevice(Device
))
2548 value
= al_string_get_cstr(Device
->DeviceName
);
2549 ALCdevice_DecRef(Device
);
2553 ProbeAllDevicesList();
2554 value
= al_string_get_cstr(alcAllDevicesList
);
2558 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2559 if(VerifyDevice(Device
))
2561 value
= al_string_get_cstr(Device
->DeviceName
);
2562 ALCdevice_DecRef(Device
);
2566 ProbeCaptureDeviceList();
2567 value
= al_string_get_cstr(alcCaptureDeviceList
);
2571 /* Default devices are always first in the list */
2572 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2573 value
= alcDefaultName
;
2576 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2577 if(al_string_empty(alcAllDevicesList
))
2578 ProbeAllDevicesList();
2580 Device
= VerifyDevice(Device
);
2582 free(alcDefaultAllDevicesSpecifier
);
2583 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2584 if(!alcDefaultAllDevicesSpecifier
)
2585 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2587 value
= alcDefaultAllDevicesSpecifier
;
2588 if(Device
) ALCdevice_DecRef(Device
);
2591 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2592 if(al_string_empty(alcCaptureDeviceList
))
2593 ProbeCaptureDeviceList();
2595 Device
= VerifyDevice(Device
);
2597 free(alcCaptureDefaultDeviceSpecifier
);
2598 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2599 if(!alcCaptureDefaultDeviceSpecifier
)
2600 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2602 value
= alcCaptureDefaultDeviceSpecifier
;
2603 if(Device
) ALCdevice_DecRef(Device
);
2606 case ALC_EXTENSIONS
:
2607 if(!VerifyDevice(Device
))
2608 value
= alcNoDeviceExtList
;
2611 value
= alcExtensionList
;
2612 ALCdevice_DecRef(Device
);
2617 Device
= VerifyDevice(Device
);
2618 alcSetError(Device
, ALC_INVALID_ENUM
);
2619 if(Device
) ALCdevice_DecRef(Device
);
2627 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2631 if(size
<= 0 || values
== NULL
)
2633 alcSetError(device
, ALC_INVALID_VALUE
);
2641 case ALC_MAJOR_VERSION
:
2642 values
[0] = alcMajorVersion
;
2644 case ALC_MINOR_VERSION
:
2645 values
[0] = alcMinorVersion
;
2648 case ALC_ATTRIBUTES_SIZE
:
2649 case ALC_ALL_ATTRIBUTES
:
2653 case ALC_MONO_SOURCES
:
2654 case ALC_STEREO_SOURCES
:
2655 case ALC_CAPTURE_SAMPLES
:
2656 case ALC_FORMAT_CHANNELS_SOFT
:
2657 case ALC_FORMAT_TYPE_SOFT
:
2658 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2662 alcSetError(NULL
, ALC_INVALID_ENUM
);
2668 if(device
->Type
== Capture
)
2672 case ALC_CAPTURE_SAMPLES
:
2673 ALCdevice_Lock(device
);
2674 values
[0] = V0(device
->Backend
,availableSamples
)();
2675 ALCdevice_Unlock(device
);
2679 values
[0] = device
->Connected
;
2683 alcSetError(device
, ALC_INVALID_ENUM
);
2692 case ALC_MAJOR_VERSION
:
2693 values
[0] = alcMajorVersion
;
2696 case ALC_MINOR_VERSION
:
2697 values
[0] = alcMinorVersion
;
2700 case ALC_EFX_MAJOR_VERSION
:
2701 values
[0] = alcEFXMajorVersion
;
2704 case ALC_EFX_MINOR_VERSION
:
2705 values
[0] = alcEFXMinorVersion
;
2708 case ALC_ATTRIBUTES_SIZE
:
2712 case ALC_ALL_ATTRIBUTES
:
2715 alcSetError(device
, ALC_INVALID_VALUE
);
2720 values
[i
++] = ALC_FREQUENCY
;
2721 values
[i
++] = device
->Frequency
;
2723 if(device
->Type
!= Loopback
)
2725 values
[i
++] = ALC_REFRESH
;
2726 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2728 values
[i
++] = ALC_SYNC
;
2729 values
[i
++] = ALC_FALSE
;
2733 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2734 values
[i
++] = device
->FmtChans
;
2736 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2737 values
[i
++] = device
->FmtType
;
2740 values
[i
++] = ALC_MONO_SOURCES
;
2741 values
[i
++] = device
->NumMonoSources
;
2743 values
[i
++] = ALC_STEREO_SOURCES
;
2744 values
[i
++] = device
->NumStereoSources
;
2746 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2747 values
[i
++] = device
->NumAuxSends
;
2749 values
[i
++] = ALC_HRTF_SOFT
;
2750 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2756 values
[0] = device
->Frequency
;
2760 if(device
->Type
== Loopback
)
2762 alcSetError(device
, ALC_INVALID_DEVICE
);
2765 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2769 if(device
->Type
== Loopback
)
2771 alcSetError(device
, ALC_INVALID_DEVICE
);
2774 values
[0] = ALC_FALSE
;
2777 case ALC_FORMAT_CHANNELS_SOFT
:
2778 if(device
->Type
!= Loopback
)
2780 alcSetError(device
, ALC_INVALID_DEVICE
);
2783 values
[0] = device
->FmtChans
;
2786 case ALC_FORMAT_TYPE_SOFT
:
2787 if(device
->Type
!= Loopback
)
2789 alcSetError(device
, ALC_INVALID_DEVICE
);
2792 values
[0] = device
->FmtType
;
2795 case ALC_MONO_SOURCES
:
2796 values
[0] = device
->NumMonoSources
;
2799 case ALC_STEREO_SOURCES
:
2800 values
[0] = device
->NumStereoSources
;
2803 case ALC_MAX_AUXILIARY_SENDS
:
2804 values
[0] = device
->NumAuxSends
;
2808 values
[0] = device
->Connected
;
2812 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2816 alcSetError(device
, ALC_INVALID_ENUM
);
2824 * Returns information about the device and the version of OpenAL
2826 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2828 device
= VerifyDevice(device
);
2829 if(size
<= 0 || values
== NULL
)
2830 alcSetError(device
, ALC_INVALID_VALUE
);
2832 GetIntegerv(device
, param
, size
, values
);
2833 if(device
) ALCdevice_DecRef(device
);
2836 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2841 device
= VerifyDevice(device
);
2842 if(size
<= 0 || values
== NULL
)
2843 alcSetError(device
, ALC_INVALID_VALUE
);
2844 else if(!device
|| device
->Type
== Capture
)
2846 ivals
= malloc(size
* sizeof(ALCint
));
2847 size
= GetIntegerv(device
, pname
, size
, ivals
);
2848 for(i
= 0;i
< size
;i
++)
2849 values
[i
] = ivals
[i
];
2852 else /* render device */
2856 case ALC_ATTRIBUTES_SIZE
:
2860 case ALC_ALL_ATTRIBUTES
:
2862 alcSetError(device
, ALC_INVALID_VALUE
);
2867 V0(device
->Backend
,lock
)();
2868 values
[i
++] = ALC_FREQUENCY
;
2869 values
[i
++] = device
->Frequency
;
2871 if(device
->Type
!= Loopback
)
2873 values
[i
++] = ALC_REFRESH
;
2874 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2876 values
[i
++] = ALC_SYNC
;
2877 values
[i
++] = ALC_FALSE
;
2881 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2882 values
[i
++] = device
->FmtChans
;
2884 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2885 values
[i
++] = device
->FmtType
;
2888 values
[i
++] = ALC_MONO_SOURCES
;
2889 values
[i
++] = device
->NumMonoSources
;
2891 values
[i
++] = ALC_STEREO_SOURCES
;
2892 values
[i
++] = device
->NumStereoSources
;
2894 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2895 values
[i
++] = device
->NumAuxSends
;
2897 values
[i
++] = ALC_HRTF_SOFT
;
2898 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2900 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2901 values
[i
++] = device
->ClockBase
+
2902 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2905 V0(device
->Backend
,unlock
)();
2909 case ALC_DEVICE_CLOCK_SOFT
:
2910 V0(device
->Backend
,lock
)();
2911 *values
= device
->ClockBase
+
2912 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2913 V0(device
->Backend
,unlock
)();
2917 ivals
= malloc(size
* sizeof(ALCint
));
2918 size
= GetIntegerv(device
, pname
, size
, ivals
);
2919 for(i
= 0;i
< size
;i
++)
2920 values
[i
] = ivals
[i
];
2926 ALCdevice_DecRef(device
);
2930 /* alcIsExtensionPresent
2932 * Determines if there is support for a particular extension
2934 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2936 ALCboolean bResult
= ALC_FALSE
;
2938 device
= VerifyDevice(device
);
2941 alcSetError(device
, ALC_INVALID_VALUE
);
2944 size_t len
= strlen(extName
);
2945 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2948 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2949 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2954 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2958 } while(isspace(*ptr
));
2963 ALCdevice_DecRef(device
);
2968 /* alcGetProcAddress
2970 * Retrieves the function address for a particular extension function
2972 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2974 ALCvoid
*ptr
= NULL
;
2978 device
= VerifyDevice(device
);
2979 alcSetError(device
, ALC_INVALID_VALUE
);
2980 if(device
) ALCdevice_DecRef(device
);
2985 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
2987 ptr
= alcFunctions
[i
].address
;
2996 * Get the value for a particular ALC enumeration name
2998 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3004 device
= VerifyDevice(device
);
3005 alcSetError(device
, ALC_INVALID_VALUE
);
3006 if(device
) ALCdevice_DecRef(device
);
3011 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3013 val
= enumeration
[i
].value
;
3022 * Create and attach a context to the given device.
3024 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3026 ALCcontext
*ALContext
;
3030 if(!(device
=VerifyDevice(device
)) || device
->Type
== Capture
|| !device
->Connected
)
3033 alcSetError(device
, ALC_INVALID_DEVICE
);
3034 if(device
) ALCdevice_DecRef(device
);
3038 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3040 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3043 alcSetError(device
, err
);
3044 if(err
== ALC_INVALID_DEVICE
)
3046 ALCdevice_Lock(device
);
3047 aluHandleDisconnect(device
);
3048 ALCdevice_Unlock(device
);
3050 ALCdevice_DecRef(device
);
3054 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3057 InitRef(&ALContext
->ref
, 1);
3058 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3060 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3062 ALContext
->VoiceCount
= 0;
3063 ALContext
->MaxVoices
= 256;
3064 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3066 if(!ALContext
|| !ALContext
->Voices
)
3068 if(!ATOMIC_LOAD(&device
->ContextList
))
3070 V0(device
->Backend
,stop
)();
3071 device
->Flags
&= ~DEVICE_RUNNING
;
3077 al_free(ALContext
->Voices
);
3078 ALContext
->Voices
= NULL
;
3080 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3086 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3087 ALCdevice_DecRef(device
);
3091 ALContext
->Device
= device
;
3092 ALCdevice_IncRef(device
);
3093 InitContext(ALContext
);
3096 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3098 ALContext
->next
= head
;
3099 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3103 ALCdevice_DecRef(device
);
3105 TRACE("Created context %p\n", ALContext
);
3109 /* alcDestroyContext
3111 * Remove a context from its device
3113 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3118 /* alcGetContextsDevice sets an error for invalid contexts */
3119 Device
= alcGetContextsDevice(context
);
3122 ReleaseContext(context
, Device
);
3123 if(!ATOMIC_LOAD(&Device
->ContextList
))
3125 V0(Device
->Backend
,stop
)();
3126 Device
->Flags
&= ~DEVICE_RUNNING
;
3133 /* alcGetCurrentContext
3135 * Returns the currently active context on the calling thread
3137 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3139 ALCcontext
*Context
= altss_get(LocalContext
);
3140 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3144 /* alcGetThreadContext
3146 * Returns the currently active thread-local context
3148 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3150 return altss_get(LocalContext
);
3154 /* alcMakeContextCurrent
3156 * Makes the given context the active process-wide context, and removes the
3157 * thread-local context for the calling thread.
3159 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3161 /* context must be valid or NULL */
3162 if(context
&& !(context
=VerifyContext(context
)))
3164 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3167 /* context's reference count is already incremented */
3168 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3169 if(context
) ALCcontext_DecRef(context
);
3171 if((context
=altss_get(LocalContext
)) != NULL
)
3173 altss_set(LocalContext
, NULL
);
3174 ALCcontext_DecRef(context
);
3180 /* alcSetThreadContext
3182 * Makes the given context the active context for the current thread
3184 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3188 /* context must be valid or NULL */
3189 if(context
&& !(context
=VerifyContext(context
)))
3191 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3194 /* context's reference count is already incremented */
3195 old
= altss_get(LocalContext
);
3196 altss_set(LocalContext
, context
);
3197 if(old
) ALCcontext_DecRef(old
);
3203 /* alcGetContextsDevice
3205 * Returns the device that a particular context is attached to
3207 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3211 if(!(Context
=VerifyContext(Context
)))
3213 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3216 Device
= Context
->Device
;
3217 ALCcontext_DecRef(Context
);
3225 * Opens the named device.
3227 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3235 if(!PlaybackBackend
.name
)
3237 alcSetError(NULL
, ALC_INVALID_VALUE
);
3241 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3244 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3247 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3252 InitRef(&device
->ref
, 1);
3253 device
->Connected
= ALC_TRUE
;
3254 device
->Type
= Playback
;
3255 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3258 device
->Bs2b
= NULL
;
3259 AL_STRING_INIT(device
->DeviceName
);
3260 device
->DryBuffer
= NULL
;
3262 ATOMIC_INIT(&device
->ContextList
, NULL
);
3264 device
->ClockBase
= 0;
3265 device
->SamplesDone
= 0;
3267 device
->MaxNoOfSources
= 256;
3268 device
->AuxiliaryEffectSlotMax
= 4;
3269 device
->NumAuxSends
= MAX_SENDS
;
3271 InitUIntMap(&device
->BufferMap
, ~0);
3272 InitUIntMap(&device
->EffectMap
, ~0);
3273 InitUIntMap(&device
->FilterMap
, ~0);
3274 InitUIntMap(&device
->SfontMap
, ~0);
3275 InitUIntMap(&device
->PresetMap
, ~0);
3276 InitUIntMap(&device
->FontsoundMap
, ~0);
3279 device
->FmtChans
= DevFmtChannelsDefault
;
3280 device
->FmtType
= DevFmtTypeDefault
;
3281 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3282 device
->IsHeadphones
= AL_FALSE
;
3283 device
->NumUpdates
= 4;
3284 device
->UpdateSize
= 1024;
3286 if(!PlaybackBackend
.getFactory
)
3287 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3288 ALCbackend_Playback
);
3291 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3292 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3294 if(!device
->Backend
)
3297 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3302 if(ConfigValueStr(NULL
, "channels", &fmt
))
3304 static const struct {
3305 const char name
[16];
3306 enum DevFmtChannels chans
;
3308 { "mono", DevFmtMono
},
3309 { "stereo", DevFmtStereo
},
3310 { "quad", DevFmtQuad
},
3311 { "surround51", DevFmtX51
},
3312 { "surround61", DevFmtX61
},
3313 { "surround71", DevFmtX71
},
3314 { "surround51rear", DevFmtX51Rear
},
3318 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3320 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3322 device
->FmtChans
= chanlist
[i
].chans
;
3323 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3327 if(i
== COUNTOF(chanlist
))
3328 ERR("Unsupported channels: %s\n", fmt
);
3330 if(ConfigValueStr(NULL
, "sample-type", &fmt
))
3332 static const struct {
3333 const char name
[16];
3334 enum DevFmtType type
;
3336 { "int8", DevFmtByte
},
3337 { "uint8", DevFmtUByte
},
3338 { "int16", DevFmtShort
},
3339 { "uint16", DevFmtUShort
},
3340 { "int32", DevFmtInt
},
3341 { "uint32", DevFmtUInt
},
3342 { "float32", DevFmtFloat
},
3346 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3348 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3350 device
->FmtType
= typelist
[i
].type
;
3351 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3355 if(i
== COUNTOF(typelist
))
3356 ERR("Unsupported sample-type: %s\n", fmt
);
3359 if(ConfigValueUInt(NULL
, "frequency", &device
->Frequency
))
3361 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3362 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3363 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3364 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3367 ConfigValueUInt(NULL
, "periods", &device
->NumUpdates
);
3368 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3370 ConfigValueUInt(NULL
, "period_size", &device
->UpdateSize
);
3371 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3372 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3373 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3375 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3376 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3378 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3379 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3381 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3382 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3384 device
->NumStereoSources
= 1;
3385 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3387 device
->Synth
= SynthCreate(device
);
3390 DELETE_OBJ(device
->Backend
);
3392 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3396 // Find a playback device to open
3397 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3399 DELETE_OBJ(device
->Synth
);
3400 DELETE_OBJ(device
->Backend
);
3402 alcSetError(NULL
, err
);
3406 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3408 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3409 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3411 device
->DefaultSlot
= NULL
;
3412 ERR("Failed to initialize the default effect slot\n");
3414 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3416 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3417 device
->DefaultSlot
= NULL
;
3419 ERR("Failed to initialize the default effect\n");
3424 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3426 device
->next
= head
;
3427 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3430 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3436 * Closes the given device.
3438 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3440 ALCdevice
*list
, *origdev
, *nextdev
;
3444 list
= ATOMIC_LOAD(&DeviceList
);
3448 } while((list
=list
->next
) != NULL
);
3449 if(!list
|| list
->Type
== Capture
)
3451 alcSetError(list
, ALC_INVALID_DEVICE
);
3457 nextdev
= device
->next
;
3458 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3463 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3467 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3470 ALCcontext
*next
= ctx
->next
;
3471 WARN("Releasing context %p\n", ctx
);
3472 ReleaseContext(ctx
, device
);
3475 if((device
->Flags
&DEVICE_RUNNING
))
3476 V0(device
->Backend
,stop
)();
3477 device
->Flags
&= ~DEVICE_RUNNING
;
3479 ALCdevice_DecRef(device
);
3485 /************************************************
3486 * ALC capture functions
3487 ************************************************/
3488 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3490 ALCdevice
*device
= NULL
;
3495 if(!CaptureBackend
.name
)
3497 alcSetError(NULL
, ALC_INVALID_VALUE
);
3503 alcSetError(NULL
, ALC_INVALID_VALUE
);
3507 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3510 device
= al_calloc(16, sizeof(ALCdevice
));
3513 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3518 InitRef(&device
->ref
, 1);
3519 device
->Connected
= ALC_TRUE
;
3520 device
->Type
= Capture
;
3522 AL_STRING_INIT(device
->DeviceName
);
3523 device
->DryBuffer
= NULL
;
3525 InitUIntMap(&device
->BufferMap
, ~0);
3526 InitUIntMap(&device
->EffectMap
, ~0);
3527 InitUIntMap(&device
->FilterMap
, ~0);
3528 InitUIntMap(&device
->SfontMap
, ~0);
3529 InitUIntMap(&device
->PresetMap
, ~0);
3530 InitUIntMap(&device
->FontsoundMap
, ~0);
3532 if(!CaptureBackend
.getFactory
)
3533 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3534 ALCbackend_Capture
);
3537 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3538 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3540 if(!device
->Backend
)
3543 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3547 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3548 device
->Frequency
= frequency
;
3550 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3551 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3554 alcSetError(NULL
, ALC_INVALID_ENUM
);
3557 device
->IsHeadphones
= AL_FALSE
;
3559 device
->UpdateSize
= samples
;
3560 device
->NumUpdates
= 1;
3562 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3565 alcSetError(NULL
, err
);
3570 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3572 device
->next
= head
;
3573 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3576 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3580 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3582 ALCdevice
*list
, *next
, *nextdev
;
3585 list
= ATOMIC_LOAD(&DeviceList
);
3589 } while((list
=list
->next
) != NULL
);
3590 if(!list
|| list
->Type
!= Capture
)
3592 alcSetError(list
, ALC_INVALID_DEVICE
);
3598 nextdev
= device
->next
;
3599 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3604 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3608 ALCdevice_DecRef(device
);
3613 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3615 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3616 alcSetError(device
, ALC_INVALID_DEVICE
);
3619 ALCdevice_Lock(device
);
3620 if(device
->Connected
)
3622 if(!(device
->Flags
&DEVICE_RUNNING
))
3623 V0(device
->Backend
,start
)();
3624 device
->Flags
|= DEVICE_RUNNING
;
3626 ALCdevice_Unlock(device
);
3629 if(device
) ALCdevice_DecRef(device
);
3632 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3634 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3635 alcSetError(device
, ALC_INVALID_DEVICE
);
3638 ALCdevice_Lock(device
);
3639 if((device
->Flags
&DEVICE_RUNNING
))
3640 V0(device
->Backend
,stop
)();
3641 device
->Flags
&= ~DEVICE_RUNNING
;
3642 ALCdevice_Unlock(device
);
3645 if(device
) ALCdevice_DecRef(device
);
3648 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3650 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Capture
)
3651 alcSetError(device
, ALC_INVALID_DEVICE
);
3654 ALCenum err
= ALC_INVALID_VALUE
;
3656 ALCdevice_Lock(device
);
3657 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3658 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3659 ALCdevice_Unlock(device
);
3661 if(err
!= ALC_NO_ERROR
)
3662 alcSetError(device
, err
);
3664 if(device
) ALCdevice_DecRef(device
);
3668 /************************************************
3669 * ALC loopback functions
3670 ************************************************/
3672 /* alcLoopbackOpenDeviceSOFT
3674 * Open a loopback device, for manual rendering.
3676 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3678 ALCbackendFactory
*factory
;
3683 /* Make sure the device name, if specified, is us. */
3684 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3686 alcSetError(NULL
, ALC_INVALID_VALUE
);
3690 device
= al_calloc(16, sizeof(ALCdevice
));
3693 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3698 InitRef(&device
->ref
, 1);
3699 device
->Connected
= ALC_TRUE
;
3700 device
->Type
= Loopback
;
3701 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3704 device
->Bs2b
= NULL
;
3705 AL_STRING_INIT(device
->DeviceName
);
3706 device
->DryBuffer
= NULL
;
3708 ATOMIC_INIT(&device
->ContextList
, NULL
);
3710 device
->ClockBase
= 0;
3711 device
->SamplesDone
= 0;
3713 device
->MaxNoOfSources
= 256;
3714 device
->AuxiliaryEffectSlotMax
= 4;
3715 device
->NumAuxSends
= MAX_SENDS
;
3717 InitUIntMap(&device
->BufferMap
, ~0);
3718 InitUIntMap(&device
->EffectMap
, ~0);
3719 InitUIntMap(&device
->FilterMap
, ~0);
3720 InitUIntMap(&device
->SfontMap
, ~0);
3721 InitUIntMap(&device
->PresetMap
, ~0);
3722 InitUIntMap(&device
->FontsoundMap
, ~0);
3724 factory
= ALCloopbackFactory_getFactory();
3725 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3726 if(!device
->Backend
)
3729 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3734 device
->NumUpdates
= 0;
3735 device
->UpdateSize
= 0;
3737 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3738 device
->FmtChans
= DevFmtChannelsDefault
;
3739 device
->FmtType
= DevFmtTypeDefault
;
3740 device
->IsHeadphones
= AL_FALSE
;
3742 ConfigValueUInt(NULL
, "sources", &device
->MaxNoOfSources
);
3743 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3745 ConfigValueUInt(NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3746 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3748 ConfigValueUInt(NULL
, "sends", &device
->NumAuxSends
);
3749 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3751 device
->NumStereoSources
= 1;
3752 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3754 device
->Synth
= SynthCreate(device
);
3757 DELETE_OBJ(device
->Backend
);
3759 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3763 // Open the "backend"
3764 V(device
->Backend
,open
)("Loopback");
3767 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3769 device
->next
= head
;
3770 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3773 TRACE("Created device %p\n", device
);
3777 /* alcIsRenderFormatSupportedSOFT
3779 * Determines if the loopback device supports the given format for rendering.
3781 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3783 ALCboolean ret
= ALC_FALSE
;
3785 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3786 alcSetError(device
, ALC_INVALID_DEVICE
);
3788 alcSetError(device
, ALC_INVALID_VALUE
);
3791 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3792 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3793 freq
>= MIN_OUTPUT_RATE
)
3796 if(device
) ALCdevice_DecRef(device
);
3801 /* alcRenderSamplesSOFT
3803 * Renders some samples into a buffer, using the format last set by the
3804 * attributes given to alcCreateContext.
3806 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3808 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Loopback
)
3809 alcSetError(device
, ALC_INVALID_DEVICE
);
3810 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3811 alcSetError(device
, ALC_INVALID_VALUE
);
3813 aluMixData(device
, buffer
, samples
);
3814 if(device
) ALCdevice_DecRef(device
);
3818 /************************************************
3819 * ALC DSP pause/resume functions
3820 ************************************************/
3822 /* alcDevicePauseSOFT
3824 * Pause the DSP to stop audio processing.
3826 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3828 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3829 alcSetError(device
, ALC_INVALID_DEVICE
);
3833 if((device
->Flags
&DEVICE_RUNNING
))
3834 V0(device
->Backend
,stop
)();
3835 device
->Flags
&= ~DEVICE_RUNNING
;
3836 device
->Flags
|= DEVICE_PAUSED
;
3839 if(device
) ALCdevice_DecRef(device
);
3842 /* alcDeviceResumeSOFT
3844 * Resume the DSP to restart audio processing.
3846 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3848 if(!(device
=VerifyDevice(device
)) || device
->Type
!= Playback
)
3849 alcSetError(device
, ALC_INVALID_DEVICE
);
3853 if((device
->Flags
&DEVICE_PAUSED
))
3855 device
->Flags
&= ~DEVICE_PAUSED
;
3856 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3858 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3859 device
->Flags
|= DEVICE_RUNNING
;
3862 alcSetError(device
, ALC_INVALID_DEVICE
);
3863 ALCdevice_Lock(device
);
3864 aluHandleDisconnect(device
);
3865 ALCdevice_Unlock(device
);
3871 if(device
) ALCdevice_DecRef(device
);