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"
38 #include "bformatdec.h"
46 #include "backends/base.h"
49 /************************************************
51 ************************************************/
54 ALCbackendFactory
* (*getFactory
)(void);
55 ALCboolean (*Init
)(BackendFuncs
*);
57 void (*Probe
)(enum DevProbe
);
61 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
62 static struct BackendInfo BackendList
[] = {
64 { "jack", ALCjackBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
66 #ifdef HAVE_PULSEAUDIO
67 { "pulse", ALCpulseBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
70 { "alsa", ALCalsaBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
73 { "core", NULL
, alc_ca_init
, alc_ca_deinit
, alc_ca_probe
, EmptyFuncs
},
76 { "oss", ALCossBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
79 { "solaris", ALCsolarisBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
82 { "sndio", NULL
, alc_sndio_init
, alc_sndio_deinit
, alc_sndio_probe
, EmptyFuncs
},
85 { "qsa", NULL
, alc_qsa_init
, alc_qsa_deinit
, alc_qsa_probe
, EmptyFuncs
},
88 { "mmdevapi", ALCmmdevBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
91 { "dsound", ALCdsoundBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
94 { "winmm", ALCwinmmBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
97 { "port", ALCportBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
100 { "opensl", NULL
, alc_opensl_init
, alc_opensl_deinit
, alc_opensl_probe
, EmptyFuncs
},
103 { "null", ALCnullBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
105 { "wave", ALCwaveBackendFactory_getFactory
, NULL
, NULL
, NULL
, EmptyFuncs
},
108 { NULL
, NULL
, NULL
, NULL
, NULL
, EmptyFuncs
}
112 static struct BackendInfo PlaybackBackend
;
113 static struct BackendInfo CaptureBackend
;
116 /************************************************
117 * Functions, enums, and errors
118 ************************************************/
119 typedef struct ALCfunction
{
120 const ALCchar
*funcName
;
124 typedef struct ALCenums
{
125 const ALCchar
*enumName
;
129 #define DECL(x) { #x, (ALCvoid*)(x) }
130 static const ALCfunction alcFunctions
[] = {
131 DECL(alcCreateContext
),
132 DECL(alcMakeContextCurrent
),
133 DECL(alcProcessContext
),
134 DECL(alcSuspendContext
),
135 DECL(alcDestroyContext
),
136 DECL(alcGetCurrentContext
),
137 DECL(alcGetContextsDevice
),
139 DECL(alcCloseDevice
),
141 DECL(alcIsExtensionPresent
),
142 DECL(alcGetProcAddress
),
143 DECL(alcGetEnumValue
),
145 DECL(alcGetIntegerv
),
146 DECL(alcCaptureOpenDevice
),
147 DECL(alcCaptureCloseDevice
),
148 DECL(alcCaptureStart
),
149 DECL(alcCaptureStop
),
150 DECL(alcCaptureSamples
),
152 DECL(alcSetThreadContext
),
153 DECL(alcGetThreadContext
),
155 DECL(alcLoopbackOpenDeviceSOFT
),
156 DECL(alcIsRenderFormatSupportedSOFT
),
157 DECL(alcRenderSamplesSOFT
),
159 DECL(alcDevicePauseSOFT
),
160 DECL(alcDeviceResumeSOFT
),
162 DECL(alcGetStringiSOFT
),
163 DECL(alcResetDeviceSOFT
),
165 DECL(alcGetInteger64vSOFT
),
180 DECL(alIsExtensionPresent
),
181 DECL(alGetProcAddress
),
182 DECL(alGetEnumValue
),
189 DECL(alGetListenerf
),
190 DECL(alGetListener3f
),
191 DECL(alGetListenerfv
),
192 DECL(alGetListeneri
),
193 DECL(alGetListener3i
),
194 DECL(alGetListeneriv
),
196 DECL(alDeleteSources
),
212 DECL(alSourceRewindv
),
213 DECL(alSourcePausev
),
216 DECL(alSourceRewind
),
218 DECL(alSourceQueueBuffers
),
219 DECL(alSourceUnqueueBuffers
),
221 DECL(alDeleteBuffers
),
236 DECL(alDopplerFactor
),
237 DECL(alDopplerVelocity
),
238 DECL(alSpeedOfSound
),
239 DECL(alDistanceModel
),
242 DECL(alDeleteFilters
),
253 DECL(alDeleteEffects
),
263 DECL(alGenAuxiliaryEffectSlots
),
264 DECL(alDeleteAuxiliaryEffectSlots
),
265 DECL(alIsAuxiliaryEffectSlot
),
266 DECL(alAuxiliaryEffectSloti
),
267 DECL(alAuxiliaryEffectSlotiv
),
268 DECL(alAuxiliaryEffectSlotf
),
269 DECL(alAuxiliaryEffectSlotfv
),
270 DECL(alGetAuxiliaryEffectSloti
),
271 DECL(alGetAuxiliaryEffectSlotiv
),
272 DECL(alGetAuxiliaryEffectSlotf
),
273 DECL(alGetAuxiliaryEffectSlotfv
),
275 DECL(alDeferUpdatesSOFT
),
276 DECL(alProcessUpdatesSOFT
),
279 DECL(alSource3dSOFT
),
280 DECL(alSourcedvSOFT
),
281 DECL(alGetSourcedSOFT
),
282 DECL(alGetSource3dSOFT
),
283 DECL(alGetSourcedvSOFT
),
284 DECL(alSourcei64SOFT
),
285 DECL(alSource3i64SOFT
),
286 DECL(alSourcei64vSOFT
),
287 DECL(alGetSourcei64SOFT
),
288 DECL(alGetSource3i64SOFT
),
289 DECL(alGetSourcei64vSOFT
),
291 DECL(alBufferSamplesSOFT
),
292 DECL(alGetBufferSamplesSOFT
),
293 DECL(alIsBufferFormatSupportedSOFT
),
299 #define DECL(x) { #x, (x) }
300 static const ALCenums enumeration
[] = {
305 DECL(ALC_MAJOR_VERSION
),
306 DECL(ALC_MINOR_VERSION
),
307 DECL(ALC_ATTRIBUTES_SIZE
),
308 DECL(ALC_ALL_ATTRIBUTES
),
309 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
310 DECL(ALC_DEVICE_SPECIFIER
),
311 DECL(ALC_ALL_DEVICES_SPECIFIER
),
312 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
313 DECL(ALC_EXTENSIONS
),
317 DECL(ALC_MONO_SOURCES
),
318 DECL(ALC_STEREO_SOURCES
),
319 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
320 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
321 DECL(ALC_CAPTURE_SAMPLES
),
324 DECL(ALC_EFX_MAJOR_VERSION
),
325 DECL(ALC_EFX_MINOR_VERSION
),
326 DECL(ALC_MAX_AUXILIARY_SENDS
),
328 DECL(ALC_FORMAT_CHANNELS_SOFT
),
329 DECL(ALC_FORMAT_TYPE_SOFT
),
332 DECL(ALC_STEREO_SOFT
),
334 DECL(ALC_5POINT1_SOFT
),
335 DECL(ALC_6POINT1_SOFT
),
336 DECL(ALC_7POINT1_SOFT
),
339 DECL(ALC_UNSIGNED_BYTE_SOFT
),
340 DECL(ALC_SHORT_SOFT
),
341 DECL(ALC_UNSIGNED_SHORT_SOFT
),
343 DECL(ALC_UNSIGNED_INT_SOFT
),
344 DECL(ALC_FLOAT_SOFT
),
347 DECL(ALC_DONT_CARE_SOFT
),
348 DECL(ALC_HRTF_STATUS_SOFT
),
349 DECL(ALC_HRTF_DISABLED_SOFT
),
350 DECL(ALC_HRTF_ENABLED_SOFT
),
351 DECL(ALC_HRTF_DENIED_SOFT
),
352 DECL(ALC_HRTF_REQUIRED_SOFT
),
353 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
354 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
355 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
356 DECL(ALC_HRTF_SPECIFIER_SOFT
),
357 DECL(ALC_HRTF_ID_SOFT
),
360 DECL(ALC_INVALID_DEVICE
),
361 DECL(ALC_INVALID_CONTEXT
),
362 DECL(ALC_INVALID_ENUM
),
363 DECL(ALC_INVALID_VALUE
),
364 DECL(ALC_OUT_OF_MEMORY
),
372 DECL(AL_SOURCE_RELATIVE
),
373 DECL(AL_CONE_INNER_ANGLE
),
374 DECL(AL_CONE_OUTER_ANGLE
),
384 DECL(AL_ORIENTATION
),
385 DECL(AL_REFERENCE_DISTANCE
),
386 DECL(AL_ROLLOFF_FACTOR
),
387 DECL(AL_CONE_OUTER_GAIN
),
388 DECL(AL_MAX_DISTANCE
),
390 DECL(AL_SAMPLE_OFFSET
),
391 DECL(AL_BYTE_OFFSET
),
392 DECL(AL_SOURCE_TYPE
),
395 DECL(AL_UNDETERMINED
),
396 DECL(AL_METERS_PER_UNIT
),
397 DECL(AL_LOOP_POINTS_SOFT
),
398 DECL(AL_DIRECT_CHANNELS_SOFT
),
400 DECL(AL_DIRECT_FILTER
),
401 DECL(AL_AUXILIARY_SEND_FILTER
),
402 DECL(AL_AIR_ABSORPTION_FACTOR
),
403 DECL(AL_ROOM_ROLLOFF_FACTOR
),
404 DECL(AL_CONE_OUTER_GAINHF
),
405 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
406 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
407 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
409 DECL(AL_SOURCE_STATE
),
415 DECL(AL_BUFFERS_QUEUED
),
416 DECL(AL_BUFFERS_PROCESSED
),
418 DECL(AL_FORMAT_MONO8
),
419 DECL(AL_FORMAT_MONO16
),
420 DECL(AL_FORMAT_MONO_FLOAT32
),
421 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
422 DECL(AL_FORMAT_STEREO8
),
423 DECL(AL_FORMAT_STEREO16
),
424 DECL(AL_FORMAT_STEREO_FLOAT32
),
425 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
426 DECL(AL_FORMAT_MONO_IMA4
),
427 DECL(AL_FORMAT_STEREO_IMA4
),
428 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
429 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
430 DECL(AL_FORMAT_QUAD8_LOKI
),
431 DECL(AL_FORMAT_QUAD16_LOKI
),
432 DECL(AL_FORMAT_QUAD8
),
433 DECL(AL_FORMAT_QUAD16
),
434 DECL(AL_FORMAT_QUAD32
),
435 DECL(AL_FORMAT_51CHN8
),
436 DECL(AL_FORMAT_51CHN16
),
437 DECL(AL_FORMAT_51CHN32
),
438 DECL(AL_FORMAT_61CHN8
),
439 DECL(AL_FORMAT_61CHN16
),
440 DECL(AL_FORMAT_61CHN32
),
441 DECL(AL_FORMAT_71CHN8
),
442 DECL(AL_FORMAT_71CHN16
),
443 DECL(AL_FORMAT_71CHN32
),
444 DECL(AL_FORMAT_REAR8
),
445 DECL(AL_FORMAT_REAR16
),
446 DECL(AL_FORMAT_REAR32
),
447 DECL(AL_FORMAT_MONO_MULAW
),
448 DECL(AL_FORMAT_MONO_MULAW_EXT
),
449 DECL(AL_FORMAT_STEREO_MULAW
),
450 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
451 DECL(AL_FORMAT_QUAD_MULAW
),
452 DECL(AL_FORMAT_51CHN_MULAW
),
453 DECL(AL_FORMAT_61CHN_MULAW
),
454 DECL(AL_FORMAT_71CHN_MULAW
),
455 DECL(AL_FORMAT_REAR_MULAW
),
456 DECL(AL_FORMAT_MONO_ALAW_EXT
),
457 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
459 DECL(AL_FORMAT_BFORMAT2D_8
),
460 DECL(AL_FORMAT_BFORMAT2D_16
),
461 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
462 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
463 DECL(AL_FORMAT_BFORMAT3D_8
),
464 DECL(AL_FORMAT_BFORMAT3D_16
),
465 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
466 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
469 DECL(AL_MONO16_SOFT
),
470 DECL(AL_MONO32F_SOFT
),
471 DECL(AL_STEREO8_SOFT
),
472 DECL(AL_STEREO16_SOFT
),
473 DECL(AL_STEREO32F_SOFT
),
475 DECL(AL_QUAD16_SOFT
),
476 DECL(AL_QUAD32F_SOFT
),
478 DECL(AL_REAR16_SOFT
),
479 DECL(AL_REAR32F_SOFT
),
480 DECL(AL_5POINT1_8_SOFT
),
481 DECL(AL_5POINT1_16_SOFT
),
482 DECL(AL_5POINT1_32F_SOFT
),
483 DECL(AL_6POINT1_8_SOFT
),
484 DECL(AL_6POINT1_16_SOFT
),
485 DECL(AL_6POINT1_32F_SOFT
),
486 DECL(AL_7POINT1_8_SOFT
),
487 DECL(AL_7POINT1_16_SOFT
),
488 DECL(AL_7POINT1_32F_SOFT
),
489 DECL(AL_BFORMAT2D_8_SOFT
),
490 DECL(AL_BFORMAT2D_16_SOFT
),
491 DECL(AL_BFORMAT2D_32F_SOFT
),
492 DECL(AL_BFORMAT3D_8_SOFT
),
493 DECL(AL_BFORMAT3D_16_SOFT
),
494 DECL(AL_BFORMAT3D_32F_SOFT
),
497 DECL(AL_STEREO_SOFT
),
500 DECL(AL_5POINT1_SOFT
),
501 DECL(AL_6POINT1_SOFT
),
502 DECL(AL_7POINT1_SOFT
),
503 DECL(AL_BFORMAT2D_SOFT
),
504 DECL(AL_BFORMAT3D_SOFT
),
507 DECL(AL_UNSIGNED_BYTE_SOFT
),
509 DECL(AL_UNSIGNED_SHORT_SOFT
),
511 DECL(AL_UNSIGNED_INT_SOFT
),
513 DECL(AL_DOUBLE_SOFT
),
515 DECL(AL_UNSIGNED_BYTE3_SOFT
),
522 DECL(AL_INTERNAL_FORMAT_SOFT
),
523 DECL(AL_BYTE_LENGTH_SOFT
),
524 DECL(AL_SAMPLE_LENGTH_SOFT
),
525 DECL(AL_SEC_LENGTH_SOFT
),
526 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
527 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
529 DECL(AL_SOURCE_RADIUS
),
531 DECL(AL_STEREO_ANGLES
),
538 DECL(AL_INVALID_NAME
),
539 DECL(AL_INVALID_ENUM
),
540 DECL(AL_INVALID_VALUE
),
541 DECL(AL_INVALID_OPERATION
),
542 DECL(AL_OUT_OF_MEMORY
),
549 DECL(AL_DOPPLER_FACTOR
),
550 DECL(AL_DOPPLER_VELOCITY
),
551 DECL(AL_DISTANCE_MODEL
),
552 DECL(AL_SPEED_OF_SOUND
),
553 DECL(AL_SOURCE_DISTANCE_MODEL
),
554 DECL(AL_DEFERRED_UPDATES_SOFT
),
556 DECL(AL_INVERSE_DISTANCE
),
557 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
558 DECL(AL_LINEAR_DISTANCE
),
559 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
560 DECL(AL_EXPONENT_DISTANCE
),
561 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
563 DECL(AL_FILTER_TYPE
),
564 DECL(AL_FILTER_NULL
),
565 DECL(AL_FILTER_LOWPASS
),
566 DECL(AL_FILTER_HIGHPASS
),
567 DECL(AL_FILTER_BANDPASS
),
569 DECL(AL_LOWPASS_GAIN
),
570 DECL(AL_LOWPASS_GAINHF
),
572 DECL(AL_HIGHPASS_GAIN
),
573 DECL(AL_HIGHPASS_GAINLF
),
575 DECL(AL_BANDPASS_GAIN
),
576 DECL(AL_BANDPASS_GAINHF
),
577 DECL(AL_BANDPASS_GAINLF
),
579 DECL(AL_EFFECT_TYPE
),
580 DECL(AL_EFFECT_NULL
),
581 DECL(AL_EFFECT_REVERB
),
582 DECL(AL_EFFECT_EAXREVERB
),
583 DECL(AL_EFFECT_CHORUS
),
584 DECL(AL_EFFECT_DISTORTION
),
585 DECL(AL_EFFECT_ECHO
),
586 DECL(AL_EFFECT_FLANGER
),
588 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
589 DECL(AL_EFFECT_VOCAL_MORPHER
),
590 DECL(AL_EFFECT_PITCH_SHIFTER
),
592 DECL(AL_EFFECT_RING_MODULATOR
),
594 DECL(AL_EFFECT_AUTOWAH
),
596 DECL(AL_EFFECT_COMPRESSOR
),
597 DECL(AL_EFFECT_EQUALIZER
),
598 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
599 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
601 DECL(AL_EAXREVERB_DENSITY
),
602 DECL(AL_EAXREVERB_DIFFUSION
),
603 DECL(AL_EAXREVERB_GAIN
),
604 DECL(AL_EAXREVERB_GAINHF
),
605 DECL(AL_EAXREVERB_GAINLF
),
606 DECL(AL_EAXREVERB_DECAY_TIME
),
607 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
608 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
609 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
610 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
611 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
612 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
613 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
614 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
615 DECL(AL_EAXREVERB_ECHO_TIME
),
616 DECL(AL_EAXREVERB_ECHO_DEPTH
),
617 DECL(AL_EAXREVERB_MODULATION_TIME
),
618 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
619 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
620 DECL(AL_EAXREVERB_HFREFERENCE
),
621 DECL(AL_EAXREVERB_LFREFERENCE
),
622 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
623 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
625 DECL(AL_REVERB_DENSITY
),
626 DECL(AL_REVERB_DIFFUSION
),
627 DECL(AL_REVERB_GAIN
),
628 DECL(AL_REVERB_GAINHF
),
629 DECL(AL_REVERB_DECAY_TIME
),
630 DECL(AL_REVERB_DECAY_HFRATIO
),
631 DECL(AL_REVERB_REFLECTIONS_GAIN
),
632 DECL(AL_REVERB_REFLECTIONS_DELAY
),
633 DECL(AL_REVERB_LATE_REVERB_GAIN
),
634 DECL(AL_REVERB_LATE_REVERB_DELAY
),
635 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
636 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
637 DECL(AL_REVERB_DECAY_HFLIMIT
),
639 DECL(AL_CHORUS_WAVEFORM
),
640 DECL(AL_CHORUS_PHASE
),
641 DECL(AL_CHORUS_RATE
),
642 DECL(AL_CHORUS_DEPTH
),
643 DECL(AL_CHORUS_FEEDBACK
),
644 DECL(AL_CHORUS_DELAY
),
646 DECL(AL_DISTORTION_EDGE
),
647 DECL(AL_DISTORTION_GAIN
),
648 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
649 DECL(AL_DISTORTION_EQCENTER
),
650 DECL(AL_DISTORTION_EQBANDWIDTH
),
653 DECL(AL_ECHO_LRDELAY
),
654 DECL(AL_ECHO_DAMPING
),
655 DECL(AL_ECHO_FEEDBACK
),
656 DECL(AL_ECHO_SPREAD
),
658 DECL(AL_FLANGER_WAVEFORM
),
659 DECL(AL_FLANGER_PHASE
),
660 DECL(AL_FLANGER_RATE
),
661 DECL(AL_FLANGER_DEPTH
),
662 DECL(AL_FLANGER_FEEDBACK
),
663 DECL(AL_FLANGER_DELAY
),
665 DECL(AL_RING_MODULATOR_FREQUENCY
),
666 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
667 DECL(AL_RING_MODULATOR_WAVEFORM
),
670 DECL(AL_AUTOWAH_ATTACK_TIME
),
671 DECL(AL_AUTOWAH_PEAK_GAIN
),
672 DECL(AL_AUTOWAH_RELEASE_TIME
),
673 DECL(AL_AUTOWAH_RESONANCE
),
676 DECL(AL_COMPRESSOR_ONOFF
),
678 DECL(AL_EQUALIZER_LOW_GAIN
),
679 DECL(AL_EQUALIZER_LOW_CUTOFF
),
680 DECL(AL_EQUALIZER_MID1_GAIN
),
681 DECL(AL_EQUALIZER_MID1_CENTER
),
682 DECL(AL_EQUALIZER_MID1_WIDTH
),
683 DECL(AL_EQUALIZER_MID2_GAIN
),
684 DECL(AL_EQUALIZER_MID2_CENTER
),
685 DECL(AL_EQUALIZER_MID2_WIDTH
),
686 DECL(AL_EQUALIZER_HIGH_GAIN
),
687 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
689 DECL(AL_DEDICATED_GAIN
),
695 static const ALCchar alcNoError
[] = "No Error";
696 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
697 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
698 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
699 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
700 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
703 /************************************************
705 ************************************************/
707 /* Enumerated device names */
708 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
710 static al_string alcAllDevicesList
;
711 static al_string alcCaptureDeviceList
;
713 /* Default is always the first in the list */
714 static ALCchar
*alcDefaultAllDevicesSpecifier
;
715 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
717 /* Default context extensions */
718 static const ALchar alExtList
[] =
719 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
720 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
721 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
722 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
723 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
724 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
725 "AL_SOFT_source_latency AL_SOFT_source_length";
727 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
729 /* Thread-local current context */
730 static altss_t LocalContext
;
731 /* Process-wide current context */
732 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
734 /* Mixing thread piority level */
739 enum LogLevel LogLevel
= LogWarning
;
741 enum LogLevel LogLevel
= LogError
;
744 /* Flag to trap ALC device errors */
745 static ALCboolean TrapALCError
= ALC_FALSE
;
747 /* One-time configuration init control */
748 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
750 /* Default effect that applies to sources that don't have an effect on send 0 */
751 static ALeffect DefaultEffect
;
753 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
756 static ALCboolean SuspendDefers
= ALC_TRUE
;
759 /************************************************
761 ************************************************/
762 static const ALCchar alcNoDeviceExtList
[] =
763 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
764 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
765 static const ALCchar alcExtensionList
[] =
766 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
767 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
768 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
769 "ALC_SOFT_loopback ALC_SOFT_pause_device";
770 static const ALCint alcMajorVersion
= 1;
771 static const ALCint alcMinorVersion
= 1;
773 static const ALCint alcEFXMajorVersion
= 1;
774 static const ALCint alcEFXMinorVersion
= 0;
777 /************************************************
779 ************************************************/
780 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
782 static almtx_t ListLock
;
783 static inline void LockLists(void)
785 int ret
= almtx_lock(&ListLock
);
786 assert(ret
== althrd_success
);
788 static inline void UnlockLists(void)
790 int ret
= almtx_unlock(&ListLock
);
791 assert(ret
== althrd_success
);
794 /************************************************
795 * Library initialization
796 ************************************************/
798 static void alc_init(void);
799 static void alc_deinit(void);
800 static void alc_deinit_safe(void);
802 #ifndef AL_LIBTYPE_STATIC
803 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
807 case DLL_PROCESS_ATTACH
:
808 /* Pin the DLL so we won't get unloaded until the process terminates */
809 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
810 (WCHAR
*)hModule
, &hModule
);
814 case DLL_THREAD_DETACH
:
817 case DLL_PROCESS_DETACH
:
826 #elif defined(_MSC_VER)
827 #pragma section(".CRT$XCU",read)
828 static void alc_constructor(void);
829 static void alc_destructor(void);
830 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
832 static void alc_constructor(void)
834 atexit(alc_destructor
);
838 static void alc_destructor(void)
842 #elif defined(HAVE_GCC_DESTRUCTOR)
843 static void alc_init(void) __attribute__((constructor
));
844 static void alc_deinit(void) __attribute__((destructor
));
846 #error "No static initialization available on this platform!"
849 #elif defined(HAVE_GCC_DESTRUCTOR)
851 static void alc_init(void) __attribute__((constructor
));
852 static void alc_deinit(void) __attribute__((destructor
));
855 #error "No global initialization available on this platform!"
858 static void ReleaseThreadCtx(void *ptr
);
859 static void alc_init(void)
866 AL_STRING_INIT(alcAllDevicesList
);
867 AL_STRING_INIT(alcCaptureDeviceList
);
869 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
870 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
873 str
= getenv("__ALSOFT_REVERSE_Z");
874 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
877 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
878 assert(ret
== althrd_success
);
880 ret
= almtx_init(&ListLock
, almtx_recursive
);
881 assert(ret
== althrd_success
);
886 static void alc_initconfig(void)
888 const char *devs
, *str
;
893 str
= getenv("ALSOFT_LOGLEVEL");
896 long lvl
= strtol(str
, NULL
, 0);
897 if(lvl
>= NoLog
&& lvl
<= LogRef
)
901 str
= getenv("ALSOFT_LOGFILE");
904 FILE *logfile
= al_fopen(str
, "wt");
905 if(logfile
) LogFile
= logfile
;
906 else ERR("Failed to open log file '%s'\n", str
);
911 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
912 for(i
= 1;BackendList
[i
].name
;i
++)
913 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
914 TRACE("Supported backends: %s\n", buf
);
918 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
921 if(strcasecmp(str
, "ignore") == 0)
923 SuspendDefers
= ALC_FALSE
;
924 TRACE("Selected context suspend behavior, \"ignore\"\n");
927 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
931 #if defined(HAVE_SSE4_1)
932 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
933 #elif defined(HAVE_SSE3)
934 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
935 #elif defined(HAVE_SSE2)
936 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
937 #elif defined(HAVE_SSE)
938 capfilter
|= CPU_CAP_SSE
;
941 capfilter
|= CPU_CAP_NEON
;
943 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
945 if(strcasecmp(str
, "all") == 0)
950 const char *next
= str
;
954 while(isspace(str
[0]))
956 next
= strchr(str
, ',');
958 if(!str
[0] || str
[0] == ',')
961 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
962 while(len
> 0 && isspace(str
[len
-1]))
964 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
965 capfilter
&= ~CPU_CAP_SSE
;
966 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
967 capfilter
&= ~CPU_CAP_SSE2
;
968 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
969 capfilter
&= ~CPU_CAP_SSE3
;
970 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
971 capfilter
&= ~CPU_CAP_SSE4_1
;
972 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
973 capfilter
&= ~CPU_CAP_NEON
;
975 WARN("Invalid CPU extension \"%s\"\n", str
);
979 FillCPUCaps(capfilter
);
986 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
990 str
= getenv("ALSOFT_TRAP_ERROR");
991 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
993 TrapALError
= AL_TRUE
;
994 TrapALCError
= AL_TRUE
;
998 str
= getenv("ALSOFT_TRAP_AL_ERROR");
999 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1000 TrapALError
= AL_TRUE
;
1001 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
1003 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
1004 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
1005 TrapALCError
= ALC_TRUE
;
1006 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1009 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1010 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1012 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1014 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1015 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1019 const char *next
= devs
;
1020 int endlist
, delitem
;
1025 while(isspace(devs
[0]))
1027 next
= strchr(devs
, ',');
1029 delitem
= (devs
[0] == '-');
1030 if(devs
[0] == '-') devs
++;
1032 if(!devs
[0] || devs
[0] == ',')
1039 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1040 while(len
> 0 && isspace(devs
[len
-1]))
1042 for(n
= i
;BackendList
[n
].name
;n
++)
1044 if(len
== strlen(BackendList
[n
].name
) &&
1045 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1050 BackendList
[n
] = BackendList
[n
+1];
1052 } while(BackendList
[n
].name
);
1056 struct BackendInfo Bkp
= BackendList
[n
];
1059 BackendList
[n
] = BackendList
[n
-1];
1062 BackendList
[n
] = Bkp
;
1073 BackendList
[i
].name
= NULL
;
1074 BackendList
[i
].getFactory
= NULL
;
1075 BackendList
[i
].Init
= NULL
;
1076 BackendList
[i
].Deinit
= NULL
;
1077 BackendList
[i
].Probe
= NULL
;
1081 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1083 if(BackendList
[i
].getFactory
)
1085 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1086 if(!V0(factory
,init
)())
1088 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1092 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1093 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1095 PlaybackBackend
= BackendList
[i
];
1096 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1098 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1100 CaptureBackend
= BackendList
[i
];
1101 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1107 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1109 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1113 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1114 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1116 PlaybackBackend
= BackendList
[i
];
1117 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1119 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1121 CaptureBackend
= BackendList
[i
];
1122 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1126 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1130 if(!PlaybackBackend
.name
)
1131 WARN("No playback backend available!\n");
1132 if(!CaptureBackend
.name
)
1133 WARN("No capture backend available!\n");
1135 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1138 const char *next
= str
;
1142 next
= strchr(str
, ',');
1144 if(!str
[0] || next
== str
)
1147 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1148 for(n
= 0;EffectList
[n
].name
;n
++)
1150 if(len
== strlen(EffectList
[n
].name
) &&
1151 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1152 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1157 InitEffectFactoryMap();
1159 InitEffect(&DefaultEffect
);
1160 str
= getenv("ALSOFT_DEFAULT_REVERB");
1161 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1162 LoadReverbPreset(str
, &DefaultEffect
);
1164 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1167 /************************************************
1168 * Library deinitialization
1169 ************************************************/
1170 static void alc_cleanup(void)
1174 AL_STRING_DEINIT(alcAllDevicesList
);
1175 AL_STRING_DEINIT(alcCaptureDeviceList
);
1177 free(alcDefaultAllDevicesSpecifier
);
1178 alcDefaultAllDevicesSpecifier
= NULL
;
1179 free(alcCaptureDefaultDeviceSpecifier
);
1180 alcCaptureDefaultDeviceSpecifier
= NULL
;
1182 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1187 } while((dev
=dev
->next
) != NULL
);
1188 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1191 DeinitEffectFactoryMap();
1194 static void alc_deinit_safe(void)
1202 almtx_destroy(&ListLock
);
1203 altss_delete(LocalContext
);
1205 if(LogFile
!= stderr
)
1210 static void alc_deinit(void)
1216 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1217 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1219 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1221 if(!BackendList
[i
].getFactory
)
1222 BackendList
[i
].Deinit();
1225 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1226 V0(factory
,deinit
)();
1230 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1231 V0(factory
,deinit
)();
1238 /************************************************
1239 * Device enumeration
1240 ************************************************/
1241 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1246 al_string_clear(list
);
1248 if(backendinfo
->Probe
)
1249 backendinfo
->Probe(type
);
1250 else if(backendinfo
->getFactory
)
1252 ALCbackendFactory
*factory
= backendinfo
->getFactory();
1253 V(factory
,probe
)(type
);
1258 static void ProbeAllDevicesList(void)
1259 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1260 static void ProbeCaptureDeviceList(void)
1261 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1263 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1265 size_t len
= strlen(name
);
1267 al_string_append_range(devnames
, name
, name
+len
+1);
1269 void AppendAllDevicesList(const ALCchar
*name
)
1270 { AppendDevice(name
, &alcAllDevicesList
); }
1271 void AppendCaptureDeviceList(const ALCchar
*name
)
1272 { AppendDevice(name
, &alcCaptureDeviceList
); }
1275 /************************************************
1276 * Device format information
1277 ************************************************/
1278 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1282 case DevFmtByte
: return "Signed Byte";
1283 case DevFmtUByte
: return "Unsigned Byte";
1284 case DevFmtShort
: return "Signed Short";
1285 case DevFmtUShort
: return "Unsigned Short";
1286 case DevFmtInt
: return "Signed Int";
1287 case DevFmtUInt
: return "Unsigned Int";
1288 case DevFmtFloat
: return "Float";
1290 return "(unknown type)";
1292 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1296 case DevFmtMono
: return "Mono";
1297 case DevFmtStereo
: return "Stereo";
1298 case DevFmtQuad
: return "Quadraphonic";
1299 case DevFmtX51
: return "5.1 Surround";
1300 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1301 case DevFmtX61
: return "6.1 Surround";
1302 case DevFmtX71
: return "7.1 Surround";
1303 case DevFmtBFormat3D
: return "B-Format 3D";
1305 return "(unknown channels)";
1308 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1309 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1313 case DevFmtByte
: return sizeof(ALbyte
);
1314 case DevFmtUByte
: return sizeof(ALubyte
);
1315 case DevFmtShort
: return sizeof(ALshort
);
1316 case DevFmtUShort
: return sizeof(ALushort
);
1317 case DevFmtInt
: return sizeof(ALint
);
1318 case DevFmtUInt
: return sizeof(ALuint
);
1319 case DevFmtFloat
: return sizeof(ALfloat
);
1323 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1327 case DevFmtMono
: return 1;
1328 case DevFmtStereo
: return 2;
1329 case DevFmtQuad
: return 4;
1330 case DevFmtX51
: return 6;
1331 case DevFmtX51Rear
: return 6;
1332 case DevFmtX61
: return 7;
1333 case DevFmtX71
: return 8;
1334 case DevFmtBFormat3D
: return 4;
1339 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1340 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1342 static const struct {
1344 enum DevFmtChannels channels
;
1345 enum DevFmtType type
;
1347 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1348 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1349 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1351 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1352 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1353 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1355 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1356 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1357 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1359 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1360 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1361 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1363 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1364 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1365 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1367 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1368 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1369 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1373 for(i
= 0;i
< COUNTOF(list
);i
++)
1375 if(list
[i
].format
== format
)
1377 *chans
= list
[i
].channels
;
1378 *type
= list
[i
].type
;
1386 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1391 case ALC_UNSIGNED_BYTE_SOFT
:
1392 case ALC_SHORT_SOFT
:
1393 case ALC_UNSIGNED_SHORT_SOFT
:
1395 case ALC_UNSIGNED_INT_SOFT
:
1396 case ALC_FLOAT_SOFT
:
1402 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1407 case ALC_STEREO_SOFT
:
1409 case ALC_5POINT1_SOFT
:
1410 case ALC_6POINT1_SOFT
:
1411 case ALC_7POINT1_SOFT
:
1418 /************************************************
1419 * Miscellaneous ALC helpers
1420 ************************************************/
1422 extern inline void LockContext(ALCcontext
*context
);
1423 extern inline void UnlockContext(ALCcontext
*context
);
1425 void ALCdevice_Lock(ALCdevice
*device
)
1427 V0(device
->Backend
,lock
)();
1430 void ALCdevice_Unlock(ALCdevice
*device
)
1432 V0(device
->Backend
,unlock
)();
1436 /* SetDefaultWFXChannelOrder
1438 * Sets the default channel order used by WaveFormatEx.
1440 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1444 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1445 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1447 switch(device
->FmtChans
)
1450 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1453 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1454 device
->RealOut
.ChannelName
[1] = FrontRight
;
1457 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1458 device
->RealOut
.ChannelName
[1] = FrontRight
;
1459 device
->RealOut
.ChannelName
[2] = BackLeft
;
1460 device
->RealOut
.ChannelName
[3] = BackRight
;
1463 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1464 device
->RealOut
.ChannelName
[1] = FrontRight
;
1465 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1466 device
->RealOut
.ChannelName
[3] = LFE
;
1467 device
->RealOut
.ChannelName
[4] = SideLeft
;
1468 device
->RealOut
.ChannelName
[5] = SideRight
;
1471 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1472 device
->RealOut
.ChannelName
[1] = FrontRight
;
1473 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1474 device
->RealOut
.ChannelName
[3] = LFE
;
1475 device
->RealOut
.ChannelName
[4] = BackLeft
;
1476 device
->RealOut
.ChannelName
[5] = BackRight
;
1479 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1480 device
->RealOut
.ChannelName
[1] = FrontRight
;
1481 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1482 device
->RealOut
.ChannelName
[3] = LFE
;
1483 device
->RealOut
.ChannelName
[4] = BackCenter
;
1484 device
->RealOut
.ChannelName
[5] = SideLeft
;
1485 device
->RealOut
.ChannelName
[6] = SideRight
;
1488 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1489 device
->RealOut
.ChannelName
[1] = FrontRight
;
1490 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1491 device
->RealOut
.ChannelName
[3] = LFE
;
1492 device
->RealOut
.ChannelName
[4] = BackLeft
;
1493 device
->RealOut
.ChannelName
[5] = BackRight
;
1494 device
->RealOut
.ChannelName
[6] = SideLeft
;
1495 device
->RealOut
.ChannelName
[7] = SideRight
;
1497 case DevFmtBFormat3D
:
1498 device
->RealOut
.ChannelName
[0] = Aux0
;
1499 device
->RealOut
.ChannelName
[1] = Aux1
;
1500 device
->RealOut
.ChannelName
[2] = Aux2
;
1501 device
->RealOut
.ChannelName
[3] = Aux3
;
1506 /* SetDefaultChannelOrder
1508 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1510 void SetDefaultChannelOrder(ALCdevice
*device
)
1514 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1515 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1517 switch(device
->FmtChans
)
1520 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1521 device
->RealOut
.ChannelName
[1] = FrontRight
;
1522 device
->RealOut
.ChannelName
[2] = BackLeft
;
1523 device
->RealOut
.ChannelName
[3] = BackRight
;
1524 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1525 device
->RealOut
.ChannelName
[5] = LFE
;
1528 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1529 device
->RealOut
.ChannelName
[1] = FrontRight
;
1530 device
->RealOut
.ChannelName
[2] = BackLeft
;
1531 device
->RealOut
.ChannelName
[3] = BackRight
;
1532 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1533 device
->RealOut
.ChannelName
[5] = LFE
;
1534 device
->RealOut
.ChannelName
[6] = SideLeft
;
1535 device
->RealOut
.ChannelName
[7] = SideRight
;
1538 /* Same as WFX order */
1544 case DevFmtBFormat3D
:
1545 SetDefaultWFXChannelOrder(device
);
1550 extern inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
);
1553 /* ALCcontext_DeferUpdates
1555 * Defers/suspends updates for the given context's listener and sources. This
1556 * does *NOT* stop mixing, but rather prevents certain property changes from
1559 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1561 ATOMIC_STORE(&context
->DeferUpdates
, AL_TRUE
);
1564 /* ALCcontext_ProcessUpdates
1566 * Resumes update processing after being deferred.
1568 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1570 ALCdevice
*device
= context
->Device
;
1572 ReadLock(&context
->PropLock
);
1573 if(ATOMIC_EXCHANGE(ALenum
, &context
->DeferUpdates
, AL_FALSE
))
1577 UpdateListenerProps(context
);
1579 LockUIntMapRead(&context
->SourceMap
);
1580 V0(device
->Backend
,lock
)();
1581 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1583 ALsource
*Source
= context
->SourceMap
.values
[pos
];
1586 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1587 Source
->OffsetType
!= AL_NONE
)
1589 WriteLock(&Source
->queue_lock
);
1590 ApplyOffset(Source
);
1591 WriteUnlock(&Source
->queue_lock
);
1594 new_state
= Source
->new_state
;
1595 Source
->new_state
= AL_NONE
;
1597 SetSourceState(Source
, context
, new_state
);
1599 V0(device
->Backend
,unlock
)();
1600 UnlockUIntMapRead(&context
->SourceMap
);
1601 UpdateAllSourceProps(context
);
1603 ReadUnlock(&context
->PropLock
);
1609 * Stores the latest ALC device error
1611 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1616 /* DebugBreak() will cause an exception if there is no debugger */
1617 if(IsDebuggerPresent())
1619 #elif defined(SIGTRAP)
1625 ATOMIC_STORE(&device
->LastError
, errorCode
);
1627 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1633 * Updates the device's base clock time with however many samples have been
1634 * done. This is used so frequency changes on the device don't cause the time
1635 * to jump forward or back.
1637 static inline void UpdateClockBase(ALCdevice
*device
)
1639 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1640 device
->SamplesDone
= 0;
1643 /* UpdateDeviceParams
1645 * Updates device parameters according to the attribute list (caller is
1646 * responsible for holding the list lock).
1648 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1650 ALCcontext
*context
;
1651 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1652 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1653 enum DevFmtChannels oldChans
;
1654 enum DevFmtType oldType
;
1657 ALCsizei hrtf_id
= -1;
1660 // Check for attributes
1661 if(device
->Type
== Loopback
)
1667 GotAll
= GotFreq
|GotChans
|GotType
1669 ALCuint freq
, numMono
, numStereo
, numSends
;
1670 enum DevFmtChannels schans
;
1671 enum DevFmtType stype
;
1672 ALCuint attrIdx
= 0;
1677 WARN("Missing attributes for loopback device\n");
1678 return ALC_INVALID_VALUE
;
1681 numMono
= device
->NumMonoSources
;
1682 numStereo
= device
->NumStereoSources
;
1683 numSends
= device
->NumAuxSends
;
1684 schans
= device
->FmtChans
;
1685 stype
= device
->FmtType
;
1686 freq
= device
->Frequency
;
1688 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1689 while(attrList
[attrIdx
])
1691 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1693 ALCint val
= attrList
[attrIdx
+ 1];
1694 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT
, val
);
1695 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1696 return ALC_INVALID_VALUE
;
1701 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1703 ALCint val
= attrList
[attrIdx
+ 1];
1704 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT
, val
);
1705 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1706 return ALC_INVALID_VALUE
;
1711 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1713 freq
= attrList
[attrIdx
+ 1];
1714 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1715 if(freq
< MIN_OUTPUT_RATE
)
1716 return ALC_INVALID_VALUE
;
1720 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1722 numStereo
= attrList
[attrIdx
+ 1];
1723 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1724 if(numStereo
> device
->SourcesMax
)
1725 numStereo
= device
->SourcesMax
;
1727 numMono
= device
->SourcesMax
- numStereo
;
1730 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1732 numSends
= attrList
[attrIdx
+ 1];
1733 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1736 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1738 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1739 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1740 hrtf_appreq
= Hrtf_Disable
;
1741 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1742 hrtf_appreq
= Hrtf_Enable
;
1744 hrtf_appreq
= Hrtf_Default
;
1747 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1749 hrtf_id
= attrList
[attrIdx
+ 1];
1750 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1757 if(gotFmt
!= GotAll
)
1759 WARN("Missing format for loopback device\n");
1760 return ALC_INVALID_VALUE
;
1763 ConfigValueUInt(NULL
, NULL
, "sends", &numSends
);
1764 numSends
= minu(MAX_SENDS
, numSends
);
1766 if((device
->Flags
&DEVICE_RUNNING
))
1767 V0(device
->Backend
,stop
)();
1768 device
->Flags
&= ~DEVICE_RUNNING
;
1770 UpdateClockBase(device
);
1772 device
->Frequency
= freq
;
1773 device
->FmtChans
= schans
;
1774 device
->FmtType
= stype
;
1775 device
->NumMonoSources
= numMono
;
1776 device
->NumStereoSources
= numStereo
;
1777 device
->NumAuxSends
= numSends
;
1779 else if(attrList
&& attrList
[0])
1781 ALCuint freq
, numMono
, numStereo
, numSends
;
1782 ALCuint attrIdx
= 0;
1784 /* If a context is already running on the device, stop playback so the
1785 * device attributes can be updated. */
1786 if((device
->Flags
&DEVICE_RUNNING
))
1787 V0(device
->Backend
,stop
)();
1788 device
->Flags
&= ~DEVICE_RUNNING
;
1790 freq
= device
->Frequency
;
1791 numMono
= device
->NumMonoSources
;
1792 numStereo
= device
->NumStereoSources
;
1793 numSends
= device
->NumAuxSends
;
1795 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1796 while(attrList
[attrIdx
])
1798 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1800 freq
= attrList
[attrIdx
+ 1];
1801 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1802 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1805 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1807 numStereo
= attrList
[attrIdx
+ 1];
1808 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1809 if(numStereo
> device
->SourcesMax
)
1810 numStereo
= device
->SourcesMax
;
1812 numMono
= device
->SourcesMax
- numStereo
;
1815 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1817 numSends
= attrList
[attrIdx
+ 1];
1818 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1821 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1823 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1824 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1825 hrtf_appreq
= Hrtf_Disable
;
1826 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1827 hrtf_appreq
= Hrtf_Enable
;
1829 hrtf_appreq
= Hrtf_Default
;
1832 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1834 hrtf_id
= attrList
[attrIdx
+ 1];
1835 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1842 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1843 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1845 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1846 numSends
= minu(MAX_SENDS
, numSends
);
1848 UpdateClockBase(device
);
1850 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1852 /* SSE and Neon do best with the update size being a multiple of 4 */
1853 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1854 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1856 device
->Frequency
= freq
;
1857 device
->NumMonoSources
= numMono
;
1858 device
->NumStereoSources
= numStereo
;
1859 device
->NumAuxSends
= numSends
;
1862 if((device
->Flags
&DEVICE_RUNNING
))
1863 return ALC_NO_ERROR
;
1865 al_free(device
->Uhj_Encoder
);
1866 device
->Uhj_Encoder
= NULL
;
1868 al_free(device
->Bs2b
);
1869 device
->Bs2b
= NULL
;
1871 al_free(device
->Dry
.Buffer
);
1872 device
->Dry
.Buffer
= NULL
;
1873 device
->Dry
.NumChannels
= 0;
1874 device
->FOAOut
.Buffer
= NULL
;
1875 device
->FOAOut
.NumChannels
= 0;
1876 device
->RealOut
.Buffer
= NULL
;
1877 device
->RealOut
.NumChannels
= 0;
1879 UpdateClockBase(device
);
1881 /*************************************************************************
1882 * Update device format request if HRTF is requested
1884 device
->Hrtf_Status
= ALC_HRTF_DISABLED_SOFT
;
1885 if(device
->Type
!= Loopback
)
1888 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
1890 if(strcasecmp(hrtf
, "true") == 0)
1891 hrtf_userreq
= Hrtf_Enable
;
1892 else if(strcasecmp(hrtf
, "false") == 0)
1893 hrtf_userreq
= Hrtf_Disable
;
1894 else if(strcasecmp(hrtf
, "auto") != 0)
1895 ERR("Unexpected hrtf value: %s\n", hrtf
);
1898 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
1900 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1902 VECTOR_DEINIT(device
->Hrtf_List
);
1903 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1905 if(VECTOR_SIZE(device
->Hrtf_List
) > 0)
1907 device
->FmtChans
= DevFmtStereo
;
1908 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
1909 device
->Frequency
= VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
).hrtf
->sampleRate
;
1911 device
->Frequency
= VECTOR_ELEM(device
->Hrtf_List
, 0).hrtf
->sampleRate
;
1912 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
1916 hrtf_userreq
= Hrtf_Default
;
1917 hrtf_appreq
= Hrtf_Disable
;
1918 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1922 else if(hrtf_appreq
== Hrtf_Enable
)
1924 size_t i
= VECTOR_SIZE(device
->Hrtf_List
);
1925 /* Loopback device. We don't need to match to a specific HRTF entry
1926 * here. If the requested ID matches, we'll pick that later, if not,
1927 * we'll try to auto-select one anyway. Just make sure one exists
1930 if(device
->FmtChans
== DevFmtStereo
)
1932 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1934 VECTOR_DEINIT(device
->Hrtf_List
);
1935 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1937 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
1939 const struct Hrtf
*hrtf
= VECTOR_ELEM(device
->Hrtf_List
, i
).hrtf
;
1940 if(hrtf
->sampleRate
== device
->Frequency
)
1944 if(i
== VECTOR_SIZE(device
->Hrtf_List
))
1946 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1947 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1948 hrtf_appreq
= Hrtf_Disable
;
1949 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1953 oldFreq
= device
->Frequency
;
1954 oldChans
= device
->FmtChans
;
1955 oldType
= device
->FmtType
;
1957 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1958 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1959 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1960 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1961 device
->UpdateSize
, device
->NumUpdates
1964 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1965 return ALC_INVALID_DEVICE
;
1967 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1969 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1970 DevFmtChannelsString(device
->FmtChans
));
1971 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1973 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1975 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1976 DevFmtTypeString(device
->FmtType
));
1977 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1979 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1981 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1982 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1985 if((device
->UpdateSize
&3) != 0)
1987 if((CPUCapFlags
&CPU_CAP_SSE
))
1988 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1989 if((CPUCapFlags
&CPU_CAP_NEON
))
1990 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1993 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1994 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1995 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1998 aluInitRenderer(device
, hrtf_id
, hrtf_appreq
, hrtf_userreq
);
2000 /* Allocate extra channels for any post-filter output. */
2001 size
= device
->Dry
.NumChannels
* sizeof(device
->Dry
.Buffer
[0]);
2002 if(device
->AmbiDecoder
&& bformatdec_getOrder(device
->AmbiDecoder
) >= 2)
2003 size
+= (ChannelsFromDevFmt(device
->FmtChans
)+4) * sizeof(device
->Dry
.Buffer
[0]);
2004 else if(device
->Hrtf
|| device
->Uhj_Encoder
|| device
->AmbiDecoder
)
2005 size
+= ChannelsFromDevFmt(device
->FmtChans
) * sizeof(device
->Dry
.Buffer
[0]);
2006 device
->Dry
.Buffer
= al_calloc(16, size
);
2007 if(!device
->Dry
.Buffer
)
2009 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2010 return ALC_INVALID_DEVICE
;
2013 if(device
->Hrtf
|| device
->Uhj_Encoder
|| device
->AmbiDecoder
)
2015 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2016 device
->RealOut
.NumChannels
= ChannelsFromDevFmt(device
->FmtChans
);
2020 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2021 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2024 if(device
->AmbiDecoder
&& bformatdec_getOrder(device
->AmbiDecoder
) >= 2)
2026 /* Higher-order high quality decoding requires upsampling first-order
2027 * content, so make sure to mix it separately.
2029 device
->FOAOut
.Buffer
= device
->RealOut
.Buffer
+ device
->RealOut
.NumChannels
;
2030 device
->FOAOut
.NumChannels
= 4;
2034 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
;
2035 device
->FOAOut
.NumChannels
= device
->Dry
.NumChannels
;
2038 SetMixerFPUMode(&oldMode
);
2039 if(device
->DefaultSlot
)
2041 ALeffectslot
*slot
= device
->DefaultSlot
;
2042 ALeffectState
*state
= slot
->Effect
.State
;
2044 state
->OutBuffer
= device
->Dry
.Buffer
;
2045 state
->OutChannels
= device
->Dry
.NumChannels
;
2046 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2048 RestoreFPUMode(&oldMode
);
2049 return ALC_INVALID_DEVICE
;
2051 UpdateEffectSlotProps(slot
);
2054 context
= ATOMIC_LOAD(&device
->ContextList
);
2059 ReadLock(&context
->PropLock
);
2060 LockUIntMapRead(&context
->EffectSlotMap
);
2061 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2063 ALeffectslot
*slot
= context
->EffectSlotMap
.values
[pos
];
2064 ALeffectState
*state
= slot
->Effect
.State
;
2066 state
->OutBuffer
= device
->Dry
.Buffer
;
2067 state
->OutChannels
= device
->Dry
.NumChannels
;
2068 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2070 UnlockUIntMapRead(&context
->EffectSlotMap
);
2071 ReadUnlock(&context
->PropLock
);
2072 RestoreFPUMode(&oldMode
);
2073 return ALC_INVALID_DEVICE
;
2076 UpdateEffectSlotProps(slot
);
2078 UnlockUIntMapRead(&context
->EffectSlotMap
);
2080 LockUIntMapRead(&context
->SourceMap
);
2081 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2083 ALsource
*source
= context
->SourceMap
.values
[pos
];
2084 ALuint s
= device
->NumAuxSends
;
2085 while(s
< MAX_SENDS
)
2087 if(source
->Send
[s
].Slot
)
2088 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2089 source
->Send
[s
].Slot
= NULL
;
2090 source
->Send
[s
].Gain
= 1.0f
;
2091 source
->Send
[s
].GainHF
= 1.0f
;
2092 source
->Send
[s
].HFReference
= LOWPASSFREQREF
;
2093 source
->Send
[s
].GainLF
= 1.0f
;
2094 source
->Send
[s
].LFReference
= HIGHPASSFREQREF
;
2098 UnlockUIntMapRead(&context
->SourceMap
);
2100 UpdateAllSourceProps(context
);
2101 ReadUnlock(&context
->PropLock
);
2103 context
= context
->next
;
2105 RestoreFPUMode(&oldMode
);
2107 if(!(device
->Flags
&DEVICE_PAUSED
))
2109 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2110 return ALC_INVALID_DEVICE
;
2111 device
->Flags
|= DEVICE_RUNNING
;
2114 return ALC_NO_ERROR
;
2119 * Frees the device structure, and destroys any objects the app failed to
2120 * delete. Called once there's no more references on the device.
2122 static ALCvoid
FreeDevice(ALCdevice
*device
)
2124 TRACE("%p\n", device
);
2126 V0(device
->Backend
,close
)();
2127 DELETE_OBJ(device
->Backend
);
2128 device
->Backend
= NULL
;
2130 almtx_destroy(&device
->BackendLock
);
2132 if(device
->DefaultSlot
)
2134 DeinitEffectSlot(device
->DefaultSlot
);
2135 device
->DefaultSlot
= NULL
;
2138 if(device
->BufferMap
.size
> 0)
2140 WARN("(%p) Deleting %d Buffer%s\n", device
, device
->BufferMap
.size
,
2141 (device
->BufferMap
.size
==1)?"":"s");
2142 ReleaseALBuffers(device
);
2144 ResetUIntMap(&device
->BufferMap
);
2146 if(device
->EffectMap
.size
> 0)
2148 WARN("(%p) Deleting %d Effect%s\n", device
, device
->EffectMap
.size
,
2149 (device
->EffectMap
.size
==1)?"":"s");
2150 ReleaseALEffects(device
);
2152 ResetUIntMap(&device
->EffectMap
);
2154 if(device
->FilterMap
.size
> 0)
2156 WARN("(%p) Deleting %d Filter%s\n", device
, device
->FilterMap
.size
,
2157 (device
->FilterMap
.size
==1)?"":"s");
2158 ReleaseALFilters(device
);
2160 ResetUIntMap(&device
->FilterMap
);
2162 AL_STRING_DEINIT(device
->Hrtf_Name
);
2163 FreeHrtfList(&device
->Hrtf_List
);
2165 al_free(device
->Bs2b
);
2166 device
->Bs2b
= NULL
;
2168 al_free(device
->Uhj_Encoder
);
2169 device
->Uhj_Encoder
= NULL
;
2171 bformatdec_free(device
->AmbiDecoder
);
2172 device
->AmbiDecoder
= NULL
;
2174 AL_STRING_DEINIT(device
->DeviceName
);
2176 al_free(device
->Dry
.Buffer
);
2177 device
->Dry
.Buffer
= NULL
;
2178 device
->Dry
.NumChannels
= 0;
2179 device
->FOAOut
.Buffer
= NULL
;
2180 device
->FOAOut
.NumChannels
= 0;
2181 device
->RealOut
.Buffer
= NULL
;
2182 device
->RealOut
.NumChannels
= 0;
2188 void ALCdevice_IncRef(ALCdevice
*device
)
2191 ref
= IncrementRef(&device
->ref
);
2192 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2195 void ALCdevice_DecRef(ALCdevice
*device
)
2198 ref
= DecrementRef(&device
->ref
);
2199 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2200 if(ref
== 0) FreeDevice(device
);
2205 * Checks if the device handle is valid, and increments its ref count if so.
2207 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2209 ALCdevice
*tmpDevice
;
2212 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2215 if(tmpDevice
== *device
)
2217 ALCdevice_IncRef(tmpDevice
);
2221 tmpDevice
= tmpDevice
->next
;
2232 * Initializes context fields
2234 static ALvoid
InitContext(ALCcontext
*Context
)
2236 ALlistener
*listener
= Context
->Listener
;
2238 //Initialise listener
2239 listener
->Gain
= 1.0f
;
2240 listener
->MetersPerUnit
= 1.0f
;
2241 listener
->Position
[0] = 0.0f
;
2242 listener
->Position
[1] = 0.0f
;
2243 listener
->Position
[2] = 0.0f
;
2244 listener
->Velocity
[0] = 0.0f
;
2245 listener
->Velocity
[1] = 0.0f
;
2246 listener
->Velocity
[2] = 0.0f
;
2247 listener
->Forward
[0] = 0.0f
;
2248 listener
->Forward
[1] = 0.0f
;
2249 listener
->Forward
[2] = -1.0f
;
2250 listener
->Up
[0] = 0.0f
;
2251 listener
->Up
[1] = 1.0f
;
2252 listener
->Up
[2] = 0.0f
;
2254 aluMatrixfSet(&listener
->Params
.Matrix
,
2255 1.0f
, 0.0f
, 0.0f
, 0.0f
,
2256 0.0f
, 1.0f
, 0.0f
, 0.0f
,
2257 0.0f
, 0.0f
, 1.0f
, 0.0f
,
2258 0.0f
, 0.0f
, 0.0f
, 1.0f
2260 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2261 listener
->Params
.Gain
= 1.0f
;
2262 listener
->Params
.MetersPerUnit
= 1.0f
;
2263 listener
->Params
.DopplerFactor
= 1.0f
;
2264 listener
->Params
.SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2266 ATOMIC_INIT(&listener
->Update
, NULL
);
2267 ATOMIC_INIT(&listener
->FreeList
, NULL
);
2270 InitRef(&Context
->UpdateCount
, 0);
2271 ATOMIC_INIT(&Context
->HoldUpdates
, AL_FALSE
);
2272 RWLockInit(&Context
->PropLock
);
2273 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2274 InitUIntMap(&Context
->SourceMap
, Context
->Device
->SourcesMax
);
2275 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2278 Context
->DistanceModel
= DefaultDistanceModel
;
2279 Context
->SourceDistanceModel
= AL_FALSE
;
2280 Context
->DopplerFactor
= 1.0f
;
2281 Context
->DopplerVelocity
= 1.0f
;
2282 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2283 ATOMIC_INIT(&Context
->DeferUpdates
, AL_FALSE
);
2285 Context
->ExtensionList
= alExtList
;
2291 * Cleans up the context, and destroys any remaining objects the app failed to
2292 * delete. Called once there's no more references on the context.
2294 static void FreeContext(ALCcontext
*context
)
2296 ALlistener
*listener
= context
->Listener
;
2297 struct ALlistenerProps
*lprops
;
2300 TRACE("%p\n", context
);
2302 if(context
->SourceMap
.size
> 0)
2304 WARN("(%p) Deleting %d Source%s\n", context
, context
->SourceMap
.size
,
2305 (context
->SourceMap
.size
==1)?"":"s");
2306 ReleaseALSources(context
);
2308 ResetUIntMap(&context
->SourceMap
);
2310 if(context
->EffectSlotMap
.size
> 0)
2312 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context
, context
->EffectSlotMap
.size
,
2313 (context
->EffectSlotMap
.size
==1)?"":"s");
2314 ReleaseALAuxiliaryEffectSlots(context
);
2316 ResetUIntMap(&context
->EffectSlotMap
);
2318 al_free(context
->Voices
);
2319 context
->Voices
= NULL
;
2320 context
->VoiceCount
= 0;
2321 context
->MaxVoices
= 0;
2323 if((lprops
=ATOMIC_LOAD(&listener
->Update
, almemory_order_acquire
)) != NULL
)
2325 TRACE("Freed unapplied listener update %p\n", lprops
);
2329 lprops
= ATOMIC_LOAD(&listener
->FreeList
, almemory_order_consume
);
2332 struct ALlistenerProps
*next
= ATOMIC_LOAD(&lprops
->next
, almemory_order_consume
);
2337 TRACE("Freed "SZFMT
" listener property object%s\n", count
, (count
==1)?"":"s");
2339 ALCdevice_DecRef(context
->Device
);
2340 context
->Device
= NULL
;
2342 //Invalidate context
2343 memset(context
, 0, sizeof(ALCcontext
));
2349 * Removes the context reference from the given device and removes it from
2350 * being current on the running thread or globally.
2352 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2354 ALCcontext
*nextctx
;
2355 ALCcontext
*origctx
;
2357 if(altss_get(LocalContext
) == context
)
2359 WARN("%p released while current on thread\n", context
);
2360 altss_set(LocalContext
, NULL
);
2361 ALCcontext_DecRef(context
);
2365 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2366 ALCcontext_DecRef(context
);
2368 ALCdevice_Lock(device
);
2370 nextctx
= context
->next
;
2371 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2377 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2379 ALCdevice_Unlock(device
);
2381 ALCcontext_DecRef(context
);
2384 void ALCcontext_IncRef(ALCcontext
*context
)
2387 ref
= IncrementRef(&context
->ref
);
2388 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2391 void ALCcontext_DecRef(ALCcontext
*context
)
2394 ref
= DecrementRef(&context
->ref
);
2395 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2396 if(ref
== 0) FreeContext(context
);
2399 static void ReleaseThreadCtx(void *ptr
)
2401 WARN("%p current for thread being destroyed\n", ptr
);
2402 ALCcontext_DecRef(ptr
);
2407 * Checks that the given context is valid, and increments its reference count.
2409 static ALCboolean
VerifyContext(ALCcontext
**context
)
2414 dev
= ATOMIC_LOAD(&DeviceList
);
2417 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2422 ALCcontext_IncRef(ctx
);
2439 * Returns the currently active context for this thread, and adds a reference
2440 * without locking it.
2442 ALCcontext
*GetContextRef(void)
2444 ALCcontext
*context
;
2446 context
= altss_get(LocalContext
);
2448 ALCcontext_IncRef(context
);
2452 context
= ATOMIC_LOAD(&GlobalContext
);
2454 ALCcontext_IncRef(context
);
2462 /************************************************
2463 * Standard ALC functions
2464 ************************************************/
2468 * Return last ALC generated error code for the given device
2470 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2474 if(VerifyDevice(&device
))
2476 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2477 ALCdevice_DecRef(device
);
2480 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2486 /* alcSuspendContext
2488 * Suspends updates for the given context
2490 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2495 if(!VerifyContext(&context
))
2496 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2499 ALCcontext_DeferUpdates(context
);
2500 ALCcontext_DecRef(context
);
2504 /* alcProcessContext
2506 * Resumes processing updates for the given context
2508 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2513 if(!VerifyContext(&context
))
2514 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2517 ALCcontext_ProcessUpdates(context
);
2518 ALCcontext_DecRef(context
);
2525 * Returns information about the device, and error strings
2527 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2529 const ALCchar
*value
= NULL
;
2537 case ALC_INVALID_ENUM
:
2538 value
= alcErrInvalidEnum
;
2541 case ALC_INVALID_VALUE
:
2542 value
= alcErrInvalidValue
;
2545 case ALC_INVALID_DEVICE
:
2546 value
= alcErrInvalidDevice
;
2549 case ALC_INVALID_CONTEXT
:
2550 value
= alcErrInvalidContext
;
2553 case ALC_OUT_OF_MEMORY
:
2554 value
= alcErrOutOfMemory
;
2557 case ALC_DEVICE_SPECIFIER
:
2558 value
= alcDefaultName
;
2561 case ALC_ALL_DEVICES_SPECIFIER
:
2562 if(VerifyDevice(&Device
))
2564 value
= al_string_get_cstr(Device
->DeviceName
);
2565 ALCdevice_DecRef(Device
);
2569 ProbeAllDevicesList();
2570 value
= al_string_get_cstr(alcAllDevicesList
);
2574 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2575 if(VerifyDevice(&Device
))
2577 value
= al_string_get_cstr(Device
->DeviceName
);
2578 ALCdevice_DecRef(Device
);
2582 ProbeCaptureDeviceList();
2583 value
= al_string_get_cstr(alcCaptureDeviceList
);
2587 /* Default devices are always first in the list */
2588 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2589 value
= alcDefaultName
;
2592 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2593 if(al_string_empty(alcAllDevicesList
))
2594 ProbeAllDevicesList();
2596 VerifyDevice(&Device
);
2598 free(alcDefaultAllDevicesSpecifier
);
2599 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2600 if(!alcDefaultAllDevicesSpecifier
)
2601 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2603 value
= alcDefaultAllDevicesSpecifier
;
2604 if(Device
) ALCdevice_DecRef(Device
);
2607 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2608 if(al_string_empty(alcCaptureDeviceList
))
2609 ProbeCaptureDeviceList();
2611 VerifyDevice(&Device
);
2613 free(alcCaptureDefaultDeviceSpecifier
);
2614 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2615 if(!alcCaptureDefaultDeviceSpecifier
)
2616 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2618 value
= alcCaptureDefaultDeviceSpecifier
;
2619 if(Device
) ALCdevice_DecRef(Device
);
2622 case ALC_EXTENSIONS
:
2623 if(!VerifyDevice(&Device
))
2624 value
= alcNoDeviceExtList
;
2627 value
= alcExtensionList
;
2628 ALCdevice_DecRef(Device
);
2632 case ALC_HRTF_SPECIFIER_SOFT
:
2633 if(!VerifyDevice(&Device
))
2634 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2637 almtx_lock(&Device
->BackendLock
);
2638 value
= (Device
->Hrtf
? al_string_get_cstr(Device
->Hrtf_Name
) : "");
2639 almtx_unlock(&Device
->BackendLock
);
2640 ALCdevice_DecRef(Device
);
2645 VerifyDevice(&Device
);
2646 alcSetError(Device
, ALC_INVALID_ENUM
);
2647 if(Device
) ALCdevice_DecRef(Device
);
2655 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2659 if(size
<= 0 || values
== NULL
)
2661 alcSetError(device
, ALC_INVALID_VALUE
);
2669 case ALC_MAJOR_VERSION
:
2670 values
[0] = alcMajorVersion
;
2672 case ALC_MINOR_VERSION
:
2673 values
[0] = alcMinorVersion
;
2676 case ALC_ATTRIBUTES_SIZE
:
2677 case ALC_ALL_ATTRIBUTES
:
2681 case ALC_MONO_SOURCES
:
2682 case ALC_STEREO_SOURCES
:
2683 case ALC_CAPTURE_SAMPLES
:
2684 case ALC_FORMAT_CHANNELS_SOFT
:
2685 case ALC_FORMAT_TYPE_SOFT
:
2686 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2690 alcSetError(NULL
, ALC_INVALID_ENUM
);
2696 if(device
->Type
== Capture
)
2700 case ALC_CAPTURE_SAMPLES
:
2701 almtx_lock(&device
->BackendLock
);
2702 values
[0] = V0(device
->Backend
,availableSamples
)();
2703 almtx_unlock(&device
->BackendLock
);
2707 values
[0] = device
->Connected
;
2711 alcSetError(device
, ALC_INVALID_ENUM
);
2720 case ALC_MAJOR_VERSION
:
2721 values
[0] = alcMajorVersion
;
2724 case ALC_MINOR_VERSION
:
2725 values
[0] = alcMinorVersion
;
2728 case ALC_EFX_MAJOR_VERSION
:
2729 values
[0] = alcEFXMajorVersion
;
2732 case ALC_EFX_MINOR_VERSION
:
2733 values
[0] = alcEFXMinorVersion
;
2736 case ALC_ATTRIBUTES_SIZE
:
2740 case ALC_ALL_ATTRIBUTES
:
2743 alcSetError(device
, ALC_INVALID_VALUE
);
2748 almtx_lock(&device
->BackendLock
);
2749 values
[i
++] = ALC_FREQUENCY
;
2750 values
[i
++] = device
->Frequency
;
2752 if(device
->Type
!= Loopback
)
2754 values
[i
++] = ALC_REFRESH
;
2755 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2757 values
[i
++] = ALC_SYNC
;
2758 values
[i
++] = ALC_FALSE
;
2762 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2763 values
[i
++] = device
->FmtChans
;
2765 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2766 values
[i
++] = device
->FmtType
;
2769 values
[i
++] = ALC_MONO_SOURCES
;
2770 values
[i
++] = device
->NumMonoSources
;
2772 values
[i
++] = ALC_STEREO_SOURCES
;
2773 values
[i
++] = device
->NumStereoSources
;
2775 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2776 values
[i
++] = device
->NumAuxSends
;
2778 values
[i
++] = ALC_HRTF_SOFT
;
2779 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2781 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2782 values
[i
++] = device
->Hrtf_Status
;
2783 almtx_unlock(&device
->BackendLock
);
2789 values
[0] = device
->Frequency
;
2793 if(device
->Type
== Loopback
)
2795 alcSetError(device
, ALC_INVALID_DEVICE
);
2798 almtx_lock(&device
->BackendLock
);
2799 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2800 almtx_unlock(&device
->BackendLock
);
2804 if(device
->Type
== Loopback
)
2806 alcSetError(device
, ALC_INVALID_DEVICE
);
2809 values
[0] = ALC_FALSE
;
2812 case ALC_FORMAT_CHANNELS_SOFT
:
2813 if(device
->Type
!= Loopback
)
2815 alcSetError(device
, ALC_INVALID_DEVICE
);
2818 values
[0] = device
->FmtChans
;
2821 case ALC_FORMAT_TYPE_SOFT
:
2822 if(device
->Type
!= Loopback
)
2824 alcSetError(device
, ALC_INVALID_DEVICE
);
2827 values
[0] = device
->FmtType
;
2830 case ALC_MONO_SOURCES
:
2831 values
[0] = device
->NumMonoSources
;
2834 case ALC_STEREO_SOURCES
:
2835 values
[0] = device
->NumStereoSources
;
2838 case ALC_MAX_AUXILIARY_SENDS
:
2839 values
[0] = device
->NumAuxSends
;
2843 values
[0] = device
->Connected
;
2847 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2850 case ALC_HRTF_STATUS_SOFT
:
2851 values
[0] = device
->Hrtf_Status
;
2854 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
2855 almtx_lock(&device
->BackendLock
);
2856 FreeHrtfList(&device
->Hrtf_List
);
2857 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2858 values
[0] = (ALCint
)VECTOR_SIZE(device
->Hrtf_List
);
2859 almtx_unlock(&device
->BackendLock
);
2863 alcSetError(device
, ALC_INVALID_ENUM
);
2871 * Returns information about the device and the version of OpenAL
2873 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2875 VerifyDevice(&device
);
2876 if(size
<= 0 || values
== NULL
)
2877 alcSetError(device
, ALC_INVALID_VALUE
);
2879 GetIntegerv(device
, param
, size
, values
);
2880 if(device
) ALCdevice_DecRef(device
);
2883 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2888 VerifyDevice(&device
);
2889 if(size
<= 0 || values
== NULL
)
2890 alcSetError(device
, ALC_INVALID_VALUE
);
2891 else if(!device
|| device
->Type
== Capture
)
2893 ivals
= malloc(size
* sizeof(ALCint
));
2894 size
= GetIntegerv(device
, pname
, size
, ivals
);
2895 for(i
= 0;i
< size
;i
++)
2896 values
[i
] = ivals
[i
];
2899 else /* render device */
2908 case ALC_ATTRIBUTES_SIZE
:
2912 case ALC_ALL_ATTRIBUTES
:
2914 alcSetError(device
, ALC_INVALID_VALUE
);
2918 almtx_lock(&device
->BackendLock
);
2919 values
[i
++] = ALC_FREQUENCY
;
2920 values
[i
++] = device
->Frequency
;
2922 if(device
->Type
!= Loopback
)
2924 values
[i
++] = ALC_REFRESH
;
2925 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2927 values
[i
++] = ALC_SYNC
;
2928 values
[i
++] = ALC_FALSE
;
2932 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2933 values
[i
++] = device
->FmtChans
;
2935 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2936 values
[i
++] = device
->FmtType
;
2939 values
[i
++] = ALC_MONO_SOURCES
;
2940 values
[i
++] = device
->NumMonoSources
;
2942 values
[i
++] = ALC_STEREO_SOURCES
;
2943 values
[i
++] = device
->NumStereoSources
;
2945 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2946 values
[i
++] = device
->NumAuxSends
;
2948 values
[i
++] = ALC_HRTF_SOFT
;
2949 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2951 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2952 values
[i
++] = device
->Hrtf_Status
;
2954 clock
= V0(device
->Backend
,getClockLatency
)();
2955 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2956 values
[i
++] = clock
.ClockTime
;
2958 values
[i
++] = ALC_DEVICE_LATENCY_SOFT
;
2959 values
[i
++] = clock
.Latency
;
2960 almtx_unlock(&device
->BackendLock
);
2966 case ALC_DEVICE_CLOCK_SOFT
:
2967 almtx_lock(&device
->BackendLock
);
2969 while(((refcount
=ReadRef(&device
->MixCount
))&1) != 0)
2971 basecount
= device
->ClockBase
;
2972 samplecount
= device
->SamplesDone
;
2973 } while(refcount
!= ReadRef(&device
->MixCount
));
2974 *values
= basecount
+ (samplecount
*DEVICE_CLOCK_RES
/device
->Frequency
);
2975 almtx_unlock(&device
->BackendLock
);
2978 case ALC_DEVICE_LATENCY_SOFT
:
2980 almtx_lock(&device
->BackendLock
);
2981 clock
= V0(device
->Backend
,getClockLatency
)();
2982 almtx_unlock(&device
->BackendLock
);
2983 *values
= clock
.Latency
;
2987 case ALC_DEVICE_CLOCK_LATENCY_SOFT
:
2989 alcSetError(device
, ALC_INVALID_VALUE
);
2993 almtx_lock(&device
->BackendLock
);
2994 clock
= V0(device
->Backend
,getClockLatency
)();
2995 almtx_unlock(&device
->BackendLock
);
2996 values
[0] = clock
.ClockTime
;
2997 values
[1] = clock
.Latency
;
3002 ivals
= malloc(size
* sizeof(ALCint
));
3003 size
= GetIntegerv(device
, pname
, size
, ivals
);
3004 for(i
= 0;i
< size
;i
++)
3005 values
[i
] = ivals
[i
];
3011 ALCdevice_DecRef(device
);
3015 /* alcIsExtensionPresent
3017 * Determines if there is support for a particular extension
3019 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3021 ALCboolean bResult
= ALC_FALSE
;
3023 VerifyDevice(&device
);
3026 alcSetError(device
, ALC_INVALID_VALUE
);
3029 size_t len
= strlen(extName
);
3030 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3033 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3034 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3039 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3043 } while(isspace(*ptr
));
3048 ALCdevice_DecRef(device
);
3053 /* alcGetProcAddress
3055 * Retrieves the function address for a particular extension function
3057 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3059 ALCvoid
*ptr
= NULL
;
3063 VerifyDevice(&device
);
3064 alcSetError(device
, ALC_INVALID_VALUE
);
3065 if(device
) ALCdevice_DecRef(device
);
3070 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3072 ptr
= alcFunctions
[i
].address
;
3081 * Get the value for a particular ALC enumeration name
3083 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3089 VerifyDevice(&device
);
3090 alcSetError(device
, ALC_INVALID_VALUE
);
3091 if(device
) ALCdevice_DecRef(device
);
3096 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3098 val
= enumeration
[i
].value
;
3107 * Create and attach a context to the given device.
3109 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3111 ALCcontext
*ALContext
;
3115 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3118 alcSetError(device
, ALC_INVALID_DEVICE
);
3119 if(device
) ALCdevice_DecRef(device
);
3122 almtx_lock(&device
->BackendLock
);
3125 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3127 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3130 InitRef(&ALContext
->ref
, 1);
3131 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3133 ATOMIC_INIT(&ALContext
->ActiveAuxSlotList
, NULL
);
3135 ALContext
->VoiceCount
= 0;
3136 ALContext
->MaxVoices
= 256;
3137 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3139 if(!ALContext
|| !ALContext
->Voices
)
3141 almtx_unlock(&device
->BackendLock
);
3145 al_free(ALContext
->Voices
);
3146 ALContext
->Voices
= NULL
;
3152 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3153 ALCdevice_DecRef(device
);
3157 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3159 almtx_unlock(&device
->BackendLock
);
3161 al_free(ALContext
->Voices
);
3162 ALContext
->Voices
= NULL
;
3167 alcSetError(device
, err
);
3168 if(err
== ALC_INVALID_DEVICE
)
3170 V0(device
->Backend
,lock
)();
3171 aluHandleDisconnect(device
);
3172 V0(device
->Backend
,unlock
)();
3174 ALCdevice_DecRef(device
);
3178 ALContext
->Device
= device
;
3179 ALCdevice_IncRef(device
);
3180 InitContext(ALContext
);
3183 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3185 ALContext
->next
= head
;
3186 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3188 almtx_unlock(&device
->BackendLock
);
3190 ALCdevice_DecRef(device
);
3192 TRACE("Created context %p\n", ALContext
);
3196 /* alcDestroyContext
3198 * Remove a context from its device
3200 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3205 /* alcGetContextsDevice sets an error for invalid contexts */
3206 Device
= alcGetContextsDevice(context
);
3209 almtx_lock(&Device
->BackendLock
);
3210 ReleaseContext(context
, Device
);
3211 if(!ATOMIC_LOAD(&Device
->ContextList
))
3213 V0(Device
->Backend
,stop
)();
3214 Device
->Flags
&= ~DEVICE_RUNNING
;
3216 almtx_unlock(&Device
->BackendLock
);
3222 /* alcGetCurrentContext
3224 * Returns the currently active context on the calling thread
3226 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3228 ALCcontext
*Context
= altss_get(LocalContext
);
3229 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3233 /* alcGetThreadContext
3235 * Returns the currently active thread-local context
3237 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3239 return altss_get(LocalContext
);
3243 /* alcMakeContextCurrent
3245 * Makes the given context the active process-wide context, and removes the
3246 * thread-local context for the calling thread.
3248 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3250 /* context must be valid or NULL */
3251 if(context
&& !VerifyContext(&context
))
3253 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3256 /* context's reference count is already incremented */
3257 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3258 if(context
) ALCcontext_DecRef(context
);
3260 if((context
=altss_get(LocalContext
)) != NULL
)
3262 altss_set(LocalContext
, NULL
);
3263 ALCcontext_DecRef(context
);
3269 /* alcSetThreadContext
3271 * Makes the given context the active context for the current thread
3273 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3277 /* context must be valid or NULL */
3278 if(context
&& !VerifyContext(&context
))
3280 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3283 /* context's reference count is already incremented */
3284 old
= altss_get(LocalContext
);
3285 altss_set(LocalContext
, context
);
3286 if(old
) ALCcontext_DecRef(old
);
3292 /* alcGetContextsDevice
3294 * Returns the device that a particular context is attached to
3296 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3300 if(!VerifyContext(&Context
))
3302 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3305 Device
= Context
->Device
;
3306 ALCcontext_DecRef(Context
);
3314 * Opens the named device.
3316 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3324 if(!PlaybackBackend
.name
)
3326 alcSetError(NULL
, ALC_INVALID_VALUE
);
3330 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3332 /* Some old Windows apps hardcode these expecting OpenAL to use a
3333 * specific audio API, even when they're not enumerated. Creative's
3334 * router effectively ignores them too.
3336 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3337 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3342 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3345 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3350 InitRef(&device
->ref
, 1);
3351 device
->Connected
= ALC_TRUE
;
3352 device
->Type
= Playback
;
3353 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3356 device
->Bs2b
= NULL
;
3357 device
->Uhj_Encoder
= NULL
;
3358 VECTOR_INIT(device
->Hrtf_List
);
3359 AL_STRING_INIT(device
->Hrtf_Name
);
3360 device
->Render_Mode
= NormalRender
;
3361 AL_STRING_INIT(device
->DeviceName
);
3362 device
->Dry
.Buffer
= NULL
;
3363 device
->Dry
.NumChannels
= 0;
3364 device
->FOAOut
.Buffer
= NULL
;
3365 device
->FOAOut
.NumChannels
= 0;
3366 device
->RealOut
.Buffer
= NULL
;
3367 device
->RealOut
.NumChannels
= 0;
3369 ATOMIC_INIT(&device
->ContextList
, NULL
);
3371 device
->ClockBase
= 0;
3372 device
->SamplesDone
= 0;
3374 device
->SourcesMax
= 256;
3375 device
->AuxiliaryEffectSlotMax
= 4;
3376 device
->NumAuxSends
= MAX_SENDS
;
3378 InitUIntMap(&device
->BufferMap
, ~0);
3379 InitUIntMap(&device
->EffectMap
, ~0);
3380 InitUIntMap(&device
->FilterMap
, ~0);
3383 device
->FmtChans
= DevFmtChannelsDefault
;
3384 device
->FmtType
= DevFmtTypeDefault
;
3385 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3386 device
->IsHeadphones
= AL_FALSE
;
3387 device
->NumUpdates
= 4;
3388 device
->UpdateSize
= 1024;
3390 if(!PlaybackBackend
.getFactory
)
3391 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3392 ALCbackend_Playback
);
3395 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3396 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3398 if(!device
->Backend
)
3401 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3406 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3408 static const struct {
3409 const char name
[16];
3410 enum DevFmtChannels chans
;
3412 { "mono", DevFmtMono
},
3413 { "stereo", DevFmtStereo
},
3414 { "quad", DevFmtQuad
},
3415 { "surround51", DevFmtX51
},
3416 { "surround61", DevFmtX61
},
3417 { "surround71", DevFmtX71
},
3418 { "surround51rear", DevFmtX51Rear
},
3422 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3424 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3426 device
->FmtChans
= chanlist
[i
].chans
;
3427 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3431 if(i
== COUNTOF(chanlist
))
3432 ERR("Unsupported channels: %s\n", fmt
);
3434 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3436 static const struct {
3437 const char name
[16];
3438 enum DevFmtType type
;
3440 { "int8", DevFmtByte
},
3441 { "uint8", DevFmtUByte
},
3442 { "int16", DevFmtShort
},
3443 { "uint16", DevFmtUShort
},
3444 { "int32", DevFmtInt
},
3445 { "uint32", DevFmtUInt
},
3446 { "float32", DevFmtFloat
},
3450 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3452 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3454 device
->FmtType
= typelist
[i
].type
;
3455 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3459 if(i
== COUNTOF(typelist
))
3460 ERR("Unsupported sample-type: %s\n", fmt
);
3463 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3465 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3466 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3467 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3468 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3471 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3472 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3474 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3475 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3476 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3477 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3479 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->SourcesMax
);
3480 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
3482 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3483 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3485 ConfigValueUInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3486 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3488 device
->NumStereoSources
= 1;
3489 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
3491 // Find a playback device to open
3492 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3494 DELETE_OBJ(device
->Backend
);
3496 alcSetError(NULL
, err
);
3499 almtx_init(&device
->BackendLock
, almtx_plain
);
3501 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3503 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3504 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3506 device
->DefaultSlot
= NULL
;
3507 ERR("Failed to initialize the default effect slot\n");
3511 aluInitEffectPanning(device
->DefaultSlot
);
3512 if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3514 DeinitEffectSlot(device
->DefaultSlot
);
3515 device
->DefaultSlot
= NULL
;
3516 ERR("Failed to initialize the default effect\n");
3522 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3524 device
->next
= head
;
3525 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3528 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3534 * Closes the given device.
3536 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3538 ALCdevice
*list
, *origdev
, *nextdev
;
3542 list
= ATOMIC_LOAD(&DeviceList
);
3546 } while((list
=list
->next
) != NULL
);
3547 if(!list
|| list
->Type
== Capture
)
3549 alcSetError(list
, ALC_INVALID_DEVICE
);
3553 almtx_lock(&device
->BackendLock
);
3556 nextdev
= device
->next
;
3557 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3562 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3566 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3569 ALCcontext
*next
= ctx
->next
;
3570 WARN("Releasing context %p\n", ctx
);
3571 ReleaseContext(ctx
, device
);
3574 if((device
->Flags
&DEVICE_RUNNING
))
3575 V0(device
->Backend
,stop
)();
3576 device
->Flags
&= ~DEVICE_RUNNING
;
3577 almtx_unlock(&device
->BackendLock
);
3579 ALCdevice_DecRef(device
);
3585 /************************************************
3586 * ALC capture functions
3587 ************************************************/
3588 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3590 ALCdevice
*device
= NULL
;
3595 if(!CaptureBackend
.name
)
3597 alcSetError(NULL
, ALC_INVALID_VALUE
);
3603 alcSetError(NULL
, ALC_INVALID_VALUE
);
3607 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3610 device
= al_calloc(16, sizeof(ALCdevice
));
3613 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3618 InitRef(&device
->ref
, 1);
3619 device
->Connected
= ALC_TRUE
;
3620 device
->Type
= Capture
;
3622 VECTOR_INIT(device
->Hrtf_List
);
3623 AL_STRING_INIT(device
->Hrtf_Name
);
3625 AL_STRING_INIT(device
->DeviceName
);
3626 device
->Dry
.Buffer
= NULL
;
3627 device
->Dry
.NumChannels
= 0;
3628 device
->FOAOut
.Buffer
= NULL
;
3629 device
->FOAOut
.NumChannels
= 0;
3630 device
->RealOut
.Buffer
= NULL
;
3631 device
->RealOut
.NumChannels
= 0;
3633 InitUIntMap(&device
->BufferMap
, ~0);
3634 InitUIntMap(&device
->EffectMap
, ~0);
3635 InitUIntMap(&device
->FilterMap
, ~0);
3637 if(!CaptureBackend
.getFactory
)
3638 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3639 ALCbackend_Capture
);
3642 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3643 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3645 if(!device
->Backend
)
3648 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3652 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3653 device
->Frequency
= frequency
;
3655 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3656 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3659 alcSetError(NULL
, ALC_INVALID_ENUM
);
3662 device
->IsHeadphones
= AL_FALSE
;
3664 device
->UpdateSize
= samples
;
3665 device
->NumUpdates
= 1;
3667 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3670 alcSetError(NULL
, err
);
3673 almtx_init(&device
->BackendLock
, almtx_plain
);
3676 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3678 device
->next
= head
;
3679 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3682 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3686 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3688 ALCdevice
*list
, *next
, *nextdev
;
3691 list
= ATOMIC_LOAD(&DeviceList
);
3695 } while((list
=list
->next
) != NULL
);
3696 if(!list
|| list
->Type
!= Capture
)
3698 alcSetError(list
, ALC_INVALID_DEVICE
);
3704 nextdev
= device
->next
;
3705 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3710 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3714 ALCdevice_DecRef(device
);
3719 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3721 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3722 alcSetError(device
, ALC_INVALID_DEVICE
);
3725 almtx_lock(&device
->BackendLock
);
3726 if(!device
->Connected
)
3727 alcSetError(device
, ALC_INVALID_DEVICE
);
3728 else if(!(device
->Flags
&DEVICE_RUNNING
))
3730 if(V0(device
->Backend
,start
)())
3731 device
->Flags
|= DEVICE_RUNNING
;
3734 aluHandleDisconnect(device
);
3735 alcSetError(device
, ALC_INVALID_DEVICE
);
3738 almtx_unlock(&device
->BackendLock
);
3741 if(device
) ALCdevice_DecRef(device
);
3744 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3746 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3747 alcSetError(device
, ALC_INVALID_DEVICE
);
3750 almtx_lock(&device
->BackendLock
);
3751 if((device
->Flags
&DEVICE_RUNNING
))
3752 V0(device
->Backend
,stop
)();
3753 device
->Flags
&= ~DEVICE_RUNNING
;
3754 almtx_unlock(&device
->BackendLock
);
3757 if(device
) ALCdevice_DecRef(device
);
3760 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3762 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3763 alcSetError(device
, ALC_INVALID_DEVICE
);
3766 ALCenum err
= ALC_INVALID_VALUE
;
3768 almtx_lock(&device
->BackendLock
);
3769 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3770 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3771 almtx_unlock(&device
->BackendLock
);
3773 if(err
!= ALC_NO_ERROR
)
3774 alcSetError(device
, err
);
3776 if(device
) ALCdevice_DecRef(device
);
3780 /************************************************
3781 * ALC loopback functions
3782 ************************************************/
3784 /* alcLoopbackOpenDeviceSOFT
3786 * Open a loopback device, for manual rendering.
3788 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3790 ALCbackendFactory
*factory
;
3795 /* Make sure the device name, if specified, is us. */
3796 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3798 alcSetError(NULL
, ALC_INVALID_VALUE
);
3802 device
= al_calloc(16, sizeof(ALCdevice
));
3805 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3810 InitRef(&device
->ref
, 1);
3811 device
->Connected
= ALC_TRUE
;
3812 device
->Type
= Loopback
;
3813 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3816 VECTOR_INIT(device
->Hrtf_List
);
3817 AL_STRING_INIT(device
->Hrtf_Name
);
3818 device
->Bs2b
= NULL
;
3819 device
->Uhj_Encoder
= NULL
;
3820 device
->Render_Mode
= NormalRender
;
3821 AL_STRING_INIT(device
->DeviceName
);
3822 device
->Dry
.Buffer
= NULL
;
3823 device
->Dry
.NumChannels
= 0;
3824 device
->FOAOut
.Buffer
= NULL
;
3825 device
->FOAOut
.NumChannels
= 0;
3826 device
->RealOut
.Buffer
= NULL
;
3827 device
->RealOut
.NumChannels
= 0;
3829 ATOMIC_INIT(&device
->ContextList
, NULL
);
3831 device
->ClockBase
= 0;
3832 device
->SamplesDone
= 0;
3834 device
->SourcesMax
= 256;
3835 device
->AuxiliaryEffectSlotMax
= 4;
3836 device
->NumAuxSends
= MAX_SENDS
;
3838 InitUIntMap(&device
->BufferMap
, ~0);
3839 InitUIntMap(&device
->EffectMap
, ~0);
3840 InitUIntMap(&device
->FilterMap
, ~0);
3842 factory
= ALCloopbackFactory_getFactory();
3843 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3844 if(!device
->Backend
)
3847 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3850 almtx_init(&device
->BackendLock
, almtx_plain
);
3853 device
->NumUpdates
= 0;
3854 device
->UpdateSize
= 0;
3856 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3857 device
->FmtChans
= DevFmtChannelsDefault
;
3858 device
->FmtType
= DevFmtTypeDefault
;
3859 device
->IsHeadphones
= AL_FALSE
;
3861 ConfigValueUInt(NULL
, NULL
, "sources", &device
->SourcesMax
);
3862 if(device
->SourcesMax
== 0) device
->SourcesMax
= 256;
3864 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3865 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3867 ConfigValueUInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
3868 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3870 device
->NumStereoSources
= 1;
3871 device
->NumMonoSources
= device
->SourcesMax
- device
->NumStereoSources
;
3873 // Open the "backend"
3874 V(device
->Backend
,open
)("Loopback");
3877 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3879 device
->next
= head
;
3880 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3883 TRACE("Created device %p\n", device
);
3887 /* alcIsRenderFormatSupportedSOFT
3889 * Determines if the loopback device supports the given format for rendering.
3891 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3893 ALCboolean ret
= ALC_FALSE
;
3895 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3896 alcSetError(device
, ALC_INVALID_DEVICE
);
3898 alcSetError(device
, ALC_INVALID_VALUE
);
3901 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3902 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3903 freq
>= MIN_OUTPUT_RATE
)
3906 if(device
) ALCdevice_DecRef(device
);
3911 /* alcRenderSamplesSOFT
3913 * Renders some samples into a buffer, using the format last set by the
3914 * attributes given to alcCreateContext.
3916 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3918 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3919 alcSetError(device
, ALC_INVALID_DEVICE
);
3920 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3921 alcSetError(device
, ALC_INVALID_VALUE
);
3923 aluMixData(device
, buffer
, samples
);
3924 if(device
) ALCdevice_DecRef(device
);
3928 /************************************************
3929 * ALC DSP pause/resume functions
3930 ************************************************/
3932 /* alcDevicePauseSOFT
3934 * Pause the DSP to stop audio processing.
3936 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3938 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3939 alcSetError(device
, ALC_INVALID_DEVICE
);
3942 almtx_lock(&device
->BackendLock
);
3943 if((device
->Flags
&DEVICE_RUNNING
))
3944 V0(device
->Backend
,stop
)();
3945 device
->Flags
&= ~DEVICE_RUNNING
;
3946 device
->Flags
|= DEVICE_PAUSED
;
3947 almtx_unlock(&device
->BackendLock
);
3949 if(device
) ALCdevice_DecRef(device
);
3952 /* alcDeviceResumeSOFT
3954 * Resume the DSP to restart audio processing.
3956 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3958 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3959 alcSetError(device
, ALC_INVALID_DEVICE
);
3962 almtx_lock(&device
->BackendLock
);
3963 if((device
->Flags
&DEVICE_PAUSED
))
3965 device
->Flags
&= ~DEVICE_PAUSED
;
3966 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3968 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3969 device
->Flags
|= DEVICE_RUNNING
;
3972 alcSetError(device
, ALC_INVALID_DEVICE
);
3973 V0(device
->Backend
,lock
)();
3974 aluHandleDisconnect(device
);
3975 V0(device
->Backend
,unlock
)();
3979 almtx_unlock(&device
->BackendLock
);
3981 if(device
) ALCdevice_DecRef(device
);
3985 /************************************************
3986 * ALC HRTF functions
3987 ************************************************/
3989 /* alcGetStringiSOFT
3991 * Gets a string parameter at the given index.
3993 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
3995 const ALCchar
*str
= NULL
;
3997 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
3998 alcSetError(device
, ALC_INVALID_DEVICE
);
3999 else switch(paramName
)
4001 case ALC_HRTF_SPECIFIER_SOFT
:
4002 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->Hrtf_List
))
4003 str
= al_string_get_cstr(VECTOR_ELEM(device
->Hrtf_List
, index
).name
);
4005 alcSetError(device
, ALC_INVALID_VALUE
);
4009 alcSetError(device
, ALC_INVALID_ENUM
);
4012 if(device
) ALCdevice_DecRef(device
);
4017 /* alcResetDeviceSOFT
4019 * Resets the given device output, using the specified attribute list.
4021 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
4026 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
4029 alcSetError(device
, ALC_INVALID_DEVICE
);
4030 if(device
) ALCdevice_DecRef(device
);
4033 almtx_lock(&device
->BackendLock
);
4036 err
= UpdateDeviceParams(device
, attribs
);
4037 almtx_unlock(&device
->BackendLock
);
4039 if(err
!= ALC_NO_ERROR
)
4041 alcSetError(device
, err
);
4042 if(err
== ALC_INVALID_DEVICE
)
4044 V0(device
->Backend
,lock
)();
4045 aluHandleDisconnect(device
);
4046 V0(device
->Backend
,unlock
)();
4048 ALCdevice_DecRef(device
);
4051 ALCdevice_DecRef(device
);