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
),
295 #define DECL(x) { #x, (x) }
296 static const ALCenums enumeration
[] = {
301 DECL(ALC_MAJOR_VERSION
),
302 DECL(ALC_MINOR_VERSION
),
303 DECL(ALC_ATTRIBUTES_SIZE
),
304 DECL(ALC_ALL_ATTRIBUTES
),
305 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
306 DECL(ALC_DEVICE_SPECIFIER
),
307 DECL(ALC_ALL_DEVICES_SPECIFIER
),
308 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
309 DECL(ALC_EXTENSIONS
),
313 DECL(ALC_MONO_SOURCES
),
314 DECL(ALC_STEREO_SOURCES
),
315 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
316 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
317 DECL(ALC_CAPTURE_SAMPLES
),
320 DECL(ALC_EFX_MAJOR_VERSION
),
321 DECL(ALC_EFX_MINOR_VERSION
),
322 DECL(ALC_MAX_AUXILIARY_SENDS
),
324 DECL(ALC_FORMAT_CHANNELS_SOFT
),
325 DECL(ALC_FORMAT_TYPE_SOFT
),
328 DECL(ALC_STEREO_SOFT
),
330 DECL(ALC_5POINT1_SOFT
),
331 DECL(ALC_6POINT1_SOFT
),
332 DECL(ALC_7POINT1_SOFT
),
335 DECL(ALC_UNSIGNED_BYTE_SOFT
),
336 DECL(ALC_SHORT_SOFT
),
337 DECL(ALC_UNSIGNED_SHORT_SOFT
),
339 DECL(ALC_UNSIGNED_INT_SOFT
),
340 DECL(ALC_FLOAT_SOFT
),
343 DECL(ALC_DONT_CARE_SOFT
),
344 DECL(ALC_HRTF_STATUS_SOFT
),
345 DECL(ALC_HRTF_DISABLED_SOFT
),
346 DECL(ALC_HRTF_ENABLED_SOFT
),
347 DECL(ALC_HRTF_DENIED_SOFT
),
348 DECL(ALC_HRTF_REQUIRED_SOFT
),
349 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
350 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
351 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
352 DECL(ALC_HRTF_SPECIFIER_SOFT
),
353 DECL(ALC_HRTF_ID_SOFT
),
356 DECL(ALC_INVALID_DEVICE
),
357 DECL(ALC_INVALID_CONTEXT
),
358 DECL(ALC_INVALID_ENUM
),
359 DECL(ALC_INVALID_VALUE
),
360 DECL(ALC_OUT_OF_MEMORY
),
368 DECL(AL_SOURCE_RELATIVE
),
369 DECL(AL_CONE_INNER_ANGLE
),
370 DECL(AL_CONE_OUTER_ANGLE
),
380 DECL(AL_ORIENTATION
),
381 DECL(AL_REFERENCE_DISTANCE
),
382 DECL(AL_ROLLOFF_FACTOR
),
383 DECL(AL_CONE_OUTER_GAIN
),
384 DECL(AL_MAX_DISTANCE
),
386 DECL(AL_SAMPLE_OFFSET
),
387 DECL(AL_BYTE_OFFSET
),
388 DECL(AL_SOURCE_TYPE
),
391 DECL(AL_UNDETERMINED
),
392 DECL(AL_METERS_PER_UNIT
),
393 DECL(AL_LOOP_POINTS_SOFT
),
394 DECL(AL_DIRECT_CHANNELS_SOFT
),
396 DECL(AL_DIRECT_FILTER
),
397 DECL(AL_AUXILIARY_SEND_FILTER
),
398 DECL(AL_AIR_ABSORPTION_FACTOR
),
399 DECL(AL_ROOM_ROLLOFF_FACTOR
),
400 DECL(AL_CONE_OUTER_GAINHF
),
401 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
402 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
403 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
405 DECL(AL_SOURCE_STATE
),
411 DECL(AL_BUFFERS_QUEUED
),
412 DECL(AL_BUFFERS_PROCESSED
),
414 DECL(AL_FORMAT_MONO8
),
415 DECL(AL_FORMAT_MONO16
),
416 DECL(AL_FORMAT_MONO_FLOAT32
),
417 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
418 DECL(AL_FORMAT_STEREO8
),
419 DECL(AL_FORMAT_STEREO16
),
420 DECL(AL_FORMAT_STEREO_FLOAT32
),
421 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
422 DECL(AL_FORMAT_MONO_IMA4
),
423 DECL(AL_FORMAT_STEREO_IMA4
),
424 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
425 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
426 DECL(AL_FORMAT_QUAD8_LOKI
),
427 DECL(AL_FORMAT_QUAD16_LOKI
),
428 DECL(AL_FORMAT_QUAD8
),
429 DECL(AL_FORMAT_QUAD16
),
430 DECL(AL_FORMAT_QUAD32
),
431 DECL(AL_FORMAT_51CHN8
),
432 DECL(AL_FORMAT_51CHN16
),
433 DECL(AL_FORMAT_51CHN32
),
434 DECL(AL_FORMAT_61CHN8
),
435 DECL(AL_FORMAT_61CHN16
),
436 DECL(AL_FORMAT_61CHN32
),
437 DECL(AL_FORMAT_71CHN8
),
438 DECL(AL_FORMAT_71CHN16
),
439 DECL(AL_FORMAT_71CHN32
),
440 DECL(AL_FORMAT_REAR8
),
441 DECL(AL_FORMAT_REAR16
),
442 DECL(AL_FORMAT_REAR32
),
443 DECL(AL_FORMAT_MONO_MULAW
),
444 DECL(AL_FORMAT_MONO_MULAW_EXT
),
445 DECL(AL_FORMAT_STEREO_MULAW
),
446 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
447 DECL(AL_FORMAT_QUAD_MULAW
),
448 DECL(AL_FORMAT_51CHN_MULAW
),
449 DECL(AL_FORMAT_61CHN_MULAW
),
450 DECL(AL_FORMAT_71CHN_MULAW
),
451 DECL(AL_FORMAT_REAR_MULAW
),
452 DECL(AL_FORMAT_MONO_ALAW_EXT
),
453 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
456 DECL(AL_MONO16_SOFT
),
457 DECL(AL_MONO32F_SOFT
),
458 DECL(AL_STEREO8_SOFT
),
459 DECL(AL_STEREO16_SOFT
),
460 DECL(AL_STEREO32F_SOFT
),
462 DECL(AL_QUAD16_SOFT
),
463 DECL(AL_QUAD32F_SOFT
),
465 DECL(AL_REAR16_SOFT
),
466 DECL(AL_REAR32F_SOFT
),
467 DECL(AL_5POINT1_8_SOFT
),
468 DECL(AL_5POINT1_16_SOFT
),
469 DECL(AL_5POINT1_32F_SOFT
),
470 DECL(AL_6POINT1_8_SOFT
),
471 DECL(AL_6POINT1_16_SOFT
),
472 DECL(AL_6POINT1_32F_SOFT
),
473 DECL(AL_7POINT1_8_SOFT
),
474 DECL(AL_7POINT1_16_SOFT
),
475 DECL(AL_7POINT1_32F_SOFT
),
476 DECL(AL_FORMAT_BFORMAT2D_8
),
477 DECL(AL_FORMAT_BFORMAT2D_16
),
478 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
479 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
480 DECL(AL_FORMAT_BFORMAT3D_8
),
481 DECL(AL_FORMAT_BFORMAT3D_16
),
482 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
483 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
486 DECL(AL_STEREO_SOFT
),
489 DECL(AL_5POINT1_SOFT
),
490 DECL(AL_6POINT1_SOFT
),
491 DECL(AL_7POINT1_SOFT
),
494 DECL(AL_UNSIGNED_BYTE_SOFT
),
496 DECL(AL_UNSIGNED_SHORT_SOFT
),
498 DECL(AL_UNSIGNED_INT_SOFT
),
500 DECL(AL_DOUBLE_SOFT
),
502 DECL(AL_UNSIGNED_BYTE3_SOFT
),
508 DECL(AL_INTERNAL_FORMAT_SOFT
),
509 DECL(AL_BYTE_LENGTH_SOFT
),
510 DECL(AL_SAMPLE_LENGTH_SOFT
),
511 DECL(AL_SEC_LENGTH_SOFT
),
512 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
513 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
515 DECL(AL_SOURCE_RADIUS
),
517 DECL(AL_STEREO_ANGLES
),
524 DECL(AL_INVALID_NAME
),
525 DECL(AL_INVALID_ENUM
),
526 DECL(AL_INVALID_VALUE
),
527 DECL(AL_INVALID_OPERATION
),
528 DECL(AL_OUT_OF_MEMORY
),
535 DECL(AL_DOPPLER_FACTOR
),
536 DECL(AL_DOPPLER_VELOCITY
),
537 DECL(AL_DISTANCE_MODEL
),
538 DECL(AL_SPEED_OF_SOUND
),
539 DECL(AL_SOURCE_DISTANCE_MODEL
),
540 DECL(AL_DEFERRED_UPDATES_SOFT
),
542 DECL(AL_INVERSE_DISTANCE
),
543 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
544 DECL(AL_LINEAR_DISTANCE
),
545 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
546 DECL(AL_EXPONENT_DISTANCE
),
547 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
549 DECL(AL_FILTER_TYPE
),
550 DECL(AL_FILTER_NULL
),
551 DECL(AL_FILTER_LOWPASS
),
552 DECL(AL_FILTER_HIGHPASS
),
553 DECL(AL_FILTER_BANDPASS
),
555 DECL(AL_LOWPASS_GAIN
),
556 DECL(AL_LOWPASS_GAINHF
),
558 DECL(AL_HIGHPASS_GAIN
),
559 DECL(AL_HIGHPASS_GAINLF
),
561 DECL(AL_BANDPASS_GAIN
),
562 DECL(AL_BANDPASS_GAINHF
),
563 DECL(AL_BANDPASS_GAINLF
),
565 DECL(AL_EFFECT_TYPE
),
566 DECL(AL_EFFECT_NULL
),
567 DECL(AL_EFFECT_REVERB
),
568 DECL(AL_EFFECT_EAXREVERB
),
569 DECL(AL_EFFECT_CHORUS
),
570 DECL(AL_EFFECT_DISTORTION
),
571 DECL(AL_EFFECT_ECHO
),
572 DECL(AL_EFFECT_FLANGER
),
574 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
575 DECL(AL_EFFECT_VOCAL_MORPHER
),
576 DECL(AL_EFFECT_PITCH_SHIFTER
),
578 DECL(AL_EFFECT_RING_MODULATOR
),
580 DECL(AL_EFFECT_AUTOWAH
),
582 DECL(AL_EFFECT_COMPRESSOR
),
583 DECL(AL_EFFECT_EQUALIZER
),
584 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
585 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
587 DECL(AL_EAXREVERB_DENSITY
),
588 DECL(AL_EAXREVERB_DIFFUSION
),
589 DECL(AL_EAXREVERB_GAIN
),
590 DECL(AL_EAXREVERB_GAINHF
),
591 DECL(AL_EAXREVERB_GAINLF
),
592 DECL(AL_EAXREVERB_DECAY_TIME
),
593 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
594 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
595 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
596 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
597 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
598 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
599 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
600 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
601 DECL(AL_EAXREVERB_ECHO_TIME
),
602 DECL(AL_EAXREVERB_ECHO_DEPTH
),
603 DECL(AL_EAXREVERB_MODULATION_TIME
),
604 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
605 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
606 DECL(AL_EAXREVERB_HFREFERENCE
),
607 DECL(AL_EAXREVERB_LFREFERENCE
),
608 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
609 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
611 DECL(AL_REVERB_DENSITY
),
612 DECL(AL_REVERB_DIFFUSION
),
613 DECL(AL_REVERB_GAIN
),
614 DECL(AL_REVERB_GAINHF
),
615 DECL(AL_REVERB_DECAY_TIME
),
616 DECL(AL_REVERB_DECAY_HFRATIO
),
617 DECL(AL_REVERB_REFLECTIONS_GAIN
),
618 DECL(AL_REVERB_REFLECTIONS_DELAY
),
619 DECL(AL_REVERB_LATE_REVERB_GAIN
),
620 DECL(AL_REVERB_LATE_REVERB_DELAY
),
621 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
622 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
623 DECL(AL_REVERB_DECAY_HFLIMIT
),
625 DECL(AL_CHORUS_WAVEFORM
),
626 DECL(AL_CHORUS_PHASE
),
627 DECL(AL_CHORUS_RATE
),
628 DECL(AL_CHORUS_DEPTH
),
629 DECL(AL_CHORUS_FEEDBACK
),
630 DECL(AL_CHORUS_DELAY
),
632 DECL(AL_DISTORTION_EDGE
),
633 DECL(AL_DISTORTION_GAIN
),
634 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
635 DECL(AL_DISTORTION_EQCENTER
),
636 DECL(AL_DISTORTION_EQBANDWIDTH
),
639 DECL(AL_ECHO_LRDELAY
),
640 DECL(AL_ECHO_DAMPING
),
641 DECL(AL_ECHO_FEEDBACK
),
642 DECL(AL_ECHO_SPREAD
),
644 DECL(AL_FLANGER_WAVEFORM
),
645 DECL(AL_FLANGER_PHASE
),
646 DECL(AL_FLANGER_RATE
),
647 DECL(AL_FLANGER_DEPTH
),
648 DECL(AL_FLANGER_FEEDBACK
),
649 DECL(AL_FLANGER_DELAY
),
651 DECL(AL_RING_MODULATOR_FREQUENCY
),
652 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
653 DECL(AL_RING_MODULATOR_WAVEFORM
),
656 DECL(AL_AUTOWAH_ATTACK_TIME
),
657 DECL(AL_AUTOWAH_PEAK_GAIN
),
658 DECL(AL_AUTOWAH_RELEASE_TIME
),
659 DECL(AL_AUTOWAH_RESONANCE
),
662 DECL(AL_COMPRESSOR_ONOFF
),
664 DECL(AL_EQUALIZER_LOW_GAIN
),
665 DECL(AL_EQUALIZER_LOW_CUTOFF
),
666 DECL(AL_EQUALIZER_MID1_GAIN
),
667 DECL(AL_EQUALIZER_MID1_CENTER
),
668 DECL(AL_EQUALIZER_MID1_WIDTH
),
669 DECL(AL_EQUALIZER_MID2_GAIN
),
670 DECL(AL_EQUALIZER_MID2_CENTER
),
671 DECL(AL_EQUALIZER_MID2_WIDTH
),
672 DECL(AL_EQUALIZER_HIGH_GAIN
),
673 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
675 DECL(AL_DEDICATED_GAIN
),
681 static const ALCchar alcNoError
[] = "No Error";
682 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
683 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
684 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
685 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
686 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
689 /************************************************
691 ************************************************/
693 /* Enumerated device names */
694 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
696 static al_string alcAllDevicesList
;
697 static al_string alcCaptureDeviceList
;
699 /* Default is always the first in the list */
700 static ALCchar
*alcDefaultAllDevicesSpecifier
;
701 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
703 /* Default context extensions */
704 static const ALchar alExtList
[] =
705 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
706 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
707 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
708 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
709 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
710 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
711 "AL_SOFT_source_latency AL_SOFT_source_length";
713 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
715 /* Thread-local current context */
716 static altss_t LocalContext
;
717 /* Process-wide current context */
718 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
720 /* Mixing thread piority level */
725 enum LogLevel LogLevel
= LogWarning
;
727 enum LogLevel LogLevel
= LogError
;
730 /* Flag to trap ALC device errors */
731 static ALCboolean TrapALCError
= ALC_FALSE
;
733 /* One-time configuration init control */
734 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
736 /* Default effect that applies to sources that don't have an effect on send 0 */
737 static ALeffect DefaultEffect
;
739 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
742 static ALCboolean SuspendDefers
= ALC_TRUE
;
745 /************************************************
747 ************************************************/
748 static const ALCchar alcNoDeviceExtList
[] =
749 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
750 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
751 static const ALCchar alcExtensionList
[] =
752 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
753 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
754 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
755 "ALC_SOFT_loopback ALC_SOFT_pause_device";
756 static const ALCint alcMajorVersion
= 1;
757 static const ALCint alcMinorVersion
= 1;
759 static const ALCint alcEFXMajorVersion
= 1;
760 static const ALCint alcEFXMinorVersion
= 0;
763 /************************************************
765 ************************************************/
766 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
768 static almtx_t ListLock
;
769 static inline void LockLists(void)
771 int lockret
= almtx_lock(&ListLock
);
772 assert(lockret
== althrd_success
);
774 static inline void UnlockLists(void)
776 int unlockret
= almtx_unlock(&ListLock
);
777 assert(unlockret
== althrd_success
);
780 /************************************************
781 * Library initialization
782 ************************************************/
784 static void alc_init(void);
785 static void alc_deinit(void);
786 static void alc_deinit_safe(void);
788 #ifndef AL_LIBTYPE_STATIC
789 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
793 case DLL_PROCESS_ATTACH
:
794 /* Pin the DLL so we won't get unloaded until the process terminates */
795 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
796 (WCHAR
*)hModule
, &hModule
);
800 case DLL_THREAD_DETACH
:
803 case DLL_PROCESS_DETACH
:
812 #elif defined(_MSC_VER)
813 #pragma section(".CRT$XCU",read)
814 static void alc_constructor(void);
815 static void alc_destructor(void);
816 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
818 static void alc_constructor(void)
820 atexit(alc_destructor
);
824 static void alc_destructor(void)
828 #elif defined(HAVE_GCC_DESTRUCTOR)
829 static void alc_init(void) __attribute__((constructor
));
830 static void alc_deinit(void) __attribute__((destructor
));
832 #error "No static initialization available on this platform!"
835 #elif defined(HAVE_GCC_DESTRUCTOR)
837 static void alc_init(void) __attribute__((constructor
));
838 static void alc_deinit(void) __attribute__((destructor
));
841 #error "No global initialization available on this platform!"
844 static void ReleaseThreadCtx(void *ptr
);
845 static void alc_init(void)
852 AL_STRING_INIT(alcAllDevicesList
);
853 AL_STRING_INIT(alcCaptureDeviceList
);
855 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
856 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
859 str
= getenv("__ALSOFT_REVERSE_Z");
860 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
863 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
864 assert(ret
== althrd_success
);
866 ret
= almtx_init(&ListLock
, almtx_recursive
);
867 assert(ret
== althrd_success
);
872 static void alc_initconfig(void)
874 const char *devs
, *str
;
879 str
= getenv("ALSOFT_LOGLEVEL");
882 long lvl
= strtol(str
, NULL
, 0);
883 if(lvl
>= NoLog
&& lvl
<= LogRef
)
887 str
= getenv("ALSOFT_LOGFILE");
890 FILE *logfile
= al_fopen(str
, "wt");
891 if(logfile
) LogFile
= logfile
;
892 else ERR("Failed to open log file '%s'\n", str
);
897 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
898 for(i
= 1;BackendList
[i
].name
;i
++)
899 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
900 TRACE("Supported backends: %s\n", buf
);
904 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
907 if(strcasecmp(str
, "ignore") == 0)
909 SuspendDefers
= ALC_FALSE
;
910 TRACE("Selected context suspend behavior, \"ignore\"\n");
913 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
917 #if defined(HAVE_SSE4_1)
918 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
919 #elif defined(HAVE_SSE3)
920 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
921 #elif defined(HAVE_SSE2)
922 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
923 #elif defined(HAVE_SSE)
924 capfilter
|= CPU_CAP_SSE
;
927 capfilter
|= CPU_CAP_NEON
;
929 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
931 if(strcasecmp(str
, "all") == 0)
936 const char *next
= str
;
940 while(isspace(str
[0]))
942 next
= strchr(str
, ',');
944 if(!str
[0] || str
[0] == ',')
947 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
948 while(len
> 0 && isspace(str
[len
-1]))
950 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
951 capfilter
&= ~CPU_CAP_SSE
;
952 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
953 capfilter
&= ~CPU_CAP_SSE2
;
954 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
955 capfilter
&= ~CPU_CAP_SSE3
;
956 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
957 capfilter
&= ~CPU_CAP_SSE4_1
;
958 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
959 capfilter
&= ~CPU_CAP_NEON
;
961 WARN("Invalid CPU extension \"%s\"\n", str
);
965 FillCPUCaps(capfilter
);
972 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
976 str
= getenv("ALSOFT_TRAP_ERROR");
977 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
979 TrapALError
= AL_TRUE
;
980 TrapALCError
= AL_TRUE
;
984 str
= getenv("ALSOFT_TRAP_AL_ERROR");
985 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
986 TrapALError
= AL_TRUE
;
987 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
989 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
990 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
991 TrapALCError
= ALC_TRUE
;
992 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
995 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
996 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
998 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1000 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1001 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1005 const char *next
= devs
;
1006 int endlist
, delitem
;
1011 while(isspace(devs
[0]))
1013 next
= strchr(devs
, ',');
1015 delitem
= (devs
[0] == '-');
1016 if(devs
[0] == '-') devs
++;
1018 if(!devs
[0] || devs
[0] == ',')
1025 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1026 while(len
> 0 && isspace(devs
[len
-1]))
1028 for(n
= i
;BackendList
[n
].name
;n
++)
1030 if(len
== strlen(BackendList
[n
].name
) &&
1031 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1036 BackendList
[n
] = BackendList
[n
+1];
1038 } while(BackendList
[n
].name
);
1042 struct BackendInfo Bkp
= BackendList
[n
];
1045 BackendList
[n
] = BackendList
[n
-1];
1048 BackendList
[n
] = Bkp
;
1059 BackendList
[i
].name
= NULL
;
1060 BackendList
[i
].getFactory
= NULL
;
1061 BackendList
[i
].Init
= NULL
;
1062 BackendList
[i
].Deinit
= NULL
;
1063 BackendList
[i
].Probe
= NULL
;
1067 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1069 if(BackendList
[i
].getFactory
)
1071 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1072 if(!V0(factory
,init
)())
1074 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1078 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1079 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1081 PlaybackBackend
= BackendList
[i
];
1082 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1084 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1086 CaptureBackend
= BackendList
[i
];
1087 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1093 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1095 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1099 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1100 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1102 PlaybackBackend
= BackendList
[i
];
1103 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1105 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1107 CaptureBackend
= BackendList
[i
];
1108 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1112 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1116 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1119 const char *next
= str
;
1123 next
= strchr(str
, ',');
1125 if(!str
[0] || next
== str
)
1128 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1129 for(n
= 0;EffectList
[n
].name
;n
++)
1131 if(len
== strlen(EffectList
[n
].name
) &&
1132 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1133 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1138 InitEffectFactoryMap();
1140 InitEffect(&DefaultEffect
);
1141 str
= getenv("ALSOFT_DEFAULT_REVERB");
1142 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1143 LoadReverbPreset(str
, &DefaultEffect
);
1145 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1148 /************************************************
1149 * Library deinitialization
1150 ************************************************/
1151 static void alc_cleanup(void)
1155 AL_STRING_DEINIT(alcAllDevicesList
);
1156 AL_STRING_DEINIT(alcCaptureDeviceList
);
1158 free(alcDefaultAllDevicesSpecifier
);
1159 alcDefaultAllDevicesSpecifier
= NULL
;
1160 free(alcCaptureDefaultDeviceSpecifier
);
1161 alcCaptureDefaultDeviceSpecifier
= NULL
;
1163 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1168 } while((dev
=dev
->next
) != NULL
);
1169 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1172 DeinitEffectFactoryMap();
1175 static void alc_deinit_safe(void)
1183 almtx_destroy(&ListLock
);
1184 altss_delete(LocalContext
);
1186 if(LogFile
!= stderr
)
1191 static void alc_deinit(void)
1197 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1198 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1200 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1202 if(!BackendList
[i
].getFactory
)
1203 BackendList
[i
].Deinit();
1206 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1207 V0(factory
,deinit
)();
1211 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1212 V0(factory
,deinit
)();
1219 /************************************************
1220 * Device enumeration
1221 ************************************************/
1222 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1227 al_string_clear(list
);
1229 if(!backendinfo
->getFactory
)
1230 backendinfo
->Probe(type
);
1233 ALCbackendFactory
*factory
= backendinfo
->getFactory();
1234 V(factory
,probe
)(type
);
1239 static void ProbeAllDevicesList(void)
1240 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1241 static void ProbeCaptureDeviceList(void)
1242 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1244 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1246 size_t len
= strlen(name
);
1248 al_string_append_range(devnames
, name
, name
+len
+1);
1250 void AppendAllDevicesList(const ALCchar
*name
)
1251 { AppendDevice(name
, &alcAllDevicesList
); }
1252 void AppendCaptureDeviceList(const ALCchar
*name
)
1253 { AppendDevice(name
, &alcCaptureDeviceList
); }
1256 /************************************************
1257 * Device format information
1258 ************************************************/
1259 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1263 case DevFmtByte
: return "Signed Byte";
1264 case DevFmtUByte
: return "Unsigned Byte";
1265 case DevFmtShort
: return "Signed Short";
1266 case DevFmtUShort
: return "Unsigned Short";
1267 case DevFmtInt
: return "Signed Int";
1268 case DevFmtUInt
: return "Unsigned Int";
1269 case DevFmtFloat
: return "Float";
1271 return "(unknown type)";
1273 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1277 case DevFmtMono
: return "Mono";
1278 case DevFmtStereo
: return "Stereo";
1279 case DevFmtQuad
: return "Quadraphonic";
1280 case DevFmtX51
: return "5.1 Surround";
1281 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1282 case DevFmtX61
: return "6.1 Surround";
1283 case DevFmtX71
: return "7.1 Surround";
1284 case DevFmtBFormat3D
: return "B-Format 3D";
1286 return "(unknown channels)";
1289 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1290 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1294 case DevFmtByte
: return sizeof(ALbyte
);
1295 case DevFmtUByte
: return sizeof(ALubyte
);
1296 case DevFmtShort
: return sizeof(ALshort
);
1297 case DevFmtUShort
: return sizeof(ALushort
);
1298 case DevFmtInt
: return sizeof(ALint
);
1299 case DevFmtUInt
: return sizeof(ALuint
);
1300 case DevFmtFloat
: return sizeof(ALfloat
);
1304 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1308 case DevFmtMono
: return 1;
1309 case DevFmtStereo
: return 2;
1310 case DevFmtQuad
: return 4;
1311 case DevFmtX51
: return 6;
1312 case DevFmtX51Rear
: return 6;
1313 case DevFmtX61
: return 7;
1314 case DevFmtX71
: return 8;
1315 case DevFmtBFormat3D
: return 4;
1320 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1321 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1323 static const struct {
1325 enum DevFmtChannels channels
;
1326 enum DevFmtType type
;
1328 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1329 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1330 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1332 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1333 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1334 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1336 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1337 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1338 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1340 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1341 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1342 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1344 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1345 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1346 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1348 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1349 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1350 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1354 for(i
= 0;i
< COUNTOF(list
);i
++)
1356 if(list
[i
].format
== format
)
1358 *chans
= list
[i
].channels
;
1359 *type
= list
[i
].type
;
1367 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1372 case ALC_UNSIGNED_BYTE_SOFT
:
1373 case ALC_SHORT_SOFT
:
1374 case ALC_UNSIGNED_SHORT_SOFT
:
1376 case ALC_UNSIGNED_INT_SOFT
:
1377 case ALC_FLOAT_SOFT
:
1383 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1388 case ALC_STEREO_SOFT
:
1390 case ALC_5POINT1_SOFT
:
1391 case ALC_6POINT1_SOFT
:
1392 case ALC_7POINT1_SOFT
:
1399 /************************************************
1400 * Miscellaneous ALC helpers
1401 ************************************************/
1403 extern inline void LockContext(ALCcontext
*context
);
1404 extern inline void UnlockContext(ALCcontext
*context
);
1406 void ALCdevice_Lock(ALCdevice
*device
)
1408 V0(device
->Backend
,lock
)();
1411 void ALCdevice_Unlock(ALCdevice
*device
)
1413 V0(device
->Backend
,unlock
)();
1417 /* SetDefaultWFXChannelOrder
1419 * Sets the default channel order used by WaveFormatEx.
1421 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1425 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1426 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1428 switch(device
->FmtChans
)
1431 device
->RealOut
.ChannelName
[0] = FrontCenter
;
1434 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1435 device
->RealOut
.ChannelName
[1] = FrontRight
;
1438 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1439 device
->RealOut
.ChannelName
[1] = FrontRight
;
1440 device
->RealOut
.ChannelName
[2] = BackLeft
;
1441 device
->RealOut
.ChannelName
[3] = BackRight
;
1444 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1445 device
->RealOut
.ChannelName
[1] = FrontRight
;
1446 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1447 device
->RealOut
.ChannelName
[3] = LFE
;
1448 device
->RealOut
.ChannelName
[4] = SideLeft
;
1449 device
->RealOut
.ChannelName
[5] = SideRight
;
1452 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1453 device
->RealOut
.ChannelName
[1] = FrontRight
;
1454 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1455 device
->RealOut
.ChannelName
[3] = LFE
;
1456 device
->RealOut
.ChannelName
[4] = BackLeft
;
1457 device
->RealOut
.ChannelName
[5] = BackRight
;
1460 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1461 device
->RealOut
.ChannelName
[1] = FrontRight
;
1462 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1463 device
->RealOut
.ChannelName
[3] = LFE
;
1464 device
->RealOut
.ChannelName
[4] = BackCenter
;
1465 device
->RealOut
.ChannelName
[5] = SideLeft
;
1466 device
->RealOut
.ChannelName
[6] = SideRight
;
1469 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1470 device
->RealOut
.ChannelName
[1] = FrontRight
;
1471 device
->RealOut
.ChannelName
[2] = FrontCenter
;
1472 device
->RealOut
.ChannelName
[3] = LFE
;
1473 device
->RealOut
.ChannelName
[4] = BackLeft
;
1474 device
->RealOut
.ChannelName
[5] = BackRight
;
1475 device
->RealOut
.ChannelName
[6] = SideLeft
;
1476 device
->RealOut
.ChannelName
[7] = SideRight
;
1478 case DevFmtBFormat3D
:
1479 device
->RealOut
.ChannelName
[0] = Aux0
;
1480 device
->RealOut
.ChannelName
[1] = Aux1
;
1481 device
->RealOut
.ChannelName
[2] = Aux2
;
1482 device
->RealOut
.ChannelName
[3] = Aux3
;
1487 /* SetDefaultChannelOrder
1489 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1491 void SetDefaultChannelOrder(ALCdevice
*device
)
1495 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1496 device
->RealOut
.ChannelName
[i
] = InvalidChannel
;
1498 switch(device
->FmtChans
)
1501 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1502 device
->RealOut
.ChannelName
[1] = FrontRight
;
1503 device
->RealOut
.ChannelName
[2] = BackLeft
;
1504 device
->RealOut
.ChannelName
[3] = BackRight
;
1505 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1506 device
->RealOut
.ChannelName
[5] = LFE
;
1509 device
->RealOut
.ChannelName
[0] = FrontLeft
;
1510 device
->RealOut
.ChannelName
[1] = FrontRight
;
1511 device
->RealOut
.ChannelName
[2] = BackLeft
;
1512 device
->RealOut
.ChannelName
[3] = BackRight
;
1513 device
->RealOut
.ChannelName
[4] = FrontCenter
;
1514 device
->RealOut
.ChannelName
[5] = LFE
;
1515 device
->RealOut
.ChannelName
[6] = SideLeft
;
1516 device
->RealOut
.ChannelName
[7] = SideRight
;
1519 /* Same as WFX order */
1525 case DevFmtBFormat3D
:
1526 SetDefaultWFXChannelOrder(device
);
1531 extern inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
);
1534 /* ALCcontext_DeferUpdates
1536 * Defers/suspends updates for the given context's listener and sources. This
1537 * does *NOT* stop mixing, but rather prevents certain property changes from
1540 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1542 ALCdevice
*device
= context
->Device
;
1545 SetMixerFPUMode(&oldMode
);
1547 V0(device
->Backend
,lock
)();
1548 if(!context
->DeferUpdates
)
1550 context
->DeferUpdates
= AL_TRUE
;
1552 /* Make sure all pending updates are performed */
1553 UpdateContextSources(context
);
1554 #define UPDATE_SLOT(iter) do { \
1555 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1556 V((*iter)->EffectState,update)(device, *iter); \
1558 VECTOR_FOR_EACH(ALeffectslot
*, context
->ActiveAuxSlots
, UPDATE_SLOT
);
1561 V0(device
->Backend
,unlock
)();
1563 RestoreFPUMode(&oldMode
);
1566 /* ALCcontext_ProcessUpdates
1568 * Resumes update processing after being deferred.
1570 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1572 ALCdevice
*device
= context
->Device
;
1574 V0(device
->Backend
,lock
)();
1575 if(context
->DeferUpdates
)
1579 context
->DeferUpdates
= AL_FALSE
;
1581 LockUIntMapRead(&context
->SourceMap
);
1582 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1584 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1587 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1588 Source
->Offset
>= 0.0)
1590 WriteLock(&Source
->queue_lock
);
1591 ApplyOffset(Source
);
1592 WriteUnlock(&Source
->queue_lock
);
1595 new_state
= Source
->new_state
;
1596 Source
->new_state
= AL_NONE
;
1598 SetSourceState(Source
, context
, new_state
);
1600 UnlockUIntMapRead(&context
->SourceMap
);
1602 V0(device
->Backend
,unlock
)();
1608 * Stores the latest ALC device error
1610 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1615 /* DebugBreak() will cause an exception if there is no debugger */
1616 if(IsDebuggerPresent())
1618 #elif defined(SIGTRAP)
1624 ATOMIC_STORE(&device
->LastError
, errorCode
);
1626 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1632 * Updates the device's base clock time with however many samples have been
1633 * done. This is used so frequency changes on the device don't cause the time
1634 * to jump forward or back.
1636 static inline void UpdateClockBase(ALCdevice
*device
)
1638 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1639 device
->SamplesDone
= 0;
1642 /* UpdateDeviceParams
1644 * Updates device parameters according to the attribute list (caller is
1645 * responsible for holding the list lock).
1647 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1649 ALCcontext
*context
;
1650 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1651 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1652 enum DevFmtChannels oldChans
;
1653 enum DevFmtType oldType
;
1656 ALCsizei hrtf_id
= -1;
1659 // Check for attributes
1660 if(device
->Type
== Loopback
)
1666 GotAll
= GotFreq
|GotChans
|GotType
1668 ALCuint freq
, numMono
, numStereo
, numSends
;
1669 enum DevFmtChannels schans
;
1670 enum DevFmtType stype
;
1671 ALCuint attrIdx
= 0;
1676 WARN("Missing attributes for loopback device\n");
1677 return ALC_INVALID_VALUE
;
1680 numMono
= device
->NumMonoSources
;
1681 numStereo
= device
->NumStereoSources
;
1682 numSends
= device
->NumAuxSends
;
1683 schans
= device
->FmtChans
;
1684 stype
= device
->FmtType
;
1685 freq
= device
->Frequency
;
1687 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1688 while(attrList
[attrIdx
])
1690 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1692 ALCint val
= attrList
[attrIdx
+ 1];
1693 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT
, val
);
1694 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1695 return ALC_INVALID_VALUE
;
1700 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1702 ALCint val
= attrList
[attrIdx
+ 1];
1703 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT
, val
);
1704 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1705 return ALC_INVALID_VALUE
;
1710 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1712 freq
= attrList
[attrIdx
+ 1];
1713 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1714 if(freq
< MIN_OUTPUT_RATE
)
1715 return ALC_INVALID_VALUE
;
1719 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1721 numStereo
= attrList
[attrIdx
+ 1];
1722 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1723 if(numStereo
> device
->MaxNoOfSources
)
1724 numStereo
= device
->MaxNoOfSources
;
1726 numMono
= device
->MaxNoOfSources
- numStereo
;
1729 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1731 numSends
= attrList
[attrIdx
+ 1];
1732 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1735 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1737 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1738 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1739 hrtf_appreq
= Hrtf_Disable
;
1740 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1741 hrtf_appreq
= Hrtf_Enable
;
1743 hrtf_appreq
= Hrtf_Default
;
1746 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1748 hrtf_id
= attrList
[attrIdx
+ 1];
1749 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1756 if(gotFmt
!= GotAll
)
1758 WARN("Missing format for loopback device\n");
1759 return ALC_INVALID_VALUE
;
1762 ConfigValueUInt(NULL
, NULL
, "sends", &numSends
);
1763 numSends
= minu(MAX_SENDS
, numSends
);
1765 if((device
->Flags
&DEVICE_RUNNING
))
1766 V0(device
->Backend
,stop
)();
1767 device
->Flags
&= ~DEVICE_RUNNING
;
1769 UpdateClockBase(device
);
1771 device
->Frequency
= freq
;
1772 device
->FmtChans
= schans
;
1773 device
->FmtType
= stype
;
1774 device
->NumMonoSources
= numMono
;
1775 device
->NumStereoSources
= numStereo
;
1776 device
->NumAuxSends
= numSends
;
1778 else if(attrList
&& attrList
[0])
1780 ALCuint freq
, numMono
, numStereo
, numSends
;
1781 ALCuint attrIdx
= 0;
1783 /* If a context is already running on the device, stop playback so the
1784 * device attributes can be updated. */
1785 if((device
->Flags
&DEVICE_RUNNING
))
1786 V0(device
->Backend
,stop
)();
1787 device
->Flags
&= ~DEVICE_RUNNING
;
1789 freq
= device
->Frequency
;
1790 numMono
= device
->NumMonoSources
;
1791 numStereo
= device
->NumStereoSources
;
1792 numSends
= device
->NumAuxSends
;
1794 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1795 while(attrList
[attrIdx
])
1797 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1799 freq
= attrList
[attrIdx
+ 1];
1800 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1801 TRACE_ATTR(ALC_FREQUENCY
, freq
);
1804 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1806 numStereo
= attrList
[attrIdx
+ 1];
1807 TRACE_ATTR(ALC_STEREO_SOURCES
, numStereo
);
1808 if(numStereo
> device
->MaxNoOfSources
)
1809 numStereo
= device
->MaxNoOfSources
;
1811 numMono
= device
->MaxNoOfSources
- numStereo
;
1814 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1816 numSends
= attrList
[attrIdx
+ 1];
1817 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS
, numSends
);
1820 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1822 TRACE_ATTR(ALC_HRTF_SOFT
, attrList
[attrIdx
+ 1]);
1823 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1824 hrtf_appreq
= Hrtf_Disable
;
1825 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1826 hrtf_appreq
= Hrtf_Enable
;
1828 hrtf_appreq
= Hrtf_Default
;
1831 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1833 hrtf_id
= attrList
[attrIdx
+ 1];
1834 TRACE_ATTR(ALC_HRTF_ID_SOFT
, hrtf_id
);
1841 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1842 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1844 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1845 numSends
= minu(MAX_SENDS
, numSends
);
1847 UpdateClockBase(device
);
1849 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1851 /* SSE and Neon do best with the update size being a multiple of 4 */
1852 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1853 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1855 device
->Frequency
= freq
;
1856 device
->NumMonoSources
= numMono
;
1857 device
->NumStereoSources
= numStereo
;
1858 device
->NumAuxSends
= numSends
;
1861 if((device
->Flags
&DEVICE_RUNNING
))
1862 return ALC_NO_ERROR
;
1864 al_free(device
->Uhj_Encoder
);
1865 device
->Uhj_Encoder
= NULL
;
1867 al_free(device
->Bs2b
);
1868 device
->Bs2b
= NULL
;
1870 al_free(device
->Dry
.Buffer
);
1871 device
->Dry
.Buffer
= NULL
;
1872 device
->Dry
.NumChannels
= 0;
1873 device
->VirtOut
.Buffer
= NULL
;
1874 device
->VirtOut
.NumChannels
= 0;
1875 device
->RealOut
.Buffer
= NULL
;
1876 device
->RealOut
.NumChannels
= 0;
1878 UpdateClockBase(device
);
1880 /*************************************************************************
1881 * Update device format request if HRTF is requested
1883 device
->Hrtf_Status
= ALC_HRTF_DISABLED_SOFT
;
1884 if(device
->Type
!= Loopback
)
1887 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
1889 if(strcasecmp(hrtf
, "true") == 0)
1890 hrtf_userreq
= Hrtf_Enable
;
1891 else if(strcasecmp(hrtf
, "false") == 0)
1892 hrtf_userreq
= Hrtf_Disable
;
1893 else if(strcasecmp(hrtf
, "auto") != 0)
1894 ERR("Unexpected hrtf value: %s\n", hrtf
);
1897 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
1899 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1901 VECTOR_DEINIT(device
->Hrtf_List
);
1902 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1904 if(VECTOR_SIZE(device
->Hrtf_List
) > 0)
1906 device
->FmtChans
= DevFmtStereo
;
1907 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
1908 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
).hrtf
);
1910 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, 0).hrtf
);
1911 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
1915 hrtf_userreq
= Hrtf_Default
;
1916 hrtf_appreq
= Hrtf_Disable
;
1917 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1921 else if(hrtf_appreq
== Hrtf_Enable
)
1923 size_t i
= VECTOR_SIZE(device
->Hrtf_List
);
1924 /* Loopback device. We don't need to match to a specific HRTF entry
1925 * here. If the requested ID matches, we'll pick that later, if not,
1926 * we'll try to auto-select one anyway. Just make sure one exists
1929 if(device
->FmtChans
== DevFmtStereo
)
1931 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1933 VECTOR_DEINIT(device
->Hrtf_List
);
1934 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1936 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
1938 const struct Hrtf
*hrtf
= VECTOR_ELEM(device
->Hrtf_List
, i
).hrtf
;
1939 if(GetHrtfSampleRate(hrtf
) == device
->Frequency
)
1943 if(i
== VECTOR_SIZE(device
->Hrtf_List
))
1945 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1946 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1947 hrtf_appreq
= Hrtf_Disable
;
1948 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1952 oldFreq
= device
->Frequency
;
1953 oldChans
= device
->FmtChans
;
1954 oldType
= device
->FmtType
;
1956 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1957 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1958 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1959 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1960 device
->UpdateSize
, device
->NumUpdates
1963 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1964 return ALC_INVALID_DEVICE
;
1966 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1968 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1969 DevFmtChannelsString(device
->FmtChans
));
1970 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1972 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1974 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1975 DevFmtTypeString(device
->FmtType
));
1976 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1978 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1980 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1981 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1984 if((device
->UpdateSize
&3) != 0)
1986 if((CPUCapFlags
&CPU_CAP_SSE
))
1987 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1988 if((CPUCapFlags
&CPU_CAP_NEON
))
1989 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1992 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1993 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1994 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1997 aluInitRenderer(device
, hrtf_id
, hrtf_appreq
, hrtf_userreq
);
1999 /* Allocate extra channels for any post-filter output. */
2000 size
= device
->Dry
.NumChannels
* sizeof(device
->Dry
.Buffer
[0]);
2001 if(device
->AmbiDecoder
&& bformatdec_getOrder(device
->AmbiDecoder
) >= 2)
2002 size
+= (ChannelsFromDevFmt(device
->FmtChans
)+4) * sizeof(device
->Dry
.Buffer
[0]);
2003 else if(device
->Hrtf
|| device
->Uhj_Encoder
|| device
->AmbiDecoder
)
2004 size
+= ChannelsFromDevFmt(device
->FmtChans
) * sizeof(device
->Dry
.Buffer
[0]);
2005 device
->Dry
.Buffer
= al_calloc(16, size
);
2006 if(!device
->Dry
.Buffer
)
2008 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2009 return ALC_INVALID_DEVICE
;
2012 if(device
->Hrtf
|| device
->Uhj_Encoder
|| device
->AmbiDecoder
)
2014 device
->VirtOut
.Buffer
= device
->Dry
.Buffer
;
2015 device
->VirtOut
.NumChannels
= device
->Dry
.NumChannels
;
2016 device
->RealOut
.Buffer
= device
->Dry
.Buffer
+ device
->Dry
.NumChannels
;
2017 device
->RealOut
.NumChannels
= ChannelsFromDevFmt(device
->FmtChans
);
2021 device
->VirtOut
.Buffer
= NULL
;
2022 device
->VirtOut
.NumChannels
= 0;
2023 device
->RealOut
.Buffer
= device
->Dry
.Buffer
;
2024 device
->RealOut
.NumChannels
= device
->Dry
.NumChannels
;
2027 if(device
->AmbiDecoder
&& bformatdec_getOrder(device
->AmbiDecoder
) >= 2)
2029 /* Higher-order high quality decoding requires upsampling first-order
2030 * content, so make sure to mix it separately.
2032 device
->FOAOut
.Buffer
= device
->RealOut
.Buffer
+ device
->RealOut
.NumChannels
;
2033 device
->FOAOut
.NumChannels
= 4;
2037 device
->FOAOut
.Buffer
= device
->Dry
.Buffer
;
2038 device
->FOAOut
.NumChannels
= device
->Dry
.NumChannels
;
2041 SetMixerFPUMode(&oldMode
);
2042 V0(device
->Backend
,lock
)();
2043 context
= ATOMIC_LOAD(&device
->ContextList
);
2048 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2049 LockUIntMapRead(&context
->EffectSlotMap
);
2050 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2052 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2054 slot
->EffectState
->OutBuffer
= device
->Dry
.Buffer
;
2055 slot
->EffectState
->OutChannels
= device
->Dry
.NumChannels
;
2056 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2058 UnlockUIntMapRead(&context
->EffectSlotMap
);
2059 V0(device
->Backend
,unlock
)();
2060 RestoreFPUMode(&oldMode
);
2061 return ALC_INVALID_DEVICE
;
2063 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2064 V(slot
->EffectState
,update
)(device
, slot
);
2066 UnlockUIntMapRead(&context
->EffectSlotMap
);
2068 LockUIntMapRead(&context
->SourceMap
);
2069 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2071 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2072 ALuint s
= device
->NumAuxSends
;
2073 while(s
< MAX_SENDS
)
2075 if(source
->Send
[s
].Slot
)
2076 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2077 source
->Send
[s
].Slot
= NULL
;
2078 source
->Send
[s
].Gain
= 1.0f
;
2079 source
->Send
[s
].GainHF
= 1.0f
;
2082 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2084 UnlockUIntMapRead(&context
->SourceMap
);
2086 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2088 ALvoice
*voice
= &context
->Voices
[pos
];
2089 ALsource
*source
= voice
->Source
;
2093 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2094 voice
->Update(voice
, source
, context
);
2098 context
= context
->next
;
2100 if(device
->DefaultSlot
)
2102 ALeffectslot
*slot
= device
->DefaultSlot
;
2103 ALeffectState
*state
= slot
->EffectState
;
2105 state
->OutBuffer
= device
->Dry
.Buffer
;
2106 state
->OutChannels
= device
->Dry
.NumChannels
;
2107 if(V(state
,deviceUpdate
)(device
) == AL_FALSE
)
2109 V0(device
->Backend
,unlock
)();
2110 RestoreFPUMode(&oldMode
);
2111 return ALC_INVALID_DEVICE
;
2113 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2114 V(slot
->EffectState
,update
)(device
, slot
);
2116 V0(device
->Backend
,unlock
)();
2117 RestoreFPUMode(&oldMode
);
2119 if(!(device
->Flags
&DEVICE_PAUSED
))
2121 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2122 return ALC_INVALID_DEVICE
;
2123 device
->Flags
|= DEVICE_RUNNING
;
2126 return ALC_NO_ERROR
;
2131 * Frees the device structure, and destroys any objects the app failed to
2132 * delete. Called once there's no more references on the device.
2134 static ALCvoid
FreeDevice(ALCdevice
*device
)
2136 TRACE("%p\n", device
);
2138 V0(device
->Backend
,close
)();
2139 DELETE_OBJ(device
->Backend
);
2140 device
->Backend
= NULL
;
2142 if(device
->DefaultSlot
)
2144 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2145 device
->DefaultSlot
= NULL
;
2149 if(device
->BufferMap
.size
> 0)
2151 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2152 ReleaseALBuffers(device
);
2154 ResetUIntMap(&device
->BufferMap
);
2156 if(device
->EffectMap
.size
> 0)
2158 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2159 ReleaseALEffects(device
);
2161 ResetUIntMap(&device
->EffectMap
);
2163 if(device
->FilterMap
.size
> 0)
2165 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2166 ReleaseALFilters(device
);
2168 ResetUIntMap(&device
->FilterMap
);
2170 AL_STRING_DEINIT(device
->Hrtf_Name
);
2171 FreeHrtfList(&device
->Hrtf_List
);
2173 al_free(device
->Bs2b
);
2174 device
->Bs2b
= NULL
;
2176 al_free(device
->Uhj_Encoder
);
2177 device
->Uhj_Encoder
= NULL
;
2179 bformatdec_free(device
->AmbiDecoder
);
2180 device
->AmbiDecoder
= NULL
;
2182 AL_STRING_DEINIT(device
->DeviceName
);
2184 al_free(device
->Dry
.Buffer
);
2185 device
->Dry
.Buffer
= NULL
;
2186 device
->Dry
.NumChannels
= 0;
2187 device
->VirtOut
.Buffer
= NULL
;
2188 device
->VirtOut
.NumChannels
= 0;
2189 device
->RealOut
.Buffer
= NULL
;
2190 device
->RealOut
.NumChannels
= 0;
2196 void ALCdevice_IncRef(ALCdevice
*device
)
2199 ref
= IncrementRef(&device
->ref
);
2200 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2203 void ALCdevice_DecRef(ALCdevice
*device
)
2206 ref
= DecrementRef(&device
->ref
);
2207 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2208 if(ref
== 0) FreeDevice(device
);
2213 * Checks if the device handle is valid, and increments its ref count if so.
2215 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2217 ALCdevice
*tmpDevice
;
2220 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2223 if(tmpDevice
== *device
)
2225 ALCdevice_IncRef(tmpDevice
);
2229 tmpDevice
= tmpDevice
->next
;
2240 * Initializes context fields
2242 static ALvoid
InitContext(ALCcontext
*Context
)
2244 ALlistener
*listener
= Context
->Listener
;
2245 //Initialise listener
2246 listener
->Gain
= 1.0f
;
2247 listener
->MetersPerUnit
= 1.0f
;
2248 aluVectorSet(&listener
->Position
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
2249 aluVectorSet(&listener
->Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2250 listener
->Forward
[0] = 0.0f
;
2251 listener
->Forward
[1] = 0.0f
;
2252 listener
->Forward
[2] = -1.0f
;
2253 listener
->Up
[0] = 0.0f
;
2254 listener
->Up
[1] = 1.0f
;
2255 listener
->Up
[2] = 0.0f
;
2256 aluMatrixdSet(&listener
->Params
.Matrix
,
2262 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2265 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2266 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2267 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2268 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2271 Context
->DistanceModel
= DefaultDistanceModel
;
2272 Context
->SourceDistanceModel
= AL_FALSE
;
2273 Context
->DopplerFactor
= 1.0f
;
2274 Context
->DopplerVelocity
= 1.0f
;
2275 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2276 Context
->DeferUpdates
= AL_FALSE
;
2278 Context
->ExtensionList
= alExtList
;
2284 * Cleans up the context, and destroys any remaining objects the app failed to
2285 * delete. Called once there's no more references on the context.
2287 static void FreeContext(ALCcontext
*context
)
2289 TRACE("%p\n", context
);
2291 if(context
->SourceMap
.size
> 0)
2293 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2294 ReleaseALSources(context
);
2296 ResetUIntMap(&context
->SourceMap
);
2298 if(context
->EffectSlotMap
.size
> 0)
2300 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2301 ReleaseALAuxiliaryEffectSlots(context
);
2303 ResetUIntMap(&context
->EffectSlotMap
);
2305 al_free(context
->Voices
);
2306 context
->Voices
= NULL
;
2307 context
->VoiceCount
= 0;
2308 context
->MaxVoices
= 0;
2310 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2312 ALCdevice_DecRef(context
->Device
);
2313 context
->Device
= NULL
;
2315 //Invalidate context
2316 memset(context
, 0, sizeof(ALCcontext
));
2322 * Removes the context reference from the given device and removes it from
2323 * being current on the running thread or globally.
2325 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2327 ALCcontext
*nextctx
;
2328 ALCcontext
*origctx
;
2330 if(altss_get(LocalContext
) == context
)
2332 WARN("%p released while current on thread\n", context
);
2333 altss_set(LocalContext
, NULL
);
2334 ALCcontext_DecRef(context
);
2338 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2339 ALCcontext_DecRef(context
);
2341 ALCdevice_Lock(device
);
2343 nextctx
= context
->next
;
2344 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2350 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2352 ALCdevice_Unlock(device
);
2354 ALCcontext_DecRef(context
);
2357 void ALCcontext_IncRef(ALCcontext
*context
)
2360 ref
= IncrementRef(&context
->ref
);
2361 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2364 void ALCcontext_DecRef(ALCcontext
*context
)
2367 ref
= DecrementRef(&context
->ref
);
2368 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2369 if(ref
== 0) FreeContext(context
);
2372 static void ReleaseThreadCtx(void *ptr
)
2374 WARN("%p current for thread being destroyed\n", ptr
);
2375 ALCcontext_DecRef(ptr
);
2380 * Checks that the given context is valid, and increments its reference count.
2382 static ALCboolean
VerifyContext(ALCcontext
**context
)
2387 dev
= ATOMIC_LOAD(&DeviceList
);
2390 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2395 ALCcontext_IncRef(ctx
);
2412 * Returns the currently active context for this thread, and adds a reference
2413 * without locking it.
2415 ALCcontext
*GetContextRef(void)
2417 ALCcontext
*context
;
2419 context
= altss_get(LocalContext
);
2421 ALCcontext_IncRef(context
);
2425 context
= ATOMIC_LOAD(&GlobalContext
);
2427 ALCcontext_IncRef(context
);
2435 /************************************************
2436 * Standard ALC functions
2437 ************************************************/
2441 * Return last ALC generated error code for the given device
2443 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2447 if(VerifyDevice(&device
))
2449 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2450 ALCdevice_DecRef(device
);
2453 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2459 /* alcSuspendContext
2461 * Suspends updates for the given context
2463 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2468 if(!VerifyContext(&context
))
2469 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2472 ALCcontext_DeferUpdates(context
);
2473 ALCcontext_DecRef(context
);
2477 /* alcProcessContext
2479 * Resumes processing updates for the given context
2481 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2486 if(!VerifyContext(&context
))
2487 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2490 ALCcontext_ProcessUpdates(context
);
2491 ALCcontext_DecRef(context
);
2498 * Returns information about the device, and error strings
2500 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2502 const ALCchar
*value
= NULL
;
2510 case ALC_INVALID_ENUM
:
2511 value
= alcErrInvalidEnum
;
2514 case ALC_INVALID_VALUE
:
2515 value
= alcErrInvalidValue
;
2518 case ALC_INVALID_DEVICE
:
2519 value
= alcErrInvalidDevice
;
2522 case ALC_INVALID_CONTEXT
:
2523 value
= alcErrInvalidContext
;
2526 case ALC_OUT_OF_MEMORY
:
2527 value
= alcErrOutOfMemory
;
2530 case ALC_DEVICE_SPECIFIER
:
2531 value
= alcDefaultName
;
2534 case ALC_ALL_DEVICES_SPECIFIER
:
2535 if(VerifyDevice(&Device
))
2537 value
= al_string_get_cstr(Device
->DeviceName
);
2538 ALCdevice_DecRef(Device
);
2542 ProbeAllDevicesList();
2543 value
= al_string_get_cstr(alcAllDevicesList
);
2547 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2548 if(VerifyDevice(&Device
))
2550 value
= al_string_get_cstr(Device
->DeviceName
);
2551 ALCdevice_DecRef(Device
);
2555 ProbeCaptureDeviceList();
2556 value
= al_string_get_cstr(alcCaptureDeviceList
);
2560 /* Default devices are always first in the list */
2561 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2562 value
= alcDefaultName
;
2565 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2566 if(al_string_empty(alcAllDevicesList
))
2567 ProbeAllDevicesList();
2569 VerifyDevice(&Device
);
2571 free(alcDefaultAllDevicesSpecifier
);
2572 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2573 if(!alcDefaultAllDevicesSpecifier
)
2574 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2576 value
= alcDefaultAllDevicesSpecifier
;
2577 if(Device
) ALCdevice_DecRef(Device
);
2580 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2581 if(al_string_empty(alcCaptureDeviceList
))
2582 ProbeCaptureDeviceList();
2584 VerifyDevice(&Device
);
2586 free(alcCaptureDefaultDeviceSpecifier
);
2587 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2588 if(!alcCaptureDefaultDeviceSpecifier
)
2589 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2591 value
= alcCaptureDefaultDeviceSpecifier
;
2592 if(Device
) ALCdevice_DecRef(Device
);
2595 case ALC_EXTENSIONS
:
2596 if(!VerifyDevice(&Device
))
2597 value
= alcNoDeviceExtList
;
2600 value
= alcExtensionList
;
2601 ALCdevice_DecRef(Device
);
2605 case ALC_HRTF_SPECIFIER_SOFT
:
2606 if(!VerifyDevice(&Device
))
2607 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2611 value
= (Device
->Hrtf
? al_string_get_cstr(Device
->Hrtf_Name
) : "");
2613 ALCdevice_DecRef(Device
);
2618 VerifyDevice(&Device
);
2619 alcSetError(Device
, ALC_INVALID_ENUM
);
2620 if(Device
) ALCdevice_DecRef(Device
);
2628 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2632 if(size
<= 0 || values
== NULL
)
2634 alcSetError(device
, ALC_INVALID_VALUE
);
2642 case ALC_MAJOR_VERSION
:
2643 values
[0] = alcMajorVersion
;
2645 case ALC_MINOR_VERSION
:
2646 values
[0] = alcMinorVersion
;
2649 case ALC_ATTRIBUTES_SIZE
:
2650 case ALC_ALL_ATTRIBUTES
:
2654 case ALC_MONO_SOURCES
:
2655 case ALC_STEREO_SOURCES
:
2656 case ALC_CAPTURE_SAMPLES
:
2657 case ALC_FORMAT_CHANNELS_SOFT
:
2658 case ALC_FORMAT_TYPE_SOFT
:
2659 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2663 alcSetError(NULL
, ALC_INVALID_ENUM
);
2669 if(device
->Type
== Capture
)
2673 case ALC_CAPTURE_SAMPLES
:
2674 V0(device
->Backend
,lock
)();
2675 values
[0] = V0(device
->Backend
,availableSamples
)();
2676 V0(device
->Backend
,unlock
)();
2680 values
[0] = device
->Connected
;
2684 alcSetError(device
, ALC_INVALID_ENUM
);
2693 case ALC_MAJOR_VERSION
:
2694 values
[0] = alcMajorVersion
;
2697 case ALC_MINOR_VERSION
:
2698 values
[0] = alcMinorVersion
;
2701 case ALC_EFX_MAJOR_VERSION
:
2702 values
[0] = alcEFXMajorVersion
;
2705 case ALC_EFX_MINOR_VERSION
:
2706 values
[0] = alcEFXMinorVersion
;
2709 case ALC_ATTRIBUTES_SIZE
:
2713 case ALC_ALL_ATTRIBUTES
:
2716 alcSetError(device
, ALC_INVALID_VALUE
);
2721 values
[i
++] = ALC_FREQUENCY
;
2722 values
[i
++] = device
->Frequency
;
2724 if(device
->Type
!= Loopback
)
2726 values
[i
++] = ALC_REFRESH
;
2727 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2729 values
[i
++] = ALC_SYNC
;
2730 values
[i
++] = ALC_FALSE
;
2734 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2735 values
[i
++] = device
->FmtChans
;
2737 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2738 values
[i
++] = device
->FmtType
;
2741 values
[i
++] = ALC_MONO_SOURCES
;
2742 values
[i
++] = device
->NumMonoSources
;
2744 values
[i
++] = ALC_STEREO_SOURCES
;
2745 values
[i
++] = device
->NumStereoSources
;
2747 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2748 values
[i
++] = device
->NumAuxSends
;
2750 values
[i
++] = ALC_HRTF_SOFT
;
2751 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2753 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2754 values
[i
++] = device
->Hrtf_Status
;
2760 values
[0] = device
->Frequency
;
2764 if(device
->Type
== Loopback
)
2766 alcSetError(device
, ALC_INVALID_DEVICE
);
2769 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2773 if(device
->Type
== Loopback
)
2775 alcSetError(device
, ALC_INVALID_DEVICE
);
2778 values
[0] = ALC_FALSE
;
2781 case ALC_FORMAT_CHANNELS_SOFT
:
2782 if(device
->Type
!= Loopback
)
2784 alcSetError(device
, ALC_INVALID_DEVICE
);
2787 values
[0] = device
->FmtChans
;
2790 case ALC_FORMAT_TYPE_SOFT
:
2791 if(device
->Type
!= Loopback
)
2793 alcSetError(device
, ALC_INVALID_DEVICE
);
2796 values
[0] = device
->FmtType
;
2799 case ALC_MONO_SOURCES
:
2800 values
[0] = device
->NumMonoSources
;
2803 case ALC_STEREO_SOURCES
:
2804 values
[0] = device
->NumStereoSources
;
2807 case ALC_MAX_AUXILIARY_SENDS
:
2808 values
[0] = device
->NumAuxSends
;
2812 values
[0] = device
->Connected
;
2816 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2819 case ALC_HRTF_STATUS_SOFT
:
2820 values
[0] = device
->Hrtf_Status
;
2823 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
2824 FreeHrtfList(&device
->Hrtf_List
);
2825 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2826 values
[0] = (ALCint
)VECTOR_SIZE(device
->Hrtf_List
);
2830 alcSetError(device
, ALC_INVALID_ENUM
);
2838 * Returns information about the device and the version of OpenAL
2840 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2842 VerifyDevice(&device
);
2843 if(size
<= 0 || values
== NULL
)
2844 alcSetError(device
, ALC_INVALID_VALUE
);
2846 GetIntegerv(device
, param
, size
, values
);
2847 if(device
) ALCdevice_DecRef(device
);
2850 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2855 VerifyDevice(&device
);
2856 if(size
<= 0 || values
== NULL
)
2857 alcSetError(device
, ALC_INVALID_VALUE
);
2858 else if(!device
|| device
->Type
== Capture
)
2860 ivals
= malloc(size
* sizeof(ALCint
));
2861 size
= GetIntegerv(device
, pname
, size
, ivals
);
2862 for(i
= 0;i
< size
;i
++)
2863 values
[i
] = ivals
[i
];
2866 else /* render device */
2870 case ALC_ATTRIBUTES_SIZE
:
2874 case ALC_ALL_ATTRIBUTES
:
2876 alcSetError(device
, ALC_INVALID_VALUE
);
2881 V0(device
->Backend
,lock
)();
2882 values
[i
++] = ALC_FREQUENCY
;
2883 values
[i
++] = device
->Frequency
;
2885 if(device
->Type
!= Loopback
)
2887 values
[i
++] = ALC_REFRESH
;
2888 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2890 values
[i
++] = ALC_SYNC
;
2891 values
[i
++] = ALC_FALSE
;
2895 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2896 values
[i
++] = device
->FmtChans
;
2898 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2899 values
[i
++] = device
->FmtType
;
2902 values
[i
++] = ALC_MONO_SOURCES
;
2903 values
[i
++] = device
->NumMonoSources
;
2905 values
[i
++] = ALC_STEREO_SOURCES
;
2906 values
[i
++] = device
->NumStereoSources
;
2908 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2909 values
[i
++] = device
->NumAuxSends
;
2911 values
[i
++] = ALC_HRTF_SOFT
;
2912 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2914 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2915 values
[i
++] = device
->Hrtf_Status
;
2917 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2918 values
[i
++] = device
->ClockBase
+
2919 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2922 V0(device
->Backend
,unlock
)();
2926 case ALC_DEVICE_CLOCK_SOFT
:
2927 V0(device
->Backend
,lock
)();
2928 *values
= device
->ClockBase
+
2929 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2930 V0(device
->Backend
,unlock
)();
2934 ivals
= malloc(size
* sizeof(ALCint
));
2935 size
= GetIntegerv(device
, pname
, size
, ivals
);
2936 for(i
= 0;i
< size
;i
++)
2937 values
[i
] = ivals
[i
];
2943 ALCdevice_DecRef(device
);
2947 /* alcIsExtensionPresent
2949 * Determines if there is support for a particular extension
2951 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
2953 ALCboolean bResult
= ALC_FALSE
;
2955 VerifyDevice(&device
);
2958 alcSetError(device
, ALC_INVALID_VALUE
);
2961 size_t len
= strlen(extName
);
2962 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
2965 if(strncasecmp(ptr
, extName
, len
) == 0 &&
2966 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
2971 if((ptr
=strchr(ptr
, ' ')) != NULL
)
2975 } while(isspace(*ptr
));
2980 ALCdevice_DecRef(device
);
2985 /* alcGetProcAddress
2987 * Retrieves the function address for a particular extension function
2989 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
2991 ALCvoid
*ptr
= NULL
;
2995 VerifyDevice(&device
);
2996 alcSetError(device
, ALC_INVALID_VALUE
);
2997 if(device
) ALCdevice_DecRef(device
);
3002 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3004 ptr
= alcFunctions
[i
].address
;
3013 * Get the value for a particular ALC enumeration name
3015 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3021 VerifyDevice(&device
);
3022 alcSetError(device
, ALC_INVALID_VALUE
);
3023 if(device
) ALCdevice_DecRef(device
);
3028 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3030 val
= enumeration
[i
].value
;
3039 * Create and attach a context to the given device.
3041 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3043 ALCcontext
*ALContext
;
3047 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3050 alcSetError(device
, ALC_INVALID_DEVICE
);
3051 if(device
) ALCdevice_DecRef(device
);
3055 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3057 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3060 alcSetError(device
, err
);
3061 if(err
== ALC_INVALID_DEVICE
)
3063 V0(device
->Backend
,lock
)();
3064 aluHandleDisconnect(device
);
3065 V0(device
->Backend
,unlock
)();
3067 ALCdevice_DecRef(device
);
3071 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3074 InitRef(&ALContext
->ref
, 1);
3075 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3077 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3079 ALContext
->VoiceCount
= 0;
3080 ALContext
->MaxVoices
= 256;
3081 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3083 if(!ALContext
|| !ALContext
->Voices
)
3085 if(!ATOMIC_LOAD(&device
->ContextList
))
3087 V0(device
->Backend
,stop
)();
3088 device
->Flags
&= ~DEVICE_RUNNING
;
3094 al_free(ALContext
->Voices
);
3095 ALContext
->Voices
= NULL
;
3097 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3103 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3104 ALCdevice_DecRef(device
);
3108 ALContext
->Device
= device
;
3109 ALCdevice_IncRef(device
);
3110 InitContext(ALContext
);
3113 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3115 ALContext
->next
= head
;
3116 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3120 ALCdevice_DecRef(device
);
3122 TRACE("Created context %p\n", ALContext
);
3126 /* alcDestroyContext
3128 * Remove a context from its device
3130 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3135 /* alcGetContextsDevice sets an error for invalid contexts */
3136 Device
= alcGetContextsDevice(context
);
3139 ReleaseContext(context
, Device
);
3140 if(!ATOMIC_LOAD(&Device
->ContextList
))
3142 V0(Device
->Backend
,stop
)();
3143 Device
->Flags
&= ~DEVICE_RUNNING
;
3150 /* alcGetCurrentContext
3152 * Returns the currently active context on the calling thread
3154 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3156 ALCcontext
*Context
= altss_get(LocalContext
);
3157 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3161 /* alcGetThreadContext
3163 * Returns the currently active thread-local context
3165 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3167 return altss_get(LocalContext
);
3171 /* alcMakeContextCurrent
3173 * Makes the given context the active process-wide context, and removes the
3174 * thread-local context for the calling thread.
3176 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3178 /* context must be valid or NULL */
3179 if(context
&& !VerifyContext(&context
))
3181 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3184 /* context's reference count is already incremented */
3185 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3186 if(context
) ALCcontext_DecRef(context
);
3188 if((context
=altss_get(LocalContext
)) != NULL
)
3190 altss_set(LocalContext
, NULL
);
3191 ALCcontext_DecRef(context
);
3197 /* alcSetThreadContext
3199 * Makes the given context the active context for the current thread
3201 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3205 /* context must be valid or NULL */
3206 if(context
&& !VerifyContext(&context
))
3208 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3211 /* context's reference count is already incremented */
3212 old
= altss_get(LocalContext
);
3213 altss_set(LocalContext
, context
);
3214 if(old
) ALCcontext_DecRef(old
);
3220 /* alcGetContextsDevice
3222 * Returns the device that a particular context is attached to
3224 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3228 if(!VerifyContext(&Context
))
3230 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3233 Device
= Context
->Device
;
3234 ALCcontext_DecRef(Context
);
3242 * Opens the named device.
3244 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3252 if(!PlaybackBackend
.name
)
3254 alcSetError(NULL
, ALC_INVALID_VALUE
);
3258 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3260 /* Some old Windows apps hardcode these expecting OpenAL to use a
3261 * specific audio API, even when they're not enumerated. Creative's
3262 * router effectively ignores them too.
3264 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3265 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3270 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3273 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3278 InitRef(&device
->ref
, 1);
3279 device
->Connected
= ALC_TRUE
;
3280 device
->Type
= Playback
;
3281 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3284 device
->Bs2b
= NULL
;
3285 device
->Uhj_Encoder
= NULL
;
3286 VECTOR_INIT(device
->Hrtf_List
);
3287 AL_STRING_INIT(device
->Hrtf_Name
);
3288 device
->Render_Mode
= NormalRender
;
3289 AL_STRING_INIT(device
->DeviceName
);
3290 device
->Dry
.Buffer
= NULL
;
3291 device
->Dry
.NumChannels
= 0;
3292 device
->VirtOut
.Buffer
= NULL
;
3293 device
->VirtOut
.NumChannels
= 0;
3294 device
->RealOut
.Buffer
= NULL
;
3295 device
->RealOut
.NumChannels
= 0;
3297 ATOMIC_INIT(&device
->ContextList
, NULL
);
3299 device
->ClockBase
= 0;
3300 device
->SamplesDone
= 0;
3302 device
->MaxNoOfSources
= 256;
3303 device
->AuxiliaryEffectSlotMax
= 4;
3304 device
->NumAuxSends
= MAX_SENDS
;
3306 InitUIntMap(&device
->BufferMap
, ~0);
3307 InitUIntMap(&device
->EffectMap
, ~0);
3308 InitUIntMap(&device
->FilterMap
, ~0);
3311 device
->FmtChans
= DevFmtChannelsDefault
;
3312 device
->FmtType
= DevFmtTypeDefault
;
3313 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3314 device
->IsHeadphones
= AL_FALSE
;
3315 device
->NumUpdates
= 4;
3316 device
->UpdateSize
= 1024;
3318 if(!PlaybackBackend
.getFactory
)
3319 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3320 ALCbackend_Playback
);
3323 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3324 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3326 if(!device
->Backend
)
3329 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3334 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3336 static const struct {
3337 const char name
[16];
3338 enum DevFmtChannels chans
;
3340 { "mono", DevFmtMono
},
3341 { "stereo", DevFmtStereo
},
3342 { "quad", DevFmtQuad
},
3343 { "surround51", DevFmtX51
},
3344 { "surround61", DevFmtX61
},
3345 { "surround71", DevFmtX71
},
3346 { "surround51rear", DevFmtX51Rear
},
3350 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3352 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3354 device
->FmtChans
= chanlist
[i
].chans
;
3355 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3359 if(i
== COUNTOF(chanlist
))
3360 ERR("Unsupported channels: %s\n", fmt
);
3362 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3364 static const struct {
3365 const char name
[16];
3366 enum DevFmtType type
;
3368 { "int8", DevFmtByte
},
3369 { "uint8", DevFmtUByte
},
3370 { "int16", DevFmtShort
},
3371 { "uint16", DevFmtUShort
},
3372 { "int32", DevFmtInt
},
3373 { "uint32", DevFmtUInt
},
3374 { "float32", DevFmtFloat
},
3378 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3380 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3382 device
->FmtType
= typelist
[i
].type
;
3383 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3387 if(i
== COUNTOF(typelist
))
3388 ERR("Unsupported sample-type: %s\n", fmt
);
3391 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3393 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3394 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3395 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3396 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3399 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3400 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3402 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3403 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3404 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3405 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3407 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->MaxNoOfSources
);
3408 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3410 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3411 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3413 ConfigValueUInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3414 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3416 device
->NumStereoSources
= 1;
3417 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3419 // Find a playback device to open
3420 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3422 DELETE_OBJ(device
->Backend
);
3424 alcSetError(NULL
, err
);
3428 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3430 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3431 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3433 device
->DefaultSlot
= NULL
;
3434 ERR("Failed to initialize the default effect slot\n");
3436 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3438 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3439 device
->DefaultSlot
= NULL
;
3441 ERR("Failed to initialize the default effect\n");
3444 aluInitEffectPanning(device
->DefaultSlot
);
3448 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3450 device
->next
= head
;
3451 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3454 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3460 * Closes the given device.
3462 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3464 ALCdevice
*list
, *origdev
, *nextdev
;
3468 list
= ATOMIC_LOAD(&DeviceList
);
3472 } while((list
=list
->next
) != NULL
);
3473 if(!list
|| list
->Type
== Capture
)
3475 alcSetError(list
, ALC_INVALID_DEVICE
);
3481 nextdev
= device
->next
;
3482 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3487 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3491 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3494 ALCcontext
*next
= ctx
->next
;
3495 WARN("Releasing context %p\n", ctx
);
3496 ReleaseContext(ctx
, device
);
3499 if((device
->Flags
&DEVICE_RUNNING
))
3500 V0(device
->Backend
,stop
)();
3501 device
->Flags
&= ~DEVICE_RUNNING
;
3503 ALCdevice_DecRef(device
);
3509 /************************************************
3510 * ALC capture functions
3511 ************************************************/
3512 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3514 ALCdevice
*device
= NULL
;
3519 if(!CaptureBackend
.name
)
3521 alcSetError(NULL
, ALC_INVALID_VALUE
);
3527 alcSetError(NULL
, ALC_INVALID_VALUE
);
3531 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3534 device
= al_calloc(16, sizeof(ALCdevice
));
3537 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3542 InitRef(&device
->ref
, 1);
3543 device
->Connected
= ALC_TRUE
;
3544 device
->Type
= Capture
;
3546 VECTOR_INIT(device
->Hrtf_List
);
3547 AL_STRING_INIT(device
->Hrtf_Name
);
3549 AL_STRING_INIT(device
->DeviceName
);
3550 device
->Dry
.Buffer
= NULL
;
3551 device
->Dry
.NumChannels
= 0;
3552 device
->VirtOut
.Buffer
= NULL
;
3553 device
->VirtOut
.NumChannels
= 0;
3554 device
->RealOut
.Buffer
= NULL
;
3555 device
->RealOut
.NumChannels
= 0;
3557 InitUIntMap(&device
->BufferMap
, ~0);
3558 InitUIntMap(&device
->EffectMap
, ~0);
3559 InitUIntMap(&device
->FilterMap
, ~0);
3561 if(!CaptureBackend
.getFactory
)
3562 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3563 ALCbackend_Capture
);
3566 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3567 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3569 if(!device
->Backend
)
3572 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3576 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3577 device
->Frequency
= frequency
;
3579 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3580 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3583 alcSetError(NULL
, ALC_INVALID_ENUM
);
3586 device
->IsHeadphones
= AL_FALSE
;
3588 device
->UpdateSize
= samples
;
3589 device
->NumUpdates
= 1;
3591 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3594 alcSetError(NULL
, err
);
3599 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3601 device
->next
= head
;
3602 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3605 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3609 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3611 ALCdevice
*list
, *next
, *nextdev
;
3614 list
= ATOMIC_LOAD(&DeviceList
);
3618 } while((list
=list
->next
) != NULL
);
3619 if(!list
|| list
->Type
!= Capture
)
3621 alcSetError(list
, ALC_INVALID_DEVICE
);
3627 nextdev
= device
->next
;
3628 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3633 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3637 ALCdevice_DecRef(device
);
3642 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3644 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3645 alcSetError(device
, ALC_INVALID_DEVICE
);
3648 V0(device
->Backend
,lock
)();
3649 if(!device
->Connected
)
3650 alcSetError(device
, ALC_INVALID_DEVICE
);
3651 else if(!(device
->Flags
&DEVICE_RUNNING
))
3653 if(V0(device
->Backend
,start
)())
3654 device
->Flags
|= DEVICE_RUNNING
;
3657 aluHandleDisconnect(device
);
3658 alcSetError(device
, ALC_INVALID_DEVICE
);
3661 V0(device
->Backend
,unlock
)();
3664 if(device
) ALCdevice_DecRef(device
);
3667 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3669 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3670 alcSetError(device
, ALC_INVALID_DEVICE
);
3673 V0(device
->Backend
,lock
)();
3674 if((device
->Flags
&DEVICE_RUNNING
))
3675 V0(device
->Backend
,stop
)();
3676 device
->Flags
&= ~DEVICE_RUNNING
;
3677 V0(device
->Backend
,unlock
)();
3680 if(device
) ALCdevice_DecRef(device
);
3683 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3685 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3686 alcSetError(device
, ALC_INVALID_DEVICE
);
3689 ALCenum err
= ALC_INVALID_VALUE
;
3691 V0(device
->Backend
,lock
)();
3692 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3693 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3694 V0(device
->Backend
,unlock
)();
3696 if(err
!= ALC_NO_ERROR
)
3697 alcSetError(device
, err
);
3699 if(device
) ALCdevice_DecRef(device
);
3703 /************************************************
3704 * ALC loopback functions
3705 ************************************************/
3707 /* alcLoopbackOpenDeviceSOFT
3709 * Open a loopback device, for manual rendering.
3711 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3713 ALCbackendFactory
*factory
;
3718 /* Make sure the device name, if specified, is us. */
3719 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3721 alcSetError(NULL
, ALC_INVALID_VALUE
);
3725 device
= al_calloc(16, sizeof(ALCdevice
));
3728 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3733 InitRef(&device
->ref
, 1);
3734 device
->Connected
= ALC_TRUE
;
3735 device
->Type
= Loopback
;
3736 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3739 VECTOR_INIT(device
->Hrtf_List
);
3740 AL_STRING_INIT(device
->Hrtf_Name
);
3741 device
->Bs2b
= NULL
;
3742 device
->Uhj_Encoder
= NULL
;
3743 device
->Render_Mode
= NormalRender
;
3744 AL_STRING_INIT(device
->DeviceName
);
3745 device
->Dry
.Buffer
= NULL
;
3746 device
->Dry
.NumChannels
= 0;
3747 device
->VirtOut
.Buffer
= NULL
;
3748 device
->VirtOut
.NumChannels
= 0;
3749 device
->RealOut
.Buffer
= NULL
;
3750 device
->RealOut
.NumChannels
= 0;
3752 ATOMIC_INIT(&device
->ContextList
, NULL
);
3754 device
->ClockBase
= 0;
3755 device
->SamplesDone
= 0;
3757 device
->MaxNoOfSources
= 256;
3758 device
->AuxiliaryEffectSlotMax
= 4;
3759 device
->NumAuxSends
= MAX_SENDS
;
3761 InitUIntMap(&device
->BufferMap
, ~0);
3762 InitUIntMap(&device
->EffectMap
, ~0);
3763 InitUIntMap(&device
->FilterMap
, ~0);
3765 factory
= ALCloopbackFactory_getFactory();
3766 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3767 if(!device
->Backend
)
3770 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3775 device
->NumUpdates
= 0;
3776 device
->UpdateSize
= 0;
3778 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3779 device
->FmtChans
= DevFmtChannelsDefault
;
3780 device
->FmtType
= DevFmtTypeDefault
;
3781 device
->IsHeadphones
= AL_FALSE
;
3783 ConfigValueUInt(NULL
, NULL
, "sources", &device
->MaxNoOfSources
);
3784 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3786 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3787 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3789 ConfigValueUInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
3790 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3792 device
->NumStereoSources
= 1;
3793 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3795 // Open the "backend"
3796 V(device
->Backend
,open
)("Loopback");
3799 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3801 device
->next
= head
;
3802 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3805 TRACE("Created device %p\n", device
);
3809 /* alcIsRenderFormatSupportedSOFT
3811 * Determines if the loopback device supports the given format for rendering.
3813 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3815 ALCboolean ret
= ALC_FALSE
;
3817 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3818 alcSetError(device
, ALC_INVALID_DEVICE
);
3820 alcSetError(device
, ALC_INVALID_VALUE
);
3823 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3824 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3825 freq
>= MIN_OUTPUT_RATE
)
3828 if(device
) ALCdevice_DecRef(device
);
3833 /* alcRenderSamplesSOFT
3835 * Renders some samples into a buffer, using the format last set by the
3836 * attributes given to alcCreateContext.
3838 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3840 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3841 alcSetError(device
, ALC_INVALID_DEVICE
);
3842 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3843 alcSetError(device
, ALC_INVALID_VALUE
);
3845 aluMixData(device
, buffer
, samples
);
3846 if(device
) ALCdevice_DecRef(device
);
3850 /************************************************
3851 * ALC DSP pause/resume functions
3852 ************************************************/
3854 /* alcDevicePauseSOFT
3856 * Pause the DSP to stop audio processing.
3858 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3860 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3861 alcSetError(device
, ALC_INVALID_DEVICE
);
3865 if((device
->Flags
&DEVICE_RUNNING
))
3866 V0(device
->Backend
,stop
)();
3867 device
->Flags
&= ~DEVICE_RUNNING
;
3868 device
->Flags
|= DEVICE_PAUSED
;
3871 if(device
) ALCdevice_DecRef(device
);
3874 /* alcDeviceResumeSOFT
3876 * Resume the DSP to restart audio processing.
3878 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3880 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3881 alcSetError(device
, ALC_INVALID_DEVICE
);
3885 if((device
->Flags
&DEVICE_PAUSED
))
3887 device
->Flags
&= ~DEVICE_PAUSED
;
3888 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3890 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3891 device
->Flags
|= DEVICE_RUNNING
;
3894 alcSetError(device
, ALC_INVALID_DEVICE
);
3895 V0(device
->Backend
,lock
)();
3896 aluHandleDisconnect(device
);
3897 V0(device
->Backend
,unlock
)();
3903 if(device
) ALCdevice_DecRef(device
);
3907 /************************************************
3908 * ALC HRTF functions
3909 ************************************************/
3911 /* alcGetStringiSOFT
3913 * Gets a string parameter at the given index.
3915 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
3917 const ALCchar
*str
= NULL
;
3919 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
3920 alcSetError(device
, ALC_INVALID_DEVICE
);
3921 else switch(paramName
)
3923 case ALC_HRTF_SPECIFIER_SOFT
:
3924 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->Hrtf_List
))
3925 str
= al_string_get_cstr(VECTOR_ELEM(device
->Hrtf_List
, index
).name
);
3927 alcSetError(device
, ALC_INVALID_VALUE
);
3931 alcSetError(device
, ALC_INVALID_ENUM
);
3934 if(device
) ALCdevice_DecRef(device
);
3939 /* alcResetDeviceSOFT
3941 * Resets the given device output, using the specified attribute list.
3943 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
3948 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3951 alcSetError(device
, ALC_INVALID_DEVICE
);
3952 if(device
) ALCdevice_DecRef(device
);
3956 if((err
=UpdateDeviceParams(device
, attribs
)) != ALC_NO_ERROR
)
3959 alcSetError(device
, err
);
3960 if(err
== ALC_INVALID_DEVICE
)
3962 V0(device
->Backend
,lock
)();
3963 aluHandleDisconnect(device
);
3964 V0(device
->Backend
,unlock
)();
3966 ALCdevice_DecRef(device
);
3970 ALCdevice_DecRef(device
);