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"
39 #include "uhjfilter.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(alBufferSubDataSOFT
),
277 DECL(alBufferSamplesSOFT
),
278 DECL(alBufferSubSamplesSOFT
),
279 DECL(alGetBufferSamplesSOFT
),
280 DECL(alIsBufferFormatSupportedSOFT
),
282 DECL(alDeferUpdatesSOFT
),
283 DECL(alProcessUpdatesSOFT
),
286 DECL(alSource3dSOFT
),
287 DECL(alSourcedvSOFT
),
288 DECL(alGetSourcedSOFT
),
289 DECL(alGetSource3dSOFT
),
290 DECL(alGetSourcedvSOFT
),
291 DECL(alSourcei64SOFT
),
292 DECL(alSource3i64SOFT
),
293 DECL(alSourcei64vSOFT
),
294 DECL(alGetSourcei64SOFT
),
295 DECL(alGetSource3i64SOFT
),
296 DECL(alGetSourcei64vSOFT
),
302 #define DECL(x) { #x, (x) }
303 static const ALCenums enumeration
[] = {
308 DECL(ALC_MAJOR_VERSION
),
309 DECL(ALC_MINOR_VERSION
),
310 DECL(ALC_ATTRIBUTES_SIZE
),
311 DECL(ALC_ALL_ATTRIBUTES
),
312 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
313 DECL(ALC_DEVICE_SPECIFIER
),
314 DECL(ALC_ALL_DEVICES_SPECIFIER
),
315 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
316 DECL(ALC_EXTENSIONS
),
320 DECL(ALC_MONO_SOURCES
),
321 DECL(ALC_STEREO_SOURCES
),
322 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
323 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
324 DECL(ALC_CAPTURE_SAMPLES
),
327 DECL(ALC_EFX_MAJOR_VERSION
),
328 DECL(ALC_EFX_MINOR_VERSION
),
329 DECL(ALC_MAX_AUXILIARY_SENDS
),
331 DECL(ALC_FORMAT_CHANNELS_SOFT
),
332 DECL(ALC_FORMAT_TYPE_SOFT
),
335 DECL(ALC_STEREO_SOFT
),
337 DECL(ALC_5POINT1_SOFT
),
338 DECL(ALC_6POINT1_SOFT
),
339 DECL(ALC_7POINT1_SOFT
),
342 DECL(ALC_UNSIGNED_BYTE_SOFT
),
343 DECL(ALC_SHORT_SOFT
),
344 DECL(ALC_UNSIGNED_SHORT_SOFT
),
346 DECL(ALC_UNSIGNED_INT_SOFT
),
347 DECL(ALC_FLOAT_SOFT
),
350 DECL(ALC_DONT_CARE_SOFT
),
351 DECL(ALC_HRTF_STATUS_SOFT
),
352 DECL(ALC_HRTF_DISABLED_SOFT
),
353 DECL(ALC_HRTF_ENABLED_SOFT
),
354 DECL(ALC_HRTF_DENIED_SOFT
),
355 DECL(ALC_HRTF_REQUIRED_SOFT
),
356 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT
),
357 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
),
358 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT
),
359 DECL(ALC_HRTF_SPECIFIER_SOFT
),
360 DECL(ALC_HRTF_ID_SOFT
),
363 DECL(ALC_INVALID_DEVICE
),
364 DECL(ALC_INVALID_CONTEXT
),
365 DECL(ALC_INVALID_ENUM
),
366 DECL(ALC_INVALID_VALUE
),
367 DECL(ALC_OUT_OF_MEMORY
),
375 DECL(AL_SOURCE_RELATIVE
),
376 DECL(AL_CONE_INNER_ANGLE
),
377 DECL(AL_CONE_OUTER_ANGLE
),
387 DECL(AL_ORIENTATION
),
388 DECL(AL_REFERENCE_DISTANCE
),
389 DECL(AL_ROLLOFF_FACTOR
),
390 DECL(AL_CONE_OUTER_GAIN
),
391 DECL(AL_MAX_DISTANCE
),
393 DECL(AL_SAMPLE_OFFSET
),
394 DECL(AL_SAMPLE_RW_OFFSETS_SOFT
),
395 DECL(AL_BYTE_OFFSET
),
396 DECL(AL_BYTE_RW_OFFSETS_SOFT
),
397 DECL(AL_SOURCE_TYPE
),
400 DECL(AL_UNDETERMINED
),
401 DECL(AL_METERS_PER_UNIT
),
402 DECL(AL_LOOP_POINTS_SOFT
),
403 DECL(AL_DIRECT_CHANNELS_SOFT
),
405 DECL(AL_DIRECT_FILTER
),
406 DECL(AL_AUXILIARY_SEND_FILTER
),
407 DECL(AL_AIR_ABSORPTION_FACTOR
),
408 DECL(AL_ROOM_ROLLOFF_FACTOR
),
409 DECL(AL_CONE_OUTER_GAINHF
),
410 DECL(AL_DIRECT_FILTER_GAINHF_AUTO
),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
),
412 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
),
414 DECL(AL_SOURCE_STATE
),
420 DECL(AL_BUFFERS_QUEUED
),
421 DECL(AL_BUFFERS_PROCESSED
),
423 DECL(AL_FORMAT_MONO8
),
424 DECL(AL_FORMAT_MONO16
),
425 DECL(AL_FORMAT_MONO_FLOAT32
),
426 DECL(AL_FORMAT_MONO_DOUBLE_EXT
),
427 DECL(AL_FORMAT_STEREO8
),
428 DECL(AL_FORMAT_STEREO16
),
429 DECL(AL_FORMAT_STEREO_FLOAT32
),
430 DECL(AL_FORMAT_STEREO_DOUBLE_EXT
),
431 DECL(AL_FORMAT_MONO_IMA4
),
432 DECL(AL_FORMAT_STEREO_IMA4
),
433 DECL(AL_FORMAT_MONO_MSADPCM_SOFT
),
434 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT
),
435 DECL(AL_FORMAT_QUAD8_LOKI
),
436 DECL(AL_FORMAT_QUAD16_LOKI
),
437 DECL(AL_FORMAT_QUAD8
),
438 DECL(AL_FORMAT_QUAD16
),
439 DECL(AL_FORMAT_QUAD32
),
440 DECL(AL_FORMAT_51CHN8
),
441 DECL(AL_FORMAT_51CHN16
),
442 DECL(AL_FORMAT_51CHN32
),
443 DECL(AL_FORMAT_61CHN8
),
444 DECL(AL_FORMAT_61CHN16
),
445 DECL(AL_FORMAT_61CHN32
),
446 DECL(AL_FORMAT_71CHN8
),
447 DECL(AL_FORMAT_71CHN16
),
448 DECL(AL_FORMAT_71CHN32
),
449 DECL(AL_FORMAT_REAR8
),
450 DECL(AL_FORMAT_REAR16
),
451 DECL(AL_FORMAT_REAR32
),
452 DECL(AL_FORMAT_MONO_MULAW
),
453 DECL(AL_FORMAT_MONO_MULAW_EXT
),
454 DECL(AL_FORMAT_STEREO_MULAW
),
455 DECL(AL_FORMAT_STEREO_MULAW_EXT
),
456 DECL(AL_FORMAT_QUAD_MULAW
),
457 DECL(AL_FORMAT_51CHN_MULAW
),
458 DECL(AL_FORMAT_61CHN_MULAW
),
459 DECL(AL_FORMAT_71CHN_MULAW
),
460 DECL(AL_FORMAT_REAR_MULAW
),
461 DECL(AL_FORMAT_MONO_ALAW_EXT
),
462 DECL(AL_FORMAT_STEREO_ALAW_EXT
),
465 DECL(AL_MONO16_SOFT
),
466 DECL(AL_MONO32F_SOFT
),
467 DECL(AL_STEREO8_SOFT
),
468 DECL(AL_STEREO16_SOFT
),
469 DECL(AL_STEREO32F_SOFT
),
471 DECL(AL_QUAD16_SOFT
),
472 DECL(AL_QUAD32F_SOFT
),
474 DECL(AL_REAR16_SOFT
),
475 DECL(AL_REAR32F_SOFT
),
476 DECL(AL_5POINT1_8_SOFT
),
477 DECL(AL_5POINT1_16_SOFT
),
478 DECL(AL_5POINT1_32F_SOFT
),
479 DECL(AL_6POINT1_8_SOFT
),
480 DECL(AL_6POINT1_16_SOFT
),
481 DECL(AL_6POINT1_32F_SOFT
),
482 DECL(AL_7POINT1_8_SOFT
),
483 DECL(AL_7POINT1_16_SOFT
),
484 DECL(AL_7POINT1_32F_SOFT
),
485 DECL(AL_FORMAT_BFORMAT2D_8
),
486 DECL(AL_FORMAT_BFORMAT2D_16
),
487 DECL(AL_FORMAT_BFORMAT2D_FLOAT32
),
488 DECL(AL_FORMAT_BFORMAT2D_MULAW
),
489 DECL(AL_FORMAT_BFORMAT3D_8
),
490 DECL(AL_FORMAT_BFORMAT3D_16
),
491 DECL(AL_FORMAT_BFORMAT3D_FLOAT32
),
492 DECL(AL_FORMAT_BFORMAT3D_MULAW
),
495 DECL(AL_STEREO_SOFT
),
498 DECL(AL_5POINT1_SOFT
),
499 DECL(AL_6POINT1_SOFT
),
500 DECL(AL_7POINT1_SOFT
),
503 DECL(AL_UNSIGNED_BYTE_SOFT
),
505 DECL(AL_UNSIGNED_SHORT_SOFT
),
507 DECL(AL_UNSIGNED_INT_SOFT
),
509 DECL(AL_DOUBLE_SOFT
),
511 DECL(AL_UNSIGNED_BYTE3_SOFT
),
517 DECL(AL_INTERNAL_FORMAT_SOFT
),
518 DECL(AL_BYTE_LENGTH_SOFT
),
519 DECL(AL_SAMPLE_LENGTH_SOFT
),
520 DECL(AL_SEC_LENGTH_SOFT
),
521 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT
),
522 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT
),
529 DECL(AL_INVALID_NAME
),
530 DECL(AL_INVALID_ENUM
),
531 DECL(AL_INVALID_VALUE
),
532 DECL(AL_INVALID_OPERATION
),
533 DECL(AL_OUT_OF_MEMORY
),
540 DECL(AL_DOPPLER_FACTOR
),
541 DECL(AL_DOPPLER_VELOCITY
),
542 DECL(AL_DISTANCE_MODEL
),
543 DECL(AL_SPEED_OF_SOUND
),
544 DECL(AL_SOURCE_DISTANCE_MODEL
),
545 DECL(AL_DEFERRED_UPDATES_SOFT
),
547 DECL(AL_INVERSE_DISTANCE
),
548 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
549 DECL(AL_LINEAR_DISTANCE
),
550 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
551 DECL(AL_EXPONENT_DISTANCE
),
552 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
554 DECL(AL_FILTER_TYPE
),
555 DECL(AL_FILTER_NULL
),
556 DECL(AL_FILTER_LOWPASS
),
557 DECL(AL_FILTER_HIGHPASS
),
558 DECL(AL_FILTER_BANDPASS
),
560 DECL(AL_LOWPASS_GAIN
),
561 DECL(AL_LOWPASS_GAINHF
),
563 DECL(AL_HIGHPASS_GAIN
),
564 DECL(AL_HIGHPASS_GAINLF
),
566 DECL(AL_BANDPASS_GAIN
),
567 DECL(AL_BANDPASS_GAINHF
),
568 DECL(AL_BANDPASS_GAINLF
),
570 DECL(AL_EFFECT_TYPE
),
571 DECL(AL_EFFECT_NULL
),
572 DECL(AL_EFFECT_REVERB
),
573 DECL(AL_EFFECT_EAXREVERB
),
574 DECL(AL_EFFECT_CHORUS
),
575 DECL(AL_EFFECT_DISTORTION
),
576 DECL(AL_EFFECT_ECHO
),
577 DECL(AL_EFFECT_FLANGER
),
579 DECL(AL_EFFECT_FREQUENCY_SHIFTER
),
580 DECL(AL_EFFECT_VOCAL_MORPHER
),
581 DECL(AL_EFFECT_PITCH_SHIFTER
),
583 DECL(AL_EFFECT_RING_MODULATOR
),
585 DECL(AL_EFFECT_AUTOWAH
),
587 DECL(AL_EFFECT_COMPRESSOR
),
588 DECL(AL_EFFECT_EQUALIZER
),
589 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
),
590 DECL(AL_EFFECT_DEDICATED_DIALOGUE
),
592 DECL(AL_EAXREVERB_DENSITY
),
593 DECL(AL_EAXREVERB_DIFFUSION
),
594 DECL(AL_EAXREVERB_GAIN
),
595 DECL(AL_EAXREVERB_GAINHF
),
596 DECL(AL_EAXREVERB_GAINLF
),
597 DECL(AL_EAXREVERB_DECAY_TIME
),
598 DECL(AL_EAXREVERB_DECAY_HFRATIO
),
599 DECL(AL_EAXREVERB_DECAY_LFRATIO
),
600 DECL(AL_EAXREVERB_REFLECTIONS_GAIN
),
601 DECL(AL_EAXREVERB_REFLECTIONS_DELAY
),
602 DECL(AL_EAXREVERB_REFLECTIONS_PAN
),
603 DECL(AL_EAXREVERB_LATE_REVERB_GAIN
),
604 DECL(AL_EAXREVERB_LATE_REVERB_DELAY
),
605 DECL(AL_EAXREVERB_LATE_REVERB_PAN
),
606 DECL(AL_EAXREVERB_ECHO_TIME
),
607 DECL(AL_EAXREVERB_ECHO_DEPTH
),
608 DECL(AL_EAXREVERB_MODULATION_TIME
),
609 DECL(AL_EAXREVERB_MODULATION_DEPTH
),
610 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF
),
611 DECL(AL_EAXREVERB_HFREFERENCE
),
612 DECL(AL_EAXREVERB_LFREFERENCE
),
613 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR
),
614 DECL(AL_EAXREVERB_DECAY_HFLIMIT
),
616 DECL(AL_REVERB_DENSITY
),
617 DECL(AL_REVERB_DIFFUSION
),
618 DECL(AL_REVERB_GAIN
),
619 DECL(AL_REVERB_GAINHF
),
620 DECL(AL_REVERB_DECAY_TIME
),
621 DECL(AL_REVERB_DECAY_HFRATIO
),
622 DECL(AL_REVERB_REFLECTIONS_GAIN
),
623 DECL(AL_REVERB_REFLECTIONS_DELAY
),
624 DECL(AL_REVERB_LATE_REVERB_GAIN
),
625 DECL(AL_REVERB_LATE_REVERB_DELAY
),
626 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF
),
627 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR
),
628 DECL(AL_REVERB_DECAY_HFLIMIT
),
630 DECL(AL_CHORUS_WAVEFORM
),
631 DECL(AL_CHORUS_PHASE
),
632 DECL(AL_CHORUS_RATE
),
633 DECL(AL_CHORUS_DEPTH
),
634 DECL(AL_CHORUS_FEEDBACK
),
635 DECL(AL_CHORUS_DELAY
),
637 DECL(AL_DISTORTION_EDGE
),
638 DECL(AL_DISTORTION_GAIN
),
639 DECL(AL_DISTORTION_LOWPASS_CUTOFF
),
640 DECL(AL_DISTORTION_EQCENTER
),
641 DECL(AL_DISTORTION_EQBANDWIDTH
),
644 DECL(AL_ECHO_LRDELAY
),
645 DECL(AL_ECHO_DAMPING
),
646 DECL(AL_ECHO_FEEDBACK
),
647 DECL(AL_ECHO_SPREAD
),
649 DECL(AL_FLANGER_WAVEFORM
),
650 DECL(AL_FLANGER_PHASE
),
651 DECL(AL_FLANGER_RATE
),
652 DECL(AL_FLANGER_DEPTH
),
653 DECL(AL_FLANGER_FEEDBACK
),
654 DECL(AL_FLANGER_DELAY
),
656 DECL(AL_RING_MODULATOR_FREQUENCY
),
657 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF
),
658 DECL(AL_RING_MODULATOR_WAVEFORM
),
661 DECL(AL_AUTOWAH_ATTACK_TIME
),
662 DECL(AL_AUTOWAH_PEAK_GAIN
),
663 DECL(AL_AUTOWAH_RELEASE_TIME
),
664 DECL(AL_AUTOWAH_RESONANCE
),
667 DECL(AL_COMPRESSOR_ONOFF
),
669 DECL(AL_EQUALIZER_LOW_GAIN
),
670 DECL(AL_EQUALIZER_LOW_CUTOFF
),
671 DECL(AL_EQUALIZER_MID1_GAIN
),
672 DECL(AL_EQUALIZER_MID1_CENTER
),
673 DECL(AL_EQUALIZER_MID1_WIDTH
),
674 DECL(AL_EQUALIZER_MID2_GAIN
),
675 DECL(AL_EQUALIZER_MID2_CENTER
),
676 DECL(AL_EQUALIZER_MID2_WIDTH
),
677 DECL(AL_EQUALIZER_HIGH_GAIN
),
678 DECL(AL_EQUALIZER_HIGH_CUTOFF
),
680 DECL(AL_DEDICATED_GAIN
),
686 static const ALCchar alcNoError
[] = "No Error";
687 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
688 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
689 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
690 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
691 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
694 /************************************************
696 ************************************************/
698 /* Enumerated device names */
699 static const ALCchar alcDefaultName
[] = "OpenAL Soft\0";
701 static al_string alcAllDevicesList
;
702 static al_string alcCaptureDeviceList
;
704 /* Default is always the first in the list */
705 static ALCchar
*alcDefaultAllDevicesSpecifier
;
706 static ALCchar
*alcCaptureDefaultDeviceSpecifier
;
708 /* Default context extensions */
709 static const ALchar alExtList
[] =
710 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
711 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
712 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
713 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
714 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
715 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
716 "AL_SOFT_source_latency AL_SOFT_source_length";
718 static ATOMIC(ALCenum
) LastNullDeviceError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
720 /* Thread-local current context */
721 static altss_t LocalContext
;
722 /* Process-wide current context */
723 static ATOMIC(ALCcontext
*) GlobalContext
= ATOMIC_INIT_STATIC(NULL
);
725 /* Mixing thread piority level */
730 enum LogLevel LogLevel
= LogWarning
;
732 enum LogLevel LogLevel
= LogError
;
735 /* Flag to trap ALC device errors */
736 static ALCboolean TrapALCError
= ALC_FALSE
;
738 /* One-time configuration init control */
739 static alonce_flag alc_config_once
= AL_ONCE_FLAG_INIT
;
741 /* Default effect that applies to sources that don't have an effect on send 0 */
742 static ALeffect DefaultEffect
;
744 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
747 static ALCboolean SuspendDefers
= ALC_TRUE
;
750 /************************************************
752 ************************************************/
753 static const ALCchar alcNoDeviceExtList
[] =
754 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
755 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
756 static const ALCchar alcExtensionList
[] =
757 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
758 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
759 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
760 "ALC_SOFT_loopback ALC_SOFT_pause_device";
761 static const ALCint alcMajorVersion
= 1;
762 static const ALCint alcMinorVersion
= 1;
764 static const ALCint alcEFXMajorVersion
= 1;
765 static const ALCint alcEFXMinorVersion
= 0;
768 /************************************************
770 ************************************************/
771 static ATOMIC(ALCdevice
*) DeviceList
= ATOMIC_INIT_STATIC(NULL
);
773 static almtx_t ListLock
;
774 static inline void LockLists(void)
776 int lockret
= almtx_lock(&ListLock
);
777 assert(lockret
== althrd_success
);
779 static inline void UnlockLists(void)
781 int unlockret
= almtx_unlock(&ListLock
);
782 assert(unlockret
== althrd_success
);
785 /************************************************
786 * Library initialization
787 ************************************************/
789 static void alc_init(void);
790 static void alc_deinit(void);
791 static void alc_deinit_safe(void);
793 #ifndef AL_LIBTYPE_STATIC
794 BOOL APIENTRY
DllMain(HINSTANCE hModule
, DWORD reason
, LPVOID lpReserved
)
798 case DLL_PROCESS_ATTACH
:
799 /* Pin the DLL so we won't get unloaded until the process terminates */
800 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
801 (WCHAR
*)hModule
, &hModule
);
805 case DLL_THREAD_DETACH
:
808 case DLL_PROCESS_DETACH
:
817 #elif defined(_MSC_VER)
818 #pragma section(".CRT$XCU",read)
819 static void alc_constructor(void);
820 static void alc_destructor(void);
821 __declspec(allocate(".CRT$XCU")) void (__cdecl
* alc_constructor_
)(void) = alc_constructor
;
823 static void alc_constructor(void)
825 atexit(alc_destructor
);
829 static void alc_destructor(void)
833 #elif defined(HAVE_GCC_DESTRUCTOR)
834 static void alc_init(void) __attribute__((constructor
));
835 static void alc_deinit(void) __attribute__((destructor
));
837 #error "No static initialization available on this platform!"
840 #elif defined(HAVE_GCC_DESTRUCTOR)
842 static void alc_init(void) __attribute__((constructor
));
843 static void alc_deinit(void) __attribute__((destructor
));
846 #error "No global initialization available on this platform!"
849 static void ReleaseThreadCtx(void *ptr
);
850 static void alc_init(void)
857 AL_STRING_INIT(alcAllDevicesList
);
858 AL_STRING_INIT(alcCaptureDeviceList
);
860 str
= getenv("__ALSOFT_HALF_ANGLE_CONES");
861 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
864 str
= getenv("__ALSOFT_REVERSE_Z");
865 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
868 ret
= altss_create(&LocalContext
, ReleaseThreadCtx
);
869 assert(ret
== althrd_success
);
871 ret
= almtx_init(&ListLock
, almtx_recursive
);
872 assert(ret
== althrd_success
);
877 static void alc_initconfig(void)
879 const char *devs
, *str
;
884 str
= getenv("ALSOFT_LOGLEVEL");
887 long lvl
= strtol(str
, NULL
, 0);
888 if(lvl
>= NoLog
&& lvl
<= LogRef
)
892 str
= getenv("ALSOFT_LOGFILE");
895 FILE *logfile
= al_fopen(str
, "wt");
896 if(logfile
) LogFile
= logfile
;
897 else ERR("Failed to open log file '%s'\n", str
);
902 int len
= snprintf(buf
, sizeof(buf
), "%s", BackendList
[0].name
);
903 for(i
= 1;BackendList
[i
].name
;i
++)
904 len
+= snprintf(buf
+len
, sizeof(buf
)-len
, ", %s", BackendList
[i
].name
);
905 TRACE("Supported backends: %s\n", buf
);
909 str
= getenv("__ALSOFT_SUSPEND_CONTEXT");
912 if(strcasecmp(str
, "ignore") == 0)
914 SuspendDefers
= ALC_FALSE
;
915 TRACE("Selected context suspend behavior, \"ignore\"\n");
918 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str
);
922 #if defined(HAVE_SSE4_1)
923 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
| CPU_CAP_SSE4_1
;
924 #elif defined(HAVE_SSE3)
925 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
| CPU_CAP_SSE3
;
926 #elif defined(HAVE_SSE2)
927 capfilter
|= CPU_CAP_SSE
| CPU_CAP_SSE2
;
928 #elif defined(HAVE_SSE)
929 capfilter
|= CPU_CAP_SSE
;
932 capfilter
|= CPU_CAP_NEON
;
934 if(ConfigValueStr(NULL
, NULL
, "disable-cpu-exts", &str
))
936 if(strcasecmp(str
, "all") == 0)
941 const char *next
= str
;
945 while(isspace(str
[0]))
947 next
= strchr(str
, ',');
949 if(!str
[0] || str
[0] == ',')
952 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
953 while(len
> 0 && isspace(str
[len
-1]))
955 if(len
== 3 && strncasecmp(str
, "sse", len
) == 0)
956 capfilter
&= ~CPU_CAP_SSE
;
957 else if(len
== 4 && strncasecmp(str
, "sse2", len
) == 0)
958 capfilter
&= ~CPU_CAP_SSE2
;
959 else if(len
== 4 && strncasecmp(str
, "sse3", len
) == 0)
960 capfilter
&= ~CPU_CAP_SSE3
;
961 else if(len
== 6 && strncasecmp(str
, "sse4.1", len
) == 0)
962 capfilter
&= ~CPU_CAP_SSE4_1
;
963 else if(len
== 4 && strncasecmp(str
, "neon", len
) == 0)
964 capfilter
&= ~CPU_CAP_NEON
;
966 WARN("Invalid CPU extension \"%s\"\n", str
);
970 FillCPUCaps(capfilter
);
977 ConfigValueInt(NULL
, NULL
, "rt-prio", &RTPrioLevel
);
981 str
= getenv("ALSOFT_TRAP_ERROR");
982 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
984 TrapALError
= AL_TRUE
;
985 TrapALCError
= AL_TRUE
;
989 str
= getenv("ALSOFT_TRAP_AL_ERROR");
990 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
991 TrapALError
= AL_TRUE
;
992 TrapALError
= GetConfigValueBool(NULL
, NULL
, "trap-al-error", TrapALError
);
994 str
= getenv("ALSOFT_TRAP_ALC_ERROR");
995 if(str
&& (strcasecmp(str
, "true") == 0 || strtol(str
, NULL
, 0) == 1))
996 TrapALCError
= ALC_TRUE
;
997 TrapALCError
= GetConfigValueBool(NULL
, NULL
, "trap-alc-error", TrapALCError
);
1000 if(ConfigValueFloat(NULL
, "reverb", "boost", &valf
))
1001 ReverbBoost
*= powf(10.0f
, valf
/ 20.0f
);
1003 EmulateEAXReverb
= GetConfigValueBool(NULL
, "reverb", "emulate-eax", AL_FALSE
);
1005 if(((devs
=getenv("ALSOFT_DRIVERS")) && devs
[0]) ||
1006 ConfigValueStr(NULL
, NULL
, "drivers", &devs
))
1010 const char *next
= devs
;
1011 int endlist
, delitem
;
1016 while(isspace(devs
[0]))
1018 next
= strchr(devs
, ',');
1020 delitem
= (devs
[0] == '-');
1021 if(devs
[0] == '-') devs
++;
1023 if(!devs
[0] || devs
[0] == ',')
1030 len
= (next
? ((size_t)(next
-devs
)) : strlen(devs
));
1031 while(len
> 0 && isspace(devs
[len
-1]))
1033 for(n
= i
;BackendList
[n
].name
;n
++)
1035 if(len
== strlen(BackendList
[n
].name
) &&
1036 strncmp(BackendList
[n
].name
, devs
, len
) == 0)
1041 BackendList
[n
] = BackendList
[n
+1];
1043 } while(BackendList
[n
].name
);
1047 struct BackendInfo Bkp
= BackendList
[n
];
1050 BackendList
[n
] = BackendList
[n
-1];
1053 BackendList
[n
] = Bkp
;
1064 BackendList
[i
].name
= NULL
;
1065 BackendList
[i
].getFactory
= NULL
;
1066 BackendList
[i
].Init
= NULL
;
1067 BackendList
[i
].Deinit
= NULL
;
1068 BackendList
[i
].Probe
= NULL
;
1072 for(i
= 0;(BackendList
[i
].Init
|| BackendList
[i
].getFactory
) && (!PlaybackBackend
.name
|| !CaptureBackend
.name
);i
++)
1074 if(BackendList
[i
].getFactory
)
1076 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1077 if(!V0(factory
,init
)())
1079 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1083 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1084 if(!PlaybackBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Playback
))
1086 PlaybackBackend
= BackendList
[i
];
1087 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1089 if(!CaptureBackend
.name
&& V(factory
,querySupport
)(ALCbackend_Capture
))
1091 CaptureBackend
= BackendList
[i
];
1092 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1098 if(!BackendList
[i
].Init(&BackendList
[i
].Funcs
))
1100 WARN("Failed to initialize backend \"%s\"\n", BackendList
[i
].name
);
1104 TRACE("Initialized backend \"%s\"\n", BackendList
[i
].name
);
1105 if(BackendList
[i
].Funcs
.OpenPlayback
&& !PlaybackBackend
.name
)
1107 PlaybackBackend
= BackendList
[i
];
1108 TRACE("Added \"%s\" for playback\n", PlaybackBackend
.name
);
1110 if(BackendList
[i
].Funcs
.OpenCapture
&& !CaptureBackend
.name
)
1112 CaptureBackend
= BackendList
[i
];
1113 TRACE("Added \"%s\" for capture\n", CaptureBackend
.name
);
1117 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1121 if(ConfigValueStr(NULL
, NULL
, "excludefx", &str
))
1124 const char *next
= str
;
1128 next
= strchr(str
, ',');
1130 if(!str
[0] || next
== str
)
1133 len
= (next
? ((size_t)(next
-str
)) : strlen(str
));
1134 for(n
= 0;EffectList
[n
].name
;n
++)
1136 if(len
== strlen(EffectList
[n
].name
) &&
1137 strncmp(EffectList
[n
].name
, str
, len
) == 0)
1138 DisabledEffects
[EffectList
[n
].type
] = AL_TRUE
;
1143 InitEffectFactoryMap();
1145 InitEffect(&DefaultEffect
);
1146 str
= getenv("ALSOFT_DEFAULT_REVERB");
1147 if((str
&& str
[0]) || ConfigValueStr(NULL
, NULL
, "default-reverb", &str
))
1148 LoadReverbPreset(str
, &DefaultEffect
);
1150 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1153 /************************************************
1154 * Library deinitialization
1155 ************************************************/
1156 static void alc_cleanup(void)
1160 AL_STRING_DEINIT(alcAllDevicesList
);
1161 AL_STRING_DEINIT(alcCaptureDeviceList
);
1163 free(alcDefaultAllDevicesSpecifier
);
1164 alcDefaultAllDevicesSpecifier
= NULL
;
1165 free(alcCaptureDefaultDeviceSpecifier
);
1166 alcCaptureDefaultDeviceSpecifier
= NULL
;
1168 if((dev
=ATOMIC_EXCHANGE(ALCdevice
*, &DeviceList
, NULL
)) != NULL
)
1173 } while((dev
=dev
->next
) != NULL
);
1174 ERR("%u device%s not closed\n", num
, (num
>1)?"s":"");
1177 DeinitEffectFactoryMap();
1180 static void alc_deinit_safe(void)
1188 almtx_destroy(&ListLock
);
1189 altss_delete(LocalContext
);
1191 if(LogFile
!= stderr
)
1196 static void alc_deinit(void)
1202 memset(&PlaybackBackend
, 0, sizeof(PlaybackBackend
));
1203 memset(&CaptureBackend
, 0, sizeof(CaptureBackend
));
1205 for(i
= 0;BackendList
[i
].Deinit
|| BackendList
[i
].getFactory
;i
++)
1207 if(!BackendList
[i
].getFactory
)
1208 BackendList
[i
].Deinit();
1211 ALCbackendFactory
*factory
= BackendList
[i
].getFactory();
1212 V0(factory
,deinit
)();
1216 ALCbackendFactory
*factory
= ALCloopbackFactory_getFactory();
1217 V0(factory
,deinit
)();
1224 /************************************************
1225 * Device enumeration
1226 ************************************************/
1227 static void ProbeDevices(al_string
*list
, struct BackendInfo
*backendinfo
, enum DevProbe type
)
1232 al_string_clear(list
);
1234 if(!backendinfo
->getFactory
)
1235 backendinfo
->Probe(type
);
1238 ALCbackendFactory
*factory
= backendinfo
->getFactory();
1239 V(factory
,probe
)(type
);
1244 static void ProbeAllDevicesList(void)
1245 { ProbeDevices(&alcAllDevicesList
, &PlaybackBackend
, ALL_DEVICE_PROBE
); }
1246 static void ProbeCaptureDeviceList(void)
1247 { ProbeDevices(&alcCaptureDeviceList
, &CaptureBackend
, CAPTURE_DEVICE_PROBE
); }
1249 static void AppendDevice(const ALCchar
*name
, al_string
*devnames
)
1251 size_t len
= strlen(name
);
1253 al_string_append_range(devnames
, name
, name
+len
+1);
1255 void AppendAllDevicesList(const ALCchar
*name
)
1256 { AppendDevice(name
, &alcAllDevicesList
); }
1257 void AppendCaptureDeviceList(const ALCchar
*name
)
1258 { AppendDevice(name
, &alcCaptureDeviceList
); }
1261 /************************************************
1262 * Device format information
1263 ************************************************/
1264 const ALCchar
*DevFmtTypeString(enum DevFmtType type
)
1268 case DevFmtByte
: return "Signed Byte";
1269 case DevFmtUByte
: return "Unsigned Byte";
1270 case DevFmtShort
: return "Signed Short";
1271 case DevFmtUShort
: return "Unsigned Short";
1272 case DevFmtInt
: return "Signed Int";
1273 case DevFmtUInt
: return "Unsigned Int";
1274 case DevFmtFloat
: return "Float";
1276 return "(unknown type)";
1278 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
)
1282 case DevFmtMono
: return "Mono";
1283 case DevFmtStereo
: return "Stereo";
1284 case DevFmtQuad
: return "Quadraphonic";
1285 case DevFmtX51
: return "5.1 Surround";
1286 case DevFmtX51Rear
: return "5.1 Surround (Rear)";
1287 case DevFmtX61
: return "6.1 Surround";
1288 case DevFmtX71
: return "7.1 Surround";
1289 case DevFmtBFormat3D
: return "B-Format 3D";
1291 return "(unknown channels)";
1294 extern inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
);
1295 ALuint
BytesFromDevFmt(enum DevFmtType type
)
1299 case DevFmtByte
: return sizeof(ALbyte
);
1300 case DevFmtUByte
: return sizeof(ALubyte
);
1301 case DevFmtShort
: return sizeof(ALshort
);
1302 case DevFmtUShort
: return sizeof(ALushort
);
1303 case DevFmtInt
: return sizeof(ALint
);
1304 case DevFmtUInt
: return sizeof(ALuint
);
1305 case DevFmtFloat
: return sizeof(ALfloat
);
1309 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
)
1313 case DevFmtMono
: return 1;
1314 case DevFmtStereo
: return 2;
1315 case DevFmtQuad
: return 4;
1316 case DevFmtX51
: return 6;
1317 case DevFmtX51Rear
: return 6;
1318 case DevFmtX61
: return 7;
1319 case DevFmtX71
: return 8;
1320 case DevFmtBFormat3D
: return 4;
1325 DECL_CONST
static ALboolean
DecomposeDevFormat(ALenum format
,
1326 enum DevFmtChannels
*chans
, enum DevFmtType
*type
)
1328 static const struct {
1330 enum DevFmtChannels channels
;
1331 enum DevFmtType type
;
1333 { AL_FORMAT_MONO8
, DevFmtMono
, DevFmtUByte
},
1334 { AL_FORMAT_MONO16
, DevFmtMono
, DevFmtShort
},
1335 { AL_FORMAT_MONO_FLOAT32
, DevFmtMono
, DevFmtFloat
},
1337 { AL_FORMAT_STEREO8
, DevFmtStereo
, DevFmtUByte
},
1338 { AL_FORMAT_STEREO16
, DevFmtStereo
, DevFmtShort
},
1339 { AL_FORMAT_STEREO_FLOAT32
, DevFmtStereo
, DevFmtFloat
},
1341 { AL_FORMAT_QUAD8
, DevFmtQuad
, DevFmtUByte
},
1342 { AL_FORMAT_QUAD16
, DevFmtQuad
, DevFmtShort
},
1343 { AL_FORMAT_QUAD32
, DevFmtQuad
, DevFmtFloat
},
1345 { AL_FORMAT_51CHN8
, DevFmtX51
, DevFmtUByte
},
1346 { AL_FORMAT_51CHN16
, DevFmtX51
, DevFmtShort
},
1347 { AL_FORMAT_51CHN32
, DevFmtX51
, DevFmtFloat
},
1349 { AL_FORMAT_61CHN8
, DevFmtX61
, DevFmtUByte
},
1350 { AL_FORMAT_61CHN16
, DevFmtX61
, DevFmtShort
},
1351 { AL_FORMAT_61CHN32
, DevFmtX61
, DevFmtFloat
},
1353 { AL_FORMAT_71CHN8
, DevFmtX71
, DevFmtUByte
},
1354 { AL_FORMAT_71CHN16
, DevFmtX71
, DevFmtShort
},
1355 { AL_FORMAT_71CHN32
, DevFmtX71
, DevFmtFloat
},
1359 for(i
= 0;i
< COUNTOF(list
);i
++)
1361 if(list
[i
].format
== format
)
1363 *chans
= list
[i
].channels
;
1364 *type
= list
[i
].type
;
1372 DECL_CONST
static ALCboolean
IsValidALCType(ALCenum type
)
1377 case ALC_UNSIGNED_BYTE_SOFT
:
1378 case ALC_SHORT_SOFT
:
1379 case ALC_UNSIGNED_SHORT_SOFT
:
1381 case ALC_UNSIGNED_INT_SOFT
:
1382 case ALC_FLOAT_SOFT
:
1388 DECL_CONST
static ALCboolean
IsValidALCChannels(ALCenum channels
)
1393 case ALC_STEREO_SOFT
:
1395 case ALC_5POINT1_SOFT
:
1396 case ALC_6POINT1_SOFT
:
1397 case ALC_7POINT1_SOFT
:
1404 /************************************************
1405 * Miscellaneous ALC helpers
1406 ************************************************/
1407 enum HrtfRequestMode
{
1413 extern inline void LockContext(ALCcontext
*context
);
1414 extern inline void UnlockContext(ALCcontext
*context
);
1416 void ALCdevice_Lock(ALCdevice
*device
)
1418 V0(device
->Backend
,lock
)();
1421 void ALCdevice_Unlock(ALCdevice
*device
)
1423 V0(device
->Backend
,unlock
)();
1427 /* SetDefaultWFXChannelOrder
1429 * Sets the default channel order used by WaveFormatEx.
1431 void SetDefaultWFXChannelOrder(ALCdevice
*device
)
1435 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1436 device
->ChannelName
[i
] = InvalidChannel
;
1438 switch(device
->FmtChans
)
1441 device
->ChannelName
[0] = FrontCenter
;
1444 device
->ChannelName
[0] = FrontLeft
;
1445 device
->ChannelName
[1] = FrontRight
;
1448 device
->ChannelName
[0] = FrontLeft
;
1449 device
->ChannelName
[1] = FrontRight
;
1450 device
->ChannelName
[2] = BackLeft
;
1451 device
->ChannelName
[3] = BackRight
;
1454 device
->ChannelName
[0] = FrontLeft
;
1455 device
->ChannelName
[1] = FrontRight
;
1456 device
->ChannelName
[2] = FrontCenter
;
1457 device
->ChannelName
[3] = LFE
;
1458 device
->ChannelName
[4] = SideLeft
;
1459 device
->ChannelName
[5] = SideRight
;
1462 device
->ChannelName
[0] = FrontLeft
;
1463 device
->ChannelName
[1] = FrontRight
;
1464 device
->ChannelName
[2] = FrontCenter
;
1465 device
->ChannelName
[3] = LFE
;
1466 device
->ChannelName
[4] = BackLeft
;
1467 device
->ChannelName
[5] = BackRight
;
1470 device
->ChannelName
[0] = FrontLeft
;
1471 device
->ChannelName
[1] = FrontRight
;
1472 device
->ChannelName
[2] = FrontCenter
;
1473 device
->ChannelName
[3] = LFE
;
1474 device
->ChannelName
[4] = BackCenter
;
1475 device
->ChannelName
[5] = SideLeft
;
1476 device
->ChannelName
[6] = SideRight
;
1479 device
->ChannelName
[0] = FrontLeft
;
1480 device
->ChannelName
[1] = FrontRight
;
1481 device
->ChannelName
[2] = FrontCenter
;
1482 device
->ChannelName
[3] = LFE
;
1483 device
->ChannelName
[4] = BackLeft
;
1484 device
->ChannelName
[5] = BackRight
;
1485 device
->ChannelName
[6] = SideLeft
;
1486 device
->ChannelName
[7] = SideRight
;
1488 case DevFmtBFormat3D
:
1489 device
->ChannelName
[0] = BFormatW
;
1490 device
->ChannelName
[1] = BFormatX
;
1491 device
->ChannelName
[2] = BFormatY
;
1492 device
->ChannelName
[3] = BFormatZ
;
1497 /* SetDefaultChannelOrder
1499 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1501 void SetDefaultChannelOrder(ALCdevice
*device
)
1505 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
1506 device
->ChannelName
[i
] = InvalidChannel
;
1508 switch(device
->FmtChans
)
1511 device
->ChannelName
[0] = FrontLeft
;
1512 device
->ChannelName
[1] = FrontRight
;
1513 device
->ChannelName
[2] = BackLeft
;
1514 device
->ChannelName
[3] = BackRight
;
1515 device
->ChannelName
[4] = FrontCenter
;
1516 device
->ChannelName
[5] = LFE
;
1519 device
->ChannelName
[0] = FrontLeft
;
1520 device
->ChannelName
[1] = FrontRight
;
1521 device
->ChannelName
[2] = BackLeft
;
1522 device
->ChannelName
[3] = BackRight
;
1523 device
->ChannelName
[4] = FrontCenter
;
1524 device
->ChannelName
[5] = LFE
;
1525 device
->ChannelName
[6] = SideLeft
;
1526 device
->ChannelName
[7] = SideRight
;
1529 /* Same as WFX order */
1535 case DevFmtBFormat3D
:
1536 SetDefaultWFXChannelOrder(device
);
1541 extern inline ALint
GetChannelIdxByName(const ALCdevice
*device
, enum Channel chan
);
1544 /* ALCcontext_DeferUpdates
1546 * Defers/suspends updates for the given context's listener and sources. This
1547 * does *NOT* stop mixing, but rather prevents certain property changes from
1550 void ALCcontext_DeferUpdates(ALCcontext
*context
)
1552 ALCdevice
*device
= context
->Device
;
1555 SetMixerFPUMode(&oldMode
);
1557 V0(device
->Backend
,lock
)();
1558 if(!context
->DeferUpdates
)
1560 context
->DeferUpdates
= AL_TRUE
;
1562 /* Make sure all pending updates are performed */
1563 UpdateContextSources(context
);
1564 #define UPDATE_SLOT(iter) do { \
1565 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1566 V((*iter)->EffectState,update)(device, *iter); \
1568 VECTOR_FOR_EACH(ALeffectslot
*, context
->ActiveAuxSlots
, UPDATE_SLOT
);
1571 V0(device
->Backend
,unlock
)();
1573 RestoreFPUMode(&oldMode
);
1576 /* ALCcontext_ProcessUpdates
1578 * Resumes update processing after being deferred.
1580 void ALCcontext_ProcessUpdates(ALCcontext
*context
)
1582 ALCdevice
*device
= context
->Device
;
1584 V0(device
->Backend
,lock
)();
1585 if(context
->DeferUpdates
)
1589 context
->DeferUpdates
= AL_FALSE
;
1591 LockUIntMapRead(&context
->SourceMap
);
1592 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
1594 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
1597 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
1598 Source
->Offset
>= 0.0)
1600 WriteLock(&Source
->queue_lock
);
1601 ApplyOffset(Source
);
1602 WriteUnlock(&Source
->queue_lock
);
1605 new_state
= Source
->new_state
;
1606 Source
->new_state
= AL_NONE
;
1608 SetSourceState(Source
, context
, new_state
);
1610 UnlockUIntMapRead(&context
->SourceMap
);
1612 V0(device
->Backend
,unlock
)();
1618 * Stores the latest ALC device error
1620 static void alcSetError(ALCdevice
*device
, ALCenum errorCode
)
1625 /* DebugBreak() will cause an exception if there is no debugger */
1626 if(IsDebuggerPresent())
1628 #elif defined(SIGTRAP)
1634 ATOMIC_STORE(&device
->LastError
, errorCode
);
1636 ATOMIC_STORE(&LastNullDeviceError
, errorCode
);
1642 * Updates the device's base clock time with however many samples have been
1643 * done. This is used so frequency changes on the device don't cause the time
1644 * to jump forward or back.
1646 static inline void UpdateClockBase(ALCdevice
*device
)
1648 device
->ClockBase
+= device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
;
1649 device
->SamplesDone
= 0;
1652 /* UpdateDeviceParams
1654 * Updates device parameters according to the attribute list (caller is
1655 * responsible for holding the list lock).
1657 static ALCenum
UpdateDeviceParams(ALCdevice
*device
, const ALCint
*attrList
)
1659 ALCcontext
*context
;
1660 enum HrtfRequestMode hrtf_appreq
= Hrtf_Default
;
1661 enum HrtfRequestMode hrtf_userreq
= Hrtf_Default
;
1662 enum DevFmtChannels oldChans
;
1663 enum DevFmtType oldType
;
1666 ALCsizei hrtf_id
= -1;
1669 // Check for attributes
1670 if(device
->Type
== Loopback
)
1676 GotAll
= GotFreq
|GotChans
|GotType
1678 ALCuint freq
, numMono
, numStereo
, numSends
;
1679 enum DevFmtChannels schans
;
1680 enum DevFmtType stype
;
1681 ALCuint attrIdx
= 0;
1686 WARN("Missing attributes for loopback device\n");
1687 return ALC_INVALID_VALUE
;
1690 numMono
= device
->NumMonoSources
;
1691 numStereo
= device
->NumStereoSources
;
1692 numSends
= device
->NumAuxSends
;
1693 schans
= device
->FmtChans
;
1694 stype
= device
->FmtType
;
1695 freq
= device
->Frequency
;
1697 while(attrList
[attrIdx
])
1699 if(attrList
[attrIdx
] == ALC_FORMAT_CHANNELS_SOFT
)
1701 ALCint val
= attrList
[attrIdx
+ 1];
1702 if(!IsValidALCChannels(val
) || !ChannelsFromDevFmt(val
))
1703 return ALC_INVALID_VALUE
;
1708 if(attrList
[attrIdx
] == ALC_FORMAT_TYPE_SOFT
)
1710 ALCint val
= attrList
[attrIdx
+ 1];
1711 if(!IsValidALCType(val
) || !BytesFromDevFmt(val
))
1712 return ALC_INVALID_VALUE
;
1717 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1719 freq
= attrList
[attrIdx
+ 1];
1720 if(freq
< MIN_OUTPUT_RATE
)
1721 return ALC_INVALID_VALUE
;
1725 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1727 numStereo
= attrList
[attrIdx
+ 1];
1728 if(numStereo
> device
->MaxNoOfSources
)
1729 numStereo
= device
->MaxNoOfSources
;
1731 numMono
= device
->MaxNoOfSources
- numStereo
;
1734 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1735 numSends
= attrList
[attrIdx
+ 1];
1737 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1739 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1740 hrtf_appreq
= Hrtf_Disable
;
1741 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1742 hrtf_appreq
= Hrtf_Enable
;
1744 hrtf_appreq
= Hrtf_Default
;
1747 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1748 hrtf_id
= attrList
[attrIdx
+ 1];
1753 if(gotFmt
!= GotAll
)
1755 WARN("Missing format for loopback device\n");
1756 return ALC_INVALID_VALUE
;
1759 ConfigValueUInt(NULL
, NULL
, "sends", &numSends
);
1760 numSends
= minu(MAX_SENDS
, numSends
);
1762 if((device
->Flags
&DEVICE_RUNNING
))
1763 V0(device
->Backend
,stop
)();
1764 device
->Flags
&= ~DEVICE_RUNNING
;
1766 UpdateClockBase(device
);
1768 device
->Frequency
= freq
;
1769 device
->FmtChans
= schans
;
1770 device
->FmtType
= stype
;
1771 device
->NumMonoSources
= numMono
;
1772 device
->NumStereoSources
= numStereo
;
1773 device
->NumAuxSends
= numSends
;
1775 else if(attrList
&& attrList
[0])
1777 ALCuint freq
, numMono
, numStereo
, numSends
;
1778 ALCuint attrIdx
= 0;
1780 /* If a context is already running on the device, stop playback so the
1781 * device attributes can be updated. */
1782 if((device
->Flags
&DEVICE_RUNNING
))
1783 V0(device
->Backend
,stop
)();
1784 device
->Flags
&= ~DEVICE_RUNNING
;
1786 freq
= device
->Frequency
;
1787 numMono
= device
->NumMonoSources
;
1788 numStereo
= device
->NumStereoSources
;
1789 numSends
= device
->NumAuxSends
;
1791 while(attrList
[attrIdx
])
1793 if(attrList
[attrIdx
] == ALC_FREQUENCY
)
1795 freq
= attrList
[attrIdx
+ 1];
1796 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
1799 if(attrList
[attrIdx
] == ALC_STEREO_SOURCES
)
1801 numStereo
= attrList
[attrIdx
+ 1];
1802 if(numStereo
> device
->MaxNoOfSources
)
1803 numStereo
= device
->MaxNoOfSources
;
1805 numMono
= device
->MaxNoOfSources
- numStereo
;
1808 if(attrList
[attrIdx
] == ALC_MAX_AUXILIARY_SENDS
)
1809 numSends
= attrList
[attrIdx
+ 1];
1811 if(attrList
[attrIdx
] == ALC_HRTF_SOFT
)
1813 if(attrList
[attrIdx
+ 1] == ALC_FALSE
)
1814 hrtf_appreq
= Hrtf_Disable
;
1815 else if(attrList
[attrIdx
+ 1] == ALC_TRUE
)
1816 hrtf_appreq
= Hrtf_Enable
;
1818 hrtf_appreq
= Hrtf_Default
;
1821 if(attrList
[attrIdx
] == ALC_HRTF_ID_SOFT
)
1822 hrtf_id
= attrList
[attrIdx
+ 1];
1827 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "frequency", &freq
);
1828 freq
= maxu(freq
, MIN_OUTPUT_RATE
);
1830 ConfigValueUInt(al_string_get_cstr(device
->DeviceName
), NULL
, "sends", &numSends
);
1831 numSends
= minu(MAX_SENDS
, numSends
);
1833 UpdateClockBase(device
);
1835 device
->UpdateSize
= (ALuint64
)device
->UpdateSize
* freq
/
1837 /* SSE and Neon do best with the update size being a multiple of 4 */
1838 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
1839 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
1841 device
->Frequency
= freq
;
1842 device
->NumMonoSources
= numMono
;
1843 device
->NumStereoSources
= numStereo
;
1844 device
->NumAuxSends
= numSends
;
1847 if((device
->Flags
&DEVICE_RUNNING
))
1848 return ALC_NO_ERROR
;
1850 al_free(device
->Uhj_Encoder
);
1851 device
->Uhj_Encoder
= NULL
;
1853 al_free(device
->Bs2b
);
1854 device
->Bs2b
= NULL
;
1856 al_free(device
->DryBuffer
);
1857 device
->DryBuffer
= NULL
;
1859 UpdateClockBase(device
);
1861 device
->Hrtf_Status
= ALC_HRTF_DISABLED_SOFT
;
1862 if(device
->Type
!= Loopback
)
1865 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf", &hrtf
))
1867 if(strcasecmp(hrtf
, "true") == 0)
1868 hrtf_userreq
= Hrtf_Enable
;
1869 else if(strcasecmp(hrtf
, "false") == 0)
1870 hrtf_userreq
= Hrtf_Disable
;
1871 else if(strcasecmp(hrtf
, "auto") != 0)
1872 ERR("Unexpected hrtf value: %s\n", hrtf
);
1875 if(hrtf_userreq
== Hrtf_Enable
|| (hrtf_userreq
!= Hrtf_Disable
&& hrtf_appreq
== Hrtf_Enable
))
1877 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1879 VECTOR_DEINIT(device
->Hrtf_List
);
1880 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1882 if(VECTOR_SIZE(device
->Hrtf_List
) > 0)
1884 device
->FmtChans
= DevFmtStereo
;
1885 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
1886 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
).hrtf
);
1888 device
->Frequency
= GetHrtfSampleRate(VECTOR_ELEM(device
->Hrtf_List
, 0).hrtf
);
1889 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_FREQUENCY_REQUEST
;
1893 hrtf_userreq
= hrtf_appreq
= Hrtf_Default
;
1894 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1898 else if(hrtf_appreq
== Hrtf_Enable
)
1901 /* Loopback device. We don't need to match to a specific HRTF entry
1902 * here. If the requested ID matches, we'll pick that later, if not,
1903 * we'll try to auto-select one anyway. */
1904 if(device
->FmtChans
!= DevFmtStereo
)
1905 i
= VECTOR_SIZE(device
->Hrtf_List
);
1908 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
1910 VECTOR_DEINIT(device
->Hrtf_List
);
1911 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
1913 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
1915 const struct Hrtf
*hrtf
= VECTOR_ELEM(device
->Hrtf_List
, i
).hrtf
;
1916 if(GetHrtfSampleRate(hrtf
) == device
->Frequency
)
1920 if(i
== VECTOR_SIZE(device
->Hrtf_List
))
1922 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1923 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
1924 hrtf_appreq
= Hrtf_Default
;
1925 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1929 oldFreq
= device
->Frequency
;
1930 oldChans
= device
->FmtChans
;
1931 oldType
= device
->FmtType
;
1933 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1934 (device
->Flags
&DEVICE_CHANNELS_REQUEST
)?"*":"", DevFmtChannelsString(device
->FmtChans
),
1935 (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
)?"*":"", DevFmtTypeString(device
->FmtType
),
1936 (device
->Flags
&DEVICE_FREQUENCY_REQUEST
)?"*":"", device
->Frequency
,
1937 device
->UpdateSize
, device
->NumUpdates
1940 if(V0(device
->Backend
,reset
)() == ALC_FALSE
)
1941 return ALC_INVALID_DEVICE
;
1943 if(device
->FmtChans
!= oldChans
&& (device
->Flags
&DEVICE_CHANNELS_REQUEST
))
1945 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans
),
1946 DevFmtChannelsString(device
->FmtChans
));
1947 device
->Flags
&= ~DEVICE_CHANNELS_REQUEST
;
1949 if(device
->FmtType
!= oldType
&& (device
->Flags
&DEVICE_SAMPLE_TYPE_REQUEST
))
1951 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType
),
1952 DevFmtTypeString(device
->FmtType
));
1953 device
->Flags
&= ~DEVICE_SAMPLE_TYPE_REQUEST
;
1955 if(device
->Frequency
!= oldFreq
&& (device
->Flags
&DEVICE_FREQUENCY_REQUEST
))
1957 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq
, device
->Frequency
);
1958 device
->Flags
&= ~DEVICE_FREQUENCY_REQUEST
;
1961 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1962 DevFmtChannelsString(device
->FmtChans
), DevFmtTypeString(device
->FmtType
),
1963 device
->Frequency
, device
->UpdateSize
, device
->NumUpdates
1966 if((device
->UpdateSize
&3) != 0)
1968 if((CPUCapFlags
&CPU_CAP_SSE
))
1969 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1970 if((CPUCapFlags
&CPU_CAP_NEON
))
1971 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device
->UpdateSize
);
1974 device
->Hrtf
= NULL
;
1975 device
->Hrtf_Mode
= DisabledHrtf
;
1976 al_string_clear(&device
->Hrtf_Name
);
1977 if(device
->FmtChans
!= DevFmtStereo
)
1979 if(hrtf_appreq
== Hrtf_Enable
)
1980 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
1984 bool headphones
= device
->IsHeadphones
;
1985 enum HrtfMode hrtf_mode
= FullHrtf
;
1986 ALCenum hrtf_status
= device
->Hrtf_Status
;
1991 if(device
->Type
!= Loopback
)
1993 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "stereo-mode", &mode
))
1995 if(strcasecmp(mode
, "headphones") == 0)
1997 else if(strcasecmp(mode
, "speakers") == 0)
1999 else if(strcasecmp(mode
, "auto") != 0)
2000 ERR("Unexpected stereo-mode: %s\n", mode
);
2003 if(ConfigValueStr(al_string_get_cstr(device
->DeviceName
), NULL
, "hrtf-mode", &mode
))
2005 if(strcasecmp(mode
, "full") == 0)
2006 hrtf_mode
= FullHrtf
;
2007 else if(strcasecmp(mode
, "basic") == 0)
2008 hrtf_mode
= BasicHrtf
;
2010 ERR("Unexpected hrtf-mode: %s\n", mode
);
2015 if(hrtf_userreq
== Hrtf_Default
)
2017 usehrtf
= (headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2018 (hrtf_appreq
== Hrtf_Enable
);
2019 if(headphones
&& hrtf_appreq
!= Hrtf_Disable
)
2020 hrtf_status
= ALC_HRTF_HEADPHONES_DETECTED_SOFT
;
2022 hrtf_status
= ALC_HRTF_ENABLED_SOFT
;
2026 usehrtf
= (hrtf_userreq
== Hrtf_Enable
);
2028 hrtf_status
= ALC_HRTF_DENIED_SOFT
;
2030 hrtf_status
= ALC_HRTF_REQUIRED_SOFT
;
2034 device
->Hrtf_Status
= hrtf_status
;
2039 device
->Hrtf_Status
= ALC_HRTF_UNSUPPORTED_FORMAT_SOFT
;
2040 if(VECTOR_SIZE(device
->Hrtf_List
) == 0)
2042 VECTOR_DEINIT(device
->Hrtf_List
);
2043 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2046 if(hrtf_id
>= 0 && (size_t)hrtf_id
< VECTOR_SIZE(device
->Hrtf_List
))
2048 const HrtfEntry
*entry
= &VECTOR_ELEM(device
->Hrtf_List
, hrtf_id
);
2049 if(GetHrtfSampleRate(entry
->hrtf
) == device
->Frequency
)
2051 device
->Hrtf
= entry
->hrtf
;
2052 al_string_copy(&device
->Hrtf_Name
, entry
->name
);
2057 for(i
= 0;i
< VECTOR_SIZE(device
->Hrtf_List
);i
++)
2059 const HrtfEntry
*entry
= &VECTOR_ELEM(device
->Hrtf_List
, i
);
2060 if(GetHrtfSampleRate(entry
->hrtf
) == device
->Frequency
)
2062 device
->Hrtf
= entry
->hrtf
;
2063 al_string_copy(&device
->Hrtf_Name
, entry
->name
);
2071 device
->Hrtf_Mode
= hrtf_mode
;
2072 device
->Hrtf_Status
= hrtf_status
;
2073 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device
->Hrtf_Name
));
2077 TRACE("HRTF disabled\n");
2079 bs2blevel
= ((headphones
&& hrtf_appreq
!= Hrtf_Disable
) ||
2080 (hrtf_appreq
== Hrtf_Enable
)) ? 5 : 0;
2081 if(device
->Type
!= Loopback
)
2082 ConfigValueInt(al_string_get_cstr(device
->DeviceName
), NULL
, "cf_level", &bs2blevel
);
2083 if(bs2blevel
> 0 && bs2blevel
<= 6)
2085 device
->Bs2b
= al_calloc(16, sizeof(*device
->Bs2b
));
2086 bs2b_set_params(device
->Bs2b
, bs2blevel
, device
->Frequency
);
2087 TRACE("BS2B enabled\n");
2091 TRACE("BS2B disabled\n");
2094 device
->Uhj_Encoder
= al_calloc(16, sizeof(Uhj2Encoder
));
2098 aluInitPanning(device
);
2100 /* With HRTF, allocate two extra channels for the post-filter output. */
2101 size
= device
->NumChannels
* sizeof(device
->DryBuffer
[0]);
2102 if(device
->Hrtf
|| device
->Uhj_Encoder
)
2103 size
+= 2 * sizeof(device
->DryBuffer
[0]);
2104 device
->DryBuffer
= al_calloc(16, size
);
2105 if(!device
->DryBuffer
)
2107 ERR("Failed to allocate "SZFMT
" bytes for mix buffer\n", size
);
2108 return ALC_INVALID_DEVICE
;
2111 SetMixerFPUMode(&oldMode
);
2112 V0(device
->Backend
,lock
)();
2113 context
= ATOMIC_LOAD(&device
->ContextList
);
2118 ATOMIC_STORE(&context
->UpdateSources
, AL_FALSE
);
2119 LockUIntMapRead(&context
->EffectSlotMap
);
2120 for(pos
= 0;pos
< context
->EffectSlotMap
.size
;pos
++)
2122 ALeffectslot
*slot
= context
->EffectSlotMap
.array
[pos
].value
;
2124 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2126 UnlockUIntMapRead(&context
->EffectSlotMap
);
2127 V0(device
->Backend
,unlock
)();
2128 RestoreFPUMode(&oldMode
);
2129 return ALC_INVALID_DEVICE
;
2131 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2132 V(slot
->EffectState
,update
)(device
, slot
);
2134 UnlockUIntMapRead(&context
->EffectSlotMap
);
2136 LockUIntMapRead(&context
->SourceMap
);
2137 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
2139 ALsource
*source
= context
->SourceMap
.array
[pos
].value
;
2140 ALuint s
= device
->NumAuxSends
;
2141 while(s
< MAX_SENDS
)
2143 if(source
->Send
[s
].Slot
)
2144 DecrementRef(&source
->Send
[s
].Slot
->ref
);
2145 source
->Send
[s
].Slot
= NULL
;
2146 source
->Send
[s
].Gain
= 1.0f
;
2147 source
->Send
[s
].GainHF
= 1.0f
;
2150 ATOMIC_STORE(&source
->NeedsUpdate
, AL_TRUE
);
2152 UnlockUIntMapRead(&context
->SourceMap
);
2154 for(pos
= 0;pos
< context
->VoiceCount
;pos
++)
2156 ALvoice
*voice
= &context
->Voices
[pos
];
2157 ALsource
*source
= voice
->Source
;
2161 ATOMIC_STORE(&source
->NeedsUpdate
, AL_FALSE
);
2162 voice
->Update(voice
, source
, context
);
2166 context
= context
->next
;
2168 if(device
->DefaultSlot
)
2170 ALeffectslot
*slot
= device
->DefaultSlot
;
2172 if(V(slot
->EffectState
,deviceUpdate
)(device
) == AL_FALSE
)
2174 V0(device
->Backend
,unlock
)();
2175 RestoreFPUMode(&oldMode
);
2176 return ALC_INVALID_DEVICE
;
2178 ATOMIC_STORE(&slot
->NeedsUpdate
, AL_FALSE
);
2179 V(slot
->EffectState
,update
)(device
, slot
);
2181 V0(device
->Backend
,unlock
)();
2182 RestoreFPUMode(&oldMode
);
2184 if(!(device
->Flags
&DEVICE_PAUSED
))
2186 if(V0(device
->Backend
,start
)() == ALC_FALSE
)
2187 return ALC_INVALID_DEVICE
;
2188 device
->Flags
|= DEVICE_RUNNING
;
2191 return ALC_NO_ERROR
;
2196 * Frees the device structure, and destroys any objects the app failed to
2197 * delete. Called once there's no more references on the device.
2199 static ALCvoid
FreeDevice(ALCdevice
*device
)
2201 TRACE("%p\n", device
);
2203 V0(device
->Backend
,close
)();
2204 DELETE_OBJ(device
->Backend
);
2205 device
->Backend
= NULL
;
2207 if(device
->DefaultSlot
)
2209 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
2210 device
->DefaultSlot
= NULL
;
2214 if(device
->BufferMap
.size
> 0)
2216 WARN("(%p) Deleting %d Buffer(s)\n", device
, device
->BufferMap
.size
);
2217 ReleaseALBuffers(device
);
2219 ResetUIntMap(&device
->BufferMap
);
2221 if(device
->EffectMap
.size
> 0)
2223 WARN("(%p) Deleting %d Effect(s)\n", device
, device
->EffectMap
.size
);
2224 ReleaseALEffects(device
);
2226 ResetUIntMap(&device
->EffectMap
);
2228 if(device
->FilterMap
.size
> 0)
2230 WARN("(%p) Deleting %d Filter(s)\n", device
, device
->FilterMap
.size
);
2231 ReleaseALFilters(device
);
2233 ResetUIntMap(&device
->FilterMap
);
2235 AL_STRING_DEINIT(device
->Hrtf_Name
);
2236 FreeHrtfList(&device
->Hrtf_List
);
2238 al_free(device
->Bs2b
);
2239 device
->Bs2b
= NULL
;
2241 al_free(device
->Uhj_Encoder
);
2242 device
->Uhj_Encoder
= NULL
;
2244 AL_STRING_DEINIT(device
->DeviceName
);
2246 al_free(device
->DryBuffer
);
2247 device
->DryBuffer
= NULL
;
2253 void ALCdevice_IncRef(ALCdevice
*device
)
2256 ref
= IncrementRef(&device
->ref
);
2257 TRACEREF("%p increasing refcount to %u\n", device
, ref
);
2260 void ALCdevice_DecRef(ALCdevice
*device
)
2263 ref
= DecrementRef(&device
->ref
);
2264 TRACEREF("%p decreasing refcount to %u\n", device
, ref
);
2265 if(ref
== 0) FreeDevice(device
);
2270 * Checks if the device handle is valid, and increments its ref count if so.
2272 static ALCboolean
VerifyDevice(ALCdevice
**device
)
2274 ALCdevice
*tmpDevice
;
2277 tmpDevice
= ATOMIC_LOAD(&DeviceList
);
2280 if(tmpDevice
== *device
)
2282 ALCdevice_IncRef(tmpDevice
);
2286 tmpDevice
= tmpDevice
->next
;
2297 * Initializes context fields
2299 static ALvoid
InitContext(ALCcontext
*Context
)
2301 ALlistener
*listener
= Context
->Listener
;
2302 //Initialise listener
2303 listener
->Gain
= 1.0f
;
2304 listener
->MetersPerUnit
= 1.0f
;
2305 aluVectorSet(&listener
->Position
, 0.0f
, 0.0f
, 0.0f
, 1.0f
);
2306 aluVectorSet(&listener
->Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2307 listener
->Forward
[0] = 0.0f
;
2308 listener
->Forward
[1] = 0.0f
;
2309 listener
->Forward
[2] = -1.0f
;
2310 listener
->Up
[0] = 0.0f
;
2311 listener
->Up
[1] = 1.0f
;
2312 listener
->Up
[2] = 0.0f
;
2313 aluMatrixdSet(&listener
->Params
.Matrix
,
2319 aluVectorSet(&listener
->Params
.Velocity
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
2322 ATOMIC_INIT(&Context
->LastError
, AL_NO_ERROR
);
2323 ATOMIC_INIT(&Context
->UpdateSources
, AL_FALSE
);
2324 InitUIntMap(&Context
->SourceMap
, Context
->Device
->MaxNoOfSources
);
2325 InitUIntMap(&Context
->EffectSlotMap
, Context
->Device
->AuxiliaryEffectSlotMax
);
2328 Context
->DistanceModel
= DefaultDistanceModel
;
2329 Context
->SourceDistanceModel
= AL_FALSE
;
2330 Context
->DopplerFactor
= 1.0f
;
2331 Context
->DopplerVelocity
= 1.0f
;
2332 Context
->SpeedOfSound
= SPEEDOFSOUNDMETRESPERSEC
;
2333 Context
->DeferUpdates
= AL_FALSE
;
2335 Context
->ExtensionList
= alExtList
;
2341 * Cleans up the context, and destroys any remaining objects the app failed to
2342 * delete. Called once there's no more references on the context.
2344 static void FreeContext(ALCcontext
*context
)
2346 TRACE("%p\n", context
);
2348 if(context
->SourceMap
.size
> 0)
2350 WARN("(%p) Deleting %d Source(s)\n", context
, context
->SourceMap
.size
);
2351 ReleaseALSources(context
);
2353 ResetUIntMap(&context
->SourceMap
);
2355 if(context
->EffectSlotMap
.size
> 0)
2357 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context
, context
->EffectSlotMap
.size
);
2358 ReleaseALAuxiliaryEffectSlots(context
);
2360 ResetUIntMap(&context
->EffectSlotMap
);
2362 al_free(context
->Voices
);
2363 context
->Voices
= NULL
;
2364 context
->VoiceCount
= 0;
2365 context
->MaxVoices
= 0;
2367 VECTOR_DEINIT(context
->ActiveAuxSlots
);
2369 ALCdevice_DecRef(context
->Device
);
2370 context
->Device
= NULL
;
2372 //Invalidate context
2373 memset(context
, 0, sizeof(ALCcontext
));
2379 * Removes the context reference from the given device and removes it from
2380 * being current on the running thread or globally.
2382 static void ReleaseContext(ALCcontext
*context
, ALCdevice
*device
)
2384 ALCcontext
*nextctx
;
2385 ALCcontext
*origctx
;
2387 if(altss_get(LocalContext
) == context
)
2389 WARN("%p released while current on thread\n", context
);
2390 altss_set(LocalContext
, NULL
);
2391 ALCcontext_DecRef(context
);
2395 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &GlobalContext
, &origctx
, NULL
))
2396 ALCcontext_DecRef(context
);
2398 ALCdevice_Lock(device
);
2400 nextctx
= context
->next
;
2401 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext
*, &device
->ContextList
, &origctx
, nextctx
))
2407 } while(!COMPARE_EXCHANGE(&list
->next
, &origctx
, nextctx
));
2409 ALCdevice_Unlock(device
);
2411 ALCcontext_DecRef(context
);
2414 void ALCcontext_IncRef(ALCcontext
*context
)
2417 ref
= IncrementRef(&context
->ref
);
2418 TRACEREF("%p increasing refcount to %u\n", context
, ref
);
2421 void ALCcontext_DecRef(ALCcontext
*context
)
2424 ref
= DecrementRef(&context
->ref
);
2425 TRACEREF("%p decreasing refcount to %u\n", context
, ref
);
2426 if(ref
== 0) FreeContext(context
);
2429 static void ReleaseThreadCtx(void *ptr
)
2431 WARN("%p current for thread being destroyed\n", ptr
);
2432 ALCcontext_DecRef(ptr
);
2437 * Checks that the given context is valid, and increments its reference count.
2439 static ALCboolean
VerifyContext(ALCcontext
**context
)
2444 dev
= ATOMIC_LOAD(&DeviceList
);
2447 ALCcontext
*ctx
= ATOMIC_LOAD(&dev
->ContextList
);
2452 ALCcontext_IncRef(ctx
);
2469 * Returns the currently active context for this thread, and adds a reference
2470 * without locking it.
2472 ALCcontext
*GetContextRef(void)
2474 ALCcontext
*context
;
2476 context
= altss_get(LocalContext
);
2478 ALCcontext_IncRef(context
);
2482 context
= ATOMIC_LOAD(&GlobalContext
);
2484 ALCcontext_IncRef(context
);
2492 /************************************************
2493 * Standard ALC functions
2494 ************************************************/
2498 * Return last ALC generated error code for the given device
2500 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
2504 if(VerifyDevice(&device
))
2506 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &device
->LastError
, ALC_NO_ERROR
);
2507 ALCdevice_DecRef(device
);
2510 errorCode
= ATOMIC_EXCHANGE(ALCenum
, &LastNullDeviceError
, ALC_NO_ERROR
);
2516 /* alcSuspendContext
2518 * Suspends updates for the given context
2520 ALC_API ALCvoid ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
2525 if(!VerifyContext(&context
))
2526 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2529 ALCcontext_DeferUpdates(context
);
2530 ALCcontext_DecRef(context
);
2534 /* alcProcessContext
2536 * Resumes processing updates for the given context
2538 ALC_API ALCvoid ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
2543 if(!VerifyContext(&context
))
2544 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
2547 ALCcontext_ProcessUpdates(context
);
2548 ALCcontext_DecRef(context
);
2555 * Returns information about the device, and error strings
2557 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*Device
, ALCenum param
)
2559 const ALCchar
*value
= NULL
;
2567 case ALC_INVALID_ENUM
:
2568 value
= alcErrInvalidEnum
;
2571 case ALC_INVALID_VALUE
:
2572 value
= alcErrInvalidValue
;
2575 case ALC_INVALID_DEVICE
:
2576 value
= alcErrInvalidDevice
;
2579 case ALC_INVALID_CONTEXT
:
2580 value
= alcErrInvalidContext
;
2583 case ALC_OUT_OF_MEMORY
:
2584 value
= alcErrOutOfMemory
;
2587 case ALC_DEVICE_SPECIFIER
:
2588 value
= alcDefaultName
;
2591 case ALC_ALL_DEVICES_SPECIFIER
:
2592 if(VerifyDevice(&Device
))
2594 value
= al_string_get_cstr(Device
->DeviceName
);
2595 ALCdevice_DecRef(Device
);
2599 ProbeAllDevicesList();
2600 value
= al_string_get_cstr(alcAllDevicesList
);
2604 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2605 if(VerifyDevice(&Device
))
2607 value
= al_string_get_cstr(Device
->DeviceName
);
2608 ALCdevice_DecRef(Device
);
2612 ProbeCaptureDeviceList();
2613 value
= al_string_get_cstr(alcCaptureDeviceList
);
2617 /* Default devices are always first in the list */
2618 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2619 value
= alcDefaultName
;
2622 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2623 if(al_string_empty(alcAllDevicesList
))
2624 ProbeAllDevicesList();
2626 VerifyDevice(&Device
);
2628 free(alcDefaultAllDevicesSpecifier
);
2629 alcDefaultAllDevicesSpecifier
= strdup(al_string_get_cstr(alcAllDevicesList
));
2630 if(!alcDefaultAllDevicesSpecifier
)
2631 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2633 value
= alcDefaultAllDevicesSpecifier
;
2634 if(Device
) ALCdevice_DecRef(Device
);
2637 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2638 if(al_string_empty(alcCaptureDeviceList
))
2639 ProbeCaptureDeviceList();
2641 VerifyDevice(&Device
);
2643 free(alcCaptureDefaultDeviceSpecifier
);
2644 alcCaptureDefaultDeviceSpecifier
= strdup(al_string_get_cstr(alcCaptureDeviceList
));
2645 if(!alcCaptureDefaultDeviceSpecifier
)
2646 alcSetError(Device
, ALC_OUT_OF_MEMORY
);
2648 value
= alcCaptureDefaultDeviceSpecifier
;
2649 if(Device
) ALCdevice_DecRef(Device
);
2652 case ALC_EXTENSIONS
:
2653 if(!VerifyDevice(&Device
))
2654 value
= alcNoDeviceExtList
;
2657 value
= alcExtensionList
;
2658 ALCdevice_DecRef(Device
);
2662 case ALC_HRTF_SPECIFIER_SOFT
:
2663 if(!VerifyDevice(&Device
))
2664 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2668 value
= (Device
->Hrtf
? al_string_get_cstr(Device
->Hrtf_Name
) : "");
2670 ALCdevice_DecRef(Device
);
2675 VerifyDevice(&Device
);
2676 alcSetError(Device
, ALC_INVALID_ENUM
);
2677 if(Device
) ALCdevice_DecRef(Device
);
2685 static ALCsizei
GetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2689 if(size
<= 0 || values
== NULL
)
2691 alcSetError(device
, ALC_INVALID_VALUE
);
2699 case ALC_MAJOR_VERSION
:
2700 values
[0] = alcMajorVersion
;
2702 case ALC_MINOR_VERSION
:
2703 values
[0] = alcMinorVersion
;
2706 case ALC_ATTRIBUTES_SIZE
:
2707 case ALC_ALL_ATTRIBUTES
:
2711 case ALC_MONO_SOURCES
:
2712 case ALC_STEREO_SOURCES
:
2713 case ALC_CAPTURE_SAMPLES
:
2714 case ALC_FORMAT_CHANNELS_SOFT
:
2715 case ALC_FORMAT_TYPE_SOFT
:
2716 alcSetError(NULL
, ALC_INVALID_DEVICE
);
2720 alcSetError(NULL
, ALC_INVALID_ENUM
);
2726 if(device
->Type
== Capture
)
2730 case ALC_CAPTURE_SAMPLES
:
2731 V0(device
->Backend
,lock
)();
2732 values
[0] = V0(device
->Backend
,availableSamples
)();
2733 V0(device
->Backend
,unlock
)();
2737 values
[0] = device
->Connected
;
2741 alcSetError(device
, ALC_INVALID_ENUM
);
2750 case ALC_MAJOR_VERSION
:
2751 values
[0] = alcMajorVersion
;
2754 case ALC_MINOR_VERSION
:
2755 values
[0] = alcMinorVersion
;
2758 case ALC_EFX_MAJOR_VERSION
:
2759 values
[0] = alcEFXMajorVersion
;
2762 case ALC_EFX_MINOR_VERSION
:
2763 values
[0] = alcEFXMinorVersion
;
2766 case ALC_ATTRIBUTES_SIZE
:
2770 case ALC_ALL_ATTRIBUTES
:
2773 alcSetError(device
, ALC_INVALID_VALUE
);
2778 values
[i
++] = ALC_FREQUENCY
;
2779 values
[i
++] = device
->Frequency
;
2781 if(device
->Type
!= Loopback
)
2783 values
[i
++] = ALC_REFRESH
;
2784 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2786 values
[i
++] = ALC_SYNC
;
2787 values
[i
++] = ALC_FALSE
;
2791 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2792 values
[i
++] = device
->FmtChans
;
2794 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2795 values
[i
++] = device
->FmtType
;
2798 values
[i
++] = ALC_MONO_SOURCES
;
2799 values
[i
++] = device
->NumMonoSources
;
2801 values
[i
++] = ALC_STEREO_SOURCES
;
2802 values
[i
++] = device
->NumStereoSources
;
2804 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2805 values
[i
++] = device
->NumAuxSends
;
2807 values
[i
++] = ALC_HRTF_SOFT
;
2808 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2810 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2811 values
[i
++] = device
->Hrtf_Status
;
2817 values
[0] = device
->Frequency
;
2821 if(device
->Type
== Loopback
)
2823 alcSetError(device
, ALC_INVALID_DEVICE
);
2826 values
[0] = device
->Frequency
/ device
->UpdateSize
;
2830 if(device
->Type
== Loopback
)
2832 alcSetError(device
, ALC_INVALID_DEVICE
);
2835 values
[0] = ALC_FALSE
;
2838 case ALC_FORMAT_CHANNELS_SOFT
:
2839 if(device
->Type
!= Loopback
)
2841 alcSetError(device
, ALC_INVALID_DEVICE
);
2844 values
[0] = device
->FmtChans
;
2847 case ALC_FORMAT_TYPE_SOFT
:
2848 if(device
->Type
!= Loopback
)
2850 alcSetError(device
, ALC_INVALID_DEVICE
);
2853 values
[0] = device
->FmtType
;
2856 case ALC_MONO_SOURCES
:
2857 values
[0] = device
->NumMonoSources
;
2860 case ALC_STEREO_SOURCES
:
2861 values
[0] = device
->NumStereoSources
;
2864 case ALC_MAX_AUXILIARY_SENDS
:
2865 values
[0] = device
->NumAuxSends
;
2869 values
[0] = device
->Connected
;
2873 values
[0] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2876 case ALC_HRTF_STATUS_SOFT
:
2877 values
[0] = device
->Hrtf_Status
;
2880 case ALC_NUM_HRTF_SPECIFIERS_SOFT
:
2881 FreeHrtfList(&device
->Hrtf_List
);
2882 device
->Hrtf_List
= EnumerateHrtf(device
->DeviceName
);
2883 values
[0] = (ALCint
)VECTOR_SIZE(device
->Hrtf_List
);
2887 alcSetError(device
, ALC_INVALID_ENUM
);
2895 * Returns information about the device and the version of OpenAL
2897 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
2899 VerifyDevice(&device
);
2900 if(size
<= 0 || values
== NULL
)
2901 alcSetError(device
, ALC_INVALID_VALUE
);
2903 GetIntegerv(device
, param
, size
, values
);
2904 if(device
) ALCdevice_DecRef(device
);
2907 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALCsizei size
, ALCint64SOFT
*values
)
2912 VerifyDevice(&device
);
2913 if(size
<= 0 || values
== NULL
)
2914 alcSetError(device
, ALC_INVALID_VALUE
);
2915 else if(!device
|| device
->Type
== Capture
)
2917 ivals
= malloc(size
* sizeof(ALCint
));
2918 size
= GetIntegerv(device
, pname
, size
, ivals
);
2919 for(i
= 0;i
< size
;i
++)
2920 values
[i
] = ivals
[i
];
2923 else /* render device */
2927 case ALC_ATTRIBUTES_SIZE
:
2931 case ALC_ALL_ATTRIBUTES
:
2933 alcSetError(device
, ALC_INVALID_VALUE
);
2938 V0(device
->Backend
,lock
)();
2939 values
[i
++] = ALC_FREQUENCY
;
2940 values
[i
++] = device
->Frequency
;
2942 if(device
->Type
!= Loopback
)
2944 values
[i
++] = ALC_REFRESH
;
2945 values
[i
++] = device
->Frequency
/ device
->UpdateSize
;
2947 values
[i
++] = ALC_SYNC
;
2948 values
[i
++] = ALC_FALSE
;
2952 values
[i
++] = ALC_FORMAT_CHANNELS_SOFT
;
2953 values
[i
++] = device
->FmtChans
;
2955 values
[i
++] = ALC_FORMAT_TYPE_SOFT
;
2956 values
[i
++] = device
->FmtType
;
2959 values
[i
++] = ALC_MONO_SOURCES
;
2960 values
[i
++] = device
->NumMonoSources
;
2962 values
[i
++] = ALC_STEREO_SOURCES
;
2963 values
[i
++] = device
->NumStereoSources
;
2965 values
[i
++] = ALC_MAX_AUXILIARY_SENDS
;
2966 values
[i
++] = device
->NumAuxSends
;
2968 values
[i
++] = ALC_HRTF_SOFT
;
2969 values
[i
++] = (device
->Hrtf
? ALC_TRUE
: ALC_FALSE
);
2971 values
[i
++] = ALC_HRTF_STATUS_SOFT
;
2972 values
[i
++] = device
->Hrtf_Status
;
2974 values
[i
++] = ALC_DEVICE_CLOCK_SOFT
;
2975 values
[i
++] = device
->ClockBase
+
2976 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2979 V0(device
->Backend
,unlock
)();
2983 case ALC_DEVICE_CLOCK_SOFT
:
2984 V0(device
->Backend
,lock
)();
2985 *values
= device
->ClockBase
+
2986 (device
->SamplesDone
* DEVICE_CLOCK_RES
/ device
->Frequency
);
2987 V0(device
->Backend
,unlock
)();
2991 ivals
= malloc(size
* sizeof(ALCint
));
2992 size
= GetIntegerv(device
, pname
, size
, ivals
);
2993 for(i
= 0;i
< size
;i
++)
2994 values
[i
] = ivals
[i
];
3000 ALCdevice_DecRef(device
);
3004 /* alcIsExtensionPresent
3006 * Determines if there is support for a particular extension
3008 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extName
)
3010 ALCboolean bResult
= ALC_FALSE
;
3012 VerifyDevice(&device
);
3015 alcSetError(device
, ALC_INVALID_VALUE
);
3018 size_t len
= strlen(extName
);
3019 const char *ptr
= (device
? alcExtensionList
: alcNoDeviceExtList
);
3022 if(strncasecmp(ptr
, extName
, len
) == 0 &&
3023 (ptr
[len
] == '\0' || isspace(ptr
[len
])))
3028 if((ptr
=strchr(ptr
, ' ')) != NULL
)
3032 } while(isspace(*ptr
));
3037 ALCdevice_DecRef(device
);
3042 /* alcGetProcAddress
3044 * Retrieves the function address for a particular extension function
3046 ALC_API ALCvoid
* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcName
)
3048 ALCvoid
*ptr
= NULL
;
3052 VerifyDevice(&device
);
3053 alcSetError(device
, ALC_INVALID_VALUE
);
3054 if(device
) ALCdevice_DecRef(device
);
3059 while(alcFunctions
[i
].funcName
&& strcmp(alcFunctions
[i
].funcName
, funcName
) != 0)
3061 ptr
= alcFunctions
[i
].address
;
3070 * Get the value for a particular ALC enumeration name
3072 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumName
)
3078 VerifyDevice(&device
);
3079 alcSetError(device
, ALC_INVALID_VALUE
);
3080 if(device
) ALCdevice_DecRef(device
);
3085 while(enumeration
[i
].enumName
&& strcmp(enumeration
[i
].enumName
, enumName
) != 0)
3087 val
= enumeration
[i
].value
;
3096 * Create and attach a context to the given device.
3098 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrList
)
3100 ALCcontext
*ALContext
;
3104 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3107 alcSetError(device
, ALC_INVALID_DEVICE
);
3108 if(device
) ALCdevice_DecRef(device
);
3112 ATOMIC_STORE(&device
->LastError
, ALC_NO_ERROR
);
3114 if((err
=UpdateDeviceParams(device
, attrList
)) != ALC_NO_ERROR
)
3117 alcSetError(device
, err
);
3118 if(err
== ALC_INVALID_DEVICE
)
3120 V0(device
->Backend
,lock
)();
3121 aluHandleDisconnect(device
);
3122 V0(device
->Backend
,unlock
)();
3124 ALCdevice_DecRef(device
);
3128 ALContext
= al_calloc(16, sizeof(ALCcontext
)+sizeof(ALlistener
));
3131 InitRef(&ALContext
->ref
, 1);
3132 ALContext
->Listener
= (ALlistener
*)ALContext
->_listener_mem
;
3134 VECTOR_INIT(ALContext
->ActiveAuxSlots
);
3136 ALContext
->VoiceCount
= 0;
3137 ALContext
->MaxVoices
= 256;
3138 ALContext
->Voices
= al_calloc(16, ALContext
->MaxVoices
* sizeof(ALContext
->Voices
[0]));
3140 if(!ALContext
|| !ALContext
->Voices
)
3142 if(!ATOMIC_LOAD(&device
->ContextList
))
3144 V0(device
->Backend
,stop
)();
3145 device
->Flags
&= ~DEVICE_RUNNING
;
3151 al_free(ALContext
->Voices
);
3152 ALContext
->Voices
= NULL
;
3154 VECTOR_DEINIT(ALContext
->ActiveAuxSlots
);
3160 alcSetError(device
, ALC_OUT_OF_MEMORY
);
3161 ALCdevice_DecRef(device
);
3165 ALContext
->Device
= device
;
3166 ALCdevice_IncRef(device
);
3167 InitContext(ALContext
);
3170 ALCcontext
*head
= ATOMIC_LOAD(&device
->ContextList
);
3172 ALContext
->next
= head
;
3173 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext
*, &device
->ContextList
, &head
, ALContext
));
3177 ALCdevice_DecRef(device
);
3179 TRACE("Created context %p\n", ALContext
);
3183 /* alcDestroyContext
3185 * Remove a context from its device
3187 ALC_API ALCvoid ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
3192 /* alcGetContextsDevice sets an error for invalid contexts */
3193 Device
= alcGetContextsDevice(context
);
3196 ReleaseContext(context
, Device
);
3197 if(!ATOMIC_LOAD(&Device
->ContextList
))
3199 V0(Device
->Backend
,stop
)();
3200 Device
->Flags
&= ~DEVICE_RUNNING
;
3207 /* alcGetCurrentContext
3209 * Returns the currently active context on the calling thread
3211 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
3213 ALCcontext
*Context
= altss_get(LocalContext
);
3214 if(!Context
) Context
= ATOMIC_LOAD(&GlobalContext
);
3218 /* alcGetThreadContext
3220 * Returns the currently active thread-local context
3222 ALC_API ALCcontext
* ALC_APIENTRY
alcGetThreadContext(void)
3224 return altss_get(LocalContext
);
3228 /* alcMakeContextCurrent
3230 * Makes the given context the active process-wide context, and removes the
3231 * thread-local context for the calling thread.
3233 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
3235 /* context must be valid or NULL */
3236 if(context
&& !VerifyContext(&context
))
3238 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3241 /* context's reference count is already incremented */
3242 context
= ATOMIC_EXCHANGE(ALCcontext
*, &GlobalContext
, context
);
3243 if(context
) ALCcontext_DecRef(context
);
3245 if((context
=altss_get(LocalContext
)) != NULL
)
3247 altss_set(LocalContext
, NULL
);
3248 ALCcontext_DecRef(context
);
3254 /* alcSetThreadContext
3256 * Makes the given context the active context for the current thread
3258 ALC_API ALCboolean ALC_APIENTRY
alcSetThreadContext(ALCcontext
*context
)
3262 /* context must be valid or NULL */
3263 if(context
&& !VerifyContext(&context
))
3265 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3268 /* context's reference count is already incremented */
3269 old
= altss_get(LocalContext
);
3270 altss_set(LocalContext
, context
);
3271 if(old
) ALCcontext_DecRef(old
);
3277 /* alcGetContextsDevice
3279 * Returns the device that a particular context is attached to
3281 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*Context
)
3285 if(!VerifyContext(&Context
))
3287 alcSetError(NULL
, ALC_INVALID_CONTEXT
);
3290 Device
= Context
->Device
;
3291 ALCcontext_DecRef(Context
);
3299 * Opens the named device.
3301 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*deviceName
)
3309 if(!PlaybackBackend
.name
)
3311 alcSetError(NULL
, ALC_INVALID_VALUE
);
3315 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0
3317 /* Some old Windows apps hardcode these expecting OpenAL to use a
3318 * specific audio API, even when they're not enumerated. Creative's
3319 * router effectively ignores them too.
3321 || strcasecmp(deviceName
, "DirectSound3D") == 0 || strcasecmp(deviceName
, "DirectSound") == 0
3322 || strcasecmp(deviceName
, "MMSYSTEM") == 0
3327 device
= al_calloc(16, sizeof(ALCdevice
)+sizeof(ALeffectslot
));
3330 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3335 InitRef(&device
->ref
, 1);
3336 device
->Connected
= ALC_TRUE
;
3337 device
->Type
= Playback
;
3338 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3341 device
->Bs2b
= NULL
;
3342 device
->Uhj_Encoder
= NULL
;
3343 VECTOR_INIT(device
->Hrtf_List
);
3344 AL_STRING_INIT(device
->Hrtf_Name
);
3345 device
->Hrtf_Mode
= DisabledHrtf
;
3346 AL_STRING_INIT(device
->DeviceName
);
3347 device
->DryBuffer
= NULL
;
3349 ATOMIC_INIT(&device
->ContextList
, NULL
);
3351 device
->ClockBase
= 0;
3352 device
->SamplesDone
= 0;
3354 device
->MaxNoOfSources
= 256;
3355 device
->AuxiliaryEffectSlotMax
= 4;
3356 device
->NumAuxSends
= MAX_SENDS
;
3358 InitUIntMap(&device
->BufferMap
, ~0);
3359 InitUIntMap(&device
->EffectMap
, ~0);
3360 InitUIntMap(&device
->FilterMap
, ~0);
3363 device
->FmtChans
= DevFmtChannelsDefault
;
3364 device
->FmtType
= DevFmtTypeDefault
;
3365 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3366 device
->IsHeadphones
= AL_FALSE
;
3367 device
->NumUpdates
= 4;
3368 device
->UpdateSize
= 1024;
3370 if(!PlaybackBackend
.getFactory
)
3371 device
->Backend
= create_backend_wrapper(device
, &PlaybackBackend
.Funcs
,
3372 ALCbackend_Playback
);
3375 ALCbackendFactory
*factory
= PlaybackBackend
.getFactory();
3376 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Playback
);
3378 if(!device
->Backend
)
3381 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3386 if(ConfigValueStr(deviceName
, NULL
, "channels", &fmt
))
3388 static const struct {
3389 const char name
[16];
3390 enum DevFmtChannels chans
;
3392 { "mono", DevFmtMono
},
3393 { "stereo", DevFmtStereo
},
3394 { "quad", DevFmtQuad
},
3395 { "surround51", DevFmtX51
},
3396 { "surround61", DevFmtX61
},
3397 { "surround71", DevFmtX71
},
3398 { "surround51rear", DevFmtX51Rear
},
3402 for(i
= 0;i
< COUNTOF(chanlist
);i
++)
3404 if(strcasecmp(chanlist
[i
].name
, fmt
) == 0)
3406 device
->FmtChans
= chanlist
[i
].chans
;
3407 device
->Flags
|= DEVICE_CHANNELS_REQUEST
;
3411 if(i
== COUNTOF(chanlist
))
3412 ERR("Unsupported channels: %s\n", fmt
);
3414 if(ConfigValueStr(deviceName
, NULL
, "sample-type", &fmt
))
3416 static const struct {
3417 const char name
[16];
3418 enum DevFmtType type
;
3420 { "int8", DevFmtByte
},
3421 { "uint8", DevFmtUByte
},
3422 { "int16", DevFmtShort
},
3423 { "uint16", DevFmtUShort
},
3424 { "int32", DevFmtInt
},
3425 { "uint32", DevFmtUInt
},
3426 { "float32", DevFmtFloat
},
3430 for(i
= 0;i
< COUNTOF(typelist
);i
++)
3432 if(strcasecmp(typelist
[i
].name
, fmt
) == 0)
3434 device
->FmtType
= typelist
[i
].type
;
3435 device
->Flags
|= DEVICE_SAMPLE_TYPE_REQUEST
;
3439 if(i
== COUNTOF(typelist
))
3440 ERR("Unsupported sample-type: %s\n", fmt
);
3443 if(ConfigValueUInt(deviceName
, NULL
, "frequency", &device
->Frequency
))
3445 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3446 if(device
->Frequency
< MIN_OUTPUT_RATE
)
3447 ERR("%uhz request clamped to %uhz minimum\n", device
->Frequency
, MIN_OUTPUT_RATE
);
3448 device
->Frequency
= maxu(device
->Frequency
, MIN_OUTPUT_RATE
);
3451 ConfigValueUInt(deviceName
, NULL
, "periods", &device
->NumUpdates
);
3452 device
->NumUpdates
= clampu(device
->NumUpdates
, 2, 16);
3454 ConfigValueUInt(deviceName
, NULL
, "period_size", &device
->UpdateSize
);
3455 device
->UpdateSize
= clampu(device
->UpdateSize
, 64, 8192);
3456 if((CPUCapFlags
&(CPU_CAP_SSE
|CPU_CAP_NEON
)) != 0)
3457 device
->UpdateSize
= (device
->UpdateSize
+3)&~3;
3459 ConfigValueUInt(deviceName
, NULL
, "sources", &device
->MaxNoOfSources
);
3460 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3462 ConfigValueUInt(deviceName
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3463 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3465 ConfigValueUInt(deviceName
, NULL
, "sends", &device
->NumAuxSends
);
3466 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3468 device
->NumStereoSources
= 1;
3469 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3471 // Find a playback device to open
3472 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3474 DELETE_OBJ(device
->Backend
);
3476 alcSetError(NULL
, err
);
3480 if(DefaultEffect
.type
!= AL_EFFECT_NULL
)
3482 device
->DefaultSlot
= (ALeffectslot
*)device
->_slot_mem
;
3483 if(InitEffectSlot(device
->DefaultSlot
) != AL_NO_ERROR
)
3485 device
->DefaultSlot
= NULL
;
3486 ERR("Failed to initialize the default effect slot\n");
3488 else if(InitializeEffect(device
, device
->DefaultSlot
, &DefaultEffect
) != AL_NO_ERROR
)
3490 ALeffectState
*state
= device
->DefaultSlot
->EffectState
;
3491 device
->DefaultSlot
= NULL
;
3493 ERR("Failed to initialize the default effect\n");
3496 aluInitEffectPanning(device
->DefaultSlot
);
3500 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3502 device
->next
= head
;
3503 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3506 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3512 * Closes the given device.
3514 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
3516 ALCdevice
*list
, *origdev
, *nextdev
;
3520 list
= ATOMIC_LOAD(&DeviceList
);
3524 } while((list
=list
->next
) != NULL
);
3525 if(!list
|| list
->Type
== Capture
)
3527 alcSetError(list
, ALC_INVALID_DEVICE
);
3533 nextdev
= device
->next
;
3534 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &origdev
, nextdev
))
3539 } while(!COMPARE_EXCHANGE(&list
->next
, &origdev
, nextdev
));
3543 ctx
= ATOMIC_LOAD(&device
->ContextList
);
3546 ALCcontext
*next
= ctx
->next
;
3547 WARN("Releasing context %p\n", ctx
);
3548 ReleaseContext(ctx
, device
);
3551 if((device
->Flags
&DEVICE_RUNNING
))
3552 V0(device
->Backend
,stop
)();
3553 device
->Flags
&= ~DEVICE_RUNNING
;
3555 ALCdevice_DecRef(device
);
3561 /************************************************
3562 * ALC capture functions
3563 ************************************************/
3564 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei samples
)
3566 ALCdevice
*device
= NULL
;
3571 if(!CaptureBackend
.name
)
3573 alcSetError(NULL
, ALC_INVALID_VALUE
);
3579 alcSetError(NULL
, ALC_INVALID_VALUE
);
3583 if(deviceName
&& (!deviceName
[0] || strcasecmp(deviceName
, alcDefaultName
) == 0 || strcasecmp(deviceName
, "openal-soft") == 0))
3586 device
= al_calloc(16, sizeof(ALCdevice
));
3589 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3594 InitRef(&device
->ref
, 1);
3595 device
->Connected
= ALC_TRUE
;
3596 device
->Type
= Capture
;
3598 VECTOR_INIT(device
->Hrtf_List
);
3599 AL_STRING_INIT(device
->Hrtf_Name
);
3601 AL_STRING_INIT(device
->DeviceName
);
3602 device
->DryBuffer
= NULL
;
3604 InitUIntMap(&device
->BufferMap
, ~0);
3605 InitUIntMap(&device
->EffectMap
, ~0);
3606 InitUIntMap(&device
->FilterMap
, ~0);
3608 if(!CaptureBackend
.getFactory
)
3609 device
->Backend
= create_backend_wrapper(device
, &CaptureBackend
.Funcs
,
3610 ALCbackend_Capture
);
3613 ALCbackendFactory
*factory
= CaptureBackend
.getFactory();
3614 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Capture
);
3616 if(!device
->Backend
)
3619 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3623 device
->Flags
|= DEVICE_FREQUENCY_REQUEST
;
3624 device
->Frequency
= frequency
;
3626 device
->Flags
|= DEVICE_CHANNELS_REQUEST
| DEVICE_SAMPLE_TYPE_REQUEST
;
3627 if(DecomposeDevFormat(format
, &device
->FmtChans
, &device
->FmtType
) == AL_FALSE
)
3630 alcSetError(NULL
, ALC_INVALID_ENUM
);
3633 device
->IsHeadphones
= AL_FALSE
;
3635 device
->UpdateSize
= samples
;
3636 device
->NumUpdates
= 1;
3638 if((err
=V(device
->Backend
,open
)(deviceName
)) != ALC_NO_ERROR
)
3641 alcSetError(NULL
, err
);
3646 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3648 device
->next
= head
;
3649 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3652 TRACE("Created device %p, \"%s\"\n", device
, al_string_get_cstr(device
->DeviceName
));
3656 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
3658 ALCdevice
*list
, *next
, *nextdev
;
3661 list
= ATOMIC_LOAD(&DeviceList
);
3665 } while((list
=list
->next
) != NULL
);
3666 if(!list
|| list
->Type
!= Capture
)
3668 alcSetError(list
, ALC_INVALID_DEVICE
);
3674 nextdev
= device
->next
;
3675 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice
*, &DeviceList
, &next
, nextdev
))
3680 } while(!COMPARE_EXCHANGE(&list
->next
, &next
, nextdev
));
3684 ALCdevice_DecRef(device
);
3689 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
3691 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3692 alcSetError(device
, ALC_INVALID_DEVICE
);
3695 V0(device
->Backend
,lock
)();
3696 if(!device
->Connected
)
3697 alcSetError(device
, ALC_INVALID_DEVICE
);
3698 else if(!(device
->Flags
&DEVICE_RUNNING
))
3700 if(V0(device
->Backend
,start
)())
3701 device
->Flags
|= DEVICE_RUNNING
;
3704 aluHandleDisconnect(device
);
3705 alcSetError(device
, ALC_INVALID_DEVICE
);
3708 V0(device
->Backend
,unlock
)();
3711 if(device
) ALCdevice_DecRef(device
);
3714 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
3716 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3717 alcSetError(device
, ALC_INVALID_DEVICE
);
3720 V0(device
->Backend
,lock
)();
3721 if((device
->Flags
&DEVICE_RUNNING
))
3722 V0(device
->Backend
,stop
)();
3723 device
->Flags
&= ~DEVICE_RUNNING
;
3724 V0(device
->Backend
,unlock
)();
3727 if(device
) ALCdevice_DecRef(device
);
3730 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3732 if(!VerifyDevice(&device
) || device
->Type
!= Capture
)
3733 alcSetError(device
, ALC_INVALID_DEVICE
);
3736 ALCenum err
= ALC_INVALID_VALUE
;
3738 V0(device
->Backend
,lock
)();
3739 if(samples
>= 0 && V0(device
->Backend
,availableSamples
)() >= (ALCuint
)samples
)
3740 err
= V(device
->Backend
,captureSamples
)(buffer
, samples
);
3741 V0(device
->Backend
,unlock
)();
3743 if(err
!= ALC_NO_ERROR
)
3744 alcSetError(device
, err
);
3746 if(device
) ALCdevice_DecRef(device
);
3750 /************************************************
3751 * ALC loopback functions
3752 ************************************************/
3754 /* alcLoopbackOpenDeviceSOFT
3756 * Open a loopback device, for manual rendering.
3758 ALC_API ALCdevice
* ALC_APIENTRY
alcLoopbackOpenDeviceSOFT(const ALCchar
*deviceName
)
3760 ALCbackendFactory
*factory
;
3765 /* Make sure the device name, if specified, is us. */
3766 if(deviceName
&& strcmp(deviceName
, alcDefaultName
) != 0)
3768 alcSetError(NULL
, ALC_INVALID_VALUE
);
3772 device
= al_calloc(16, sizeof(ALCdevice
));
3775 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3780 InitRef(&device
->ref
, 1);
3781 device
->Connected
= ALC_TRUE
;
3782 device
->Type
= Loopback
;
3783 ATOMIC_INIT(&device
->LastError
, ALC_NO_ERROR
);
3786 VECTOR_INIT(device
->Hrtf_List
);
3787 AL_STRING_INIT(device
->Hrtf_Name
);
3788 device
->Bs2b
= NULL
;
3789 device
->Uhj_Encoder
= NULL
;
3790 device
->Hrtf_Mode
= DisabledHrtf
;
3791 AL_STRING_INIT(device
->DeviceName
);
3792 device
->DryBuffer
= NULL
;
3794 ATOMIC_INIT(&device
->ContextList
, NULL
);
3796 device
->ClockBase
= 0;
3797 device
->SamplesDone
= 0;
3799 device
->MaxNoOfSources
= 256;
3800 device
->AuxiliaryEffectSlotMax
= 4;
3801 device
->NumAuxSends
= MAX_SENDS
;
3803 InitUIntMap(&device
->BufferMap
, ~0);
3804 InitUIntMap(&device
->EffectMap
, ~0);
3805 InitUIntMap(&device
->FilterMap
, ~0);
3807 factory
= ALCloopbackFactory_getFactory();
3808 device
->Backend
= V(factory
,createBackend
)(device
, ALCbackend_Loopback
);
3809 if(!device
->Backend
)
3812 alcSetError(NULL
, ALC_OUT_OF_MEMORY
);
3817 device
->NumUpdates
= 0;
3818 device
->UpdateSize
= 0;
3820 device
->Frequency
= DEFAULT_OUTPUT_RATE
;
3821 device
->FmtChans
= DevFmtChannelsDefault
;
3822 device
->FmtType
= DevFmtTypeDefault
;
3823 device
->IsHeadphones
= AL_FALSE
;
3825 ConfigValueUInt(NULL
, NULL
, "sources", &device
->MaxNoOfSources
);
3826 if(device
->MaxNoOfSources
== 0) device
->MaxNoOfSources
= 256;
3828 ConfigValueUInt(NULL
, NULL
, "slots", &device
->AuxiliaryEffectSlotMax
);
3829 if(device
->AuxiliaryEffectSlotMax
== 0) device
->AuxiliaryEffectSlotMax
= 4;
3831 ConfigValueUInt(NULL
, NULL
, "sends", &device
->NumAuxSends
);
3832 if(device
->NumAuxSends
> MAX_SENDS
) device
->NumAuxSends
= MAX_SENDS
;
3834 device
->NumStereoSources
= 1;
3835 device
->NumMonoSources
= device
->MaxNoOfSources
- device
->NumStereoSources
;
3837 // Open the "backend"
3838 V(device
->Backend
,open
)("Loopback");
3841 ALCdevice
*head
= ATOMIC_LOAD(&DeviceList
);
3843 device
->next
= head
;
3844 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice
*, &DeviceList
, &head
, device
));
3847 TRACE("Created device %p\n", device
);
3851 /* alcIsRenderFormatSupportedSOFT
3853 * Determines if the loopback device supports the given format for rendering.
3855 ALC_API ALCboolean ALC_APIENTRY
alcIsRenderFormatSupportedSOFT(ALCdevice
*device
, ALCsizei freq
, ALCenum channels
, ALCenum type
)
3857 ALCboolean ret
= ALC_FALSE
;
3859 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3860 alcSetError(device
, ALC_INVALID_DEVICE
);
3862 alcSetError(device
, ALC_INVALID_VALUE
);
3865 if(IsValidALCType(type
) && BytesFromDevFmt(type
) > 0 &&
3866 IsValidALCChannels(channels
) && ChannelsFromDevFmt(channels
) > 0 &&
3867 freq
>= MIN_OUTPUT_RATE
)
3870 if(device
) ALCdevice_DecRef(device
);
3875 /* alcRenderSamplesSOFT
3877 * Renders some samples into a buffer, using the format last set by the
3878 * attributes given to alcCreateContext.
3880 FORCE_ALIGN ALC_API
void ALC_APIENTRY
alcRenderSamplesSOFT(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
3882 if(!VerifyDevice(&device
) || device
->Type
!= Loopback
)
3883 alcSetError(device
, ALC_INVALID_DEVICE
);
3884 else if(samples
< 0 || (samples
> 0 && buffer
== NULL
))
3885 alcSetError(device
, ALC_INVALID_VALUE
);
3887 aluMixData(device
, buffer
, samples
);
3888 if(device
) ALCdevice_DecRef(device
);
3892 /************************************************
3893 * ALC DSP pause/resume functions
3894 ************************************************/
3896 /* alcDevicePauseSOFT
3898 * Pause the DSP to stop audio processing.
3900 ALC_API
void ALC_APIENTRY
alcDevicePauseSOFT(ALCdevice
*device
)
3902 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3903 alcSetError(device
, ALC_INVALID_DEVICE
);
3907 if((device
->Flags
&DEVICE_RUNNING
))
3908 V0(device
->Backend
,stop
)();
3909 device
->Flags
&= ~DEVICE_RUNNING
;
3910 device
->Flags
|= DEVICE_PAUSED
;
3913 if(device
) ALCdevice_DecRef(device
);
3916 /* alcDeviceResumeSOFT
3918 * Resume the DSP to restart audio processing.
3920 ALC_API
void ALC_APIENTRY
alcDeviceResumeSOFT(ALCdevice
*device
)
3922 if(!VerifyDevice(&device
) || device
->Type
!= Playback
)
3923 alcSetError(device
, ALC_INVALID_DEVICE
);
3927 if((device
->Flags
&DEVICE_PAUSED
))
3929 device
->Flags
&= ~DEVICE_PAUSED
;
3930 if(ATOMIC_LOAD(&device
->ContextList
) != NULL
)
3932 if(V0(device
->Backend
,start
)() != ALC_FALSE
)
3933 device
->Flags
|= DEVICE_RUNNING
;
3936 alcSetError(device
, ALC_INVALID_DEVICE
);
3937 V0(device
->Backend
,lock
)();
3938 aluHandleDisconnect(device
);
3939 V0(device
->Backend
,unlock
)();
3945 if(device
) ALCdevice_DecRef(device
);
3949 /************************************************
3950 * ALC HRTF functions
3951 ************************************************/
3953 /* alcGetStringiSOFT
3955 * Gets a string parameter at the given index.
3957 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetStringiSOFT(ALCdevice
*device
, ALCenum paramName
, ALCsizei index
)
3959 const ALCchar
*str
= NULL
;
3961 if(!VerifyDevice(&device
) || device
->Type
== Capture
)
3962 alcSetError(device
, ALC_INVALID_DEVICE
);
3963 else switch(paramName
)
3965 case ALC_HRTF_SPECIFIER_SOFT
:
3966 if(index
>= 0 && (size_t)index
< VECTOR_SIZE(device
->Hrtf_List
))
3967 str
= al_string_get_cstr(VECTOR_ELEM(device
->Hrtf_List
, index
).name
);
3969 alcSetError(device
, ALC_INVALID_VALUE
);
3973 alcSetError(device
, ALC_INVALID_ENUM
);
3976 if(device
) ALCdevice_DecRef(device
);
3981 /* alcResetDeviceSOFT
3983 * Resets the given device output, using the specified attribute list.
3985 ALC_API ALCboolean ALC_APIENTRY
alcResetDeviceSOFT(ALCdevice
*device
, const ALCint
*attribs
)
3990 if(!VerifyDevice(&device
) || device
->Type
== Capture
|| !device
->Connected
)
3993 alcSetError(device
, ALC_INVALID_DEVICE
);
3994 if(device
) ALCdevice_DecRef(device
);
3998 if((err
=UpdateDeviceParams(device
, attribs
)) != ALC_NO_ERROR
)
4001 alcSetError(device
, err
);
4002 if(err
== ALC_INVALID_DEVICE
)
4004 V0(device
->Backend
,lock
)();
4005 aluHandleDisconnect(device
);
4006 V0(device
->Backend
,unlock
)();
4008 ALCdevice_DecRef(device
);
4012 ALCdevice_DecRef(device
);