Keep track of the real output's channel names
[openal-soft.git] / Alc / ALc.c
blob6074df4a86ae4406c691b1fb21cde907412fac69
1 /**
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
21 #include "config.h"
23 #include <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include <ctype.h>
28 #include <signal.h>
30 #include "alMain.h"
31 #include "alSource.h"
32 #include "alListener.h"
33 #include "alThunk.h"
34 #include "alSource.h"
35 #include "alBuffer.h"
36 #include "alAuxEffectSlot.h"
37 #include "alError.h"
38 #include "bs2b.h"
39 #include "uhjfilter.h"
40 #include "alu.h"
42 #include "compat.h"
43 #include "threads.h"
44 #include "alstring.h"
46 #include "backends/base.h"
49 /************************************************
50 * Backends
51 ************************************************/
52 struct BackendInfo {
53 const char *name;
54 ALCbackendFactory* (*getFactory)(void);
55 ALCboolean (*Init)(BackendFuncs*);
56 void (*Deinit)(void);
57 void (*Probe)(enum DevProbe);
58 BackendFuncs Funcs;
61 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
62 static struct BackendInfo BackendList[] = {
63 #ifdef HAVE_JACK
64 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
65 #endif
66 #ifdef HAVE_PULSEAUDIO
67 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
68 #endif
69 #ifdef HAVE_ALSA
70 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
71 #endif
72 #ifdef HAVE_COREAUDIO
73 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
74 #endif
75 #ifdef HAVE_OSS
76 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
77 #endif
78 #ifdef HAVE_SOLARIS
79 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
80 #endif
81 #ifdef HAVE_SNDIO
82 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
83 #endif
84 #ifdef HAVE_QSA
85 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
86 #endif
87 #ifdef HAVE_MMDEVAPI
88 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
89 #endif
90 #ifdef HAVE_DSOUND
91 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
92 #endif
93 #ifdef HAVE_WINMM
94 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
95 #endif
96 #ifdef HAVE_PORTAUDIO
97 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
98 #endif
99 #ifdef HAVE_OPENSL
100 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
101 #endif
103 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
104 #ifdef HAVE_WAVE
105 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
106 #endif
108 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
110 #undef 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;
121 ALCvoid *address;
122 } ALCfunction;
124 typedef struct ALCenums {
125 const ALCchar *enumName;
126 ALCenum value;
127 } ALCenums;
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),
138 DECL(alcOpenDevice),
139 DECL(alcCloseDevice),
140 DECL(alcGetError),
141 DECL(alcIsExtensionPresent),
142 DECL(alcGetProcAddress),
143 DECL(alcGetEnumValue),
144 DECL(alcGetString),
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),
167 DECL(alEnable),
168 DECL(alDisable),
169 DECL(alIsEnabled),
170 DECL(alGetString),
171 DECL(alGetBooleanv),
172 DECL(alGetIntegerv),
173 DECL(alGetFloatv),
174 DECL(alGetDoublev),
175 DECL(alGetBoolean),
176 DECL(alGetInteger),
177 DECL(alGetFloat),
178 DECL(alGetDouble),
179 DECL(alGetError),
180 DECL(alIsExtensionPresent),
181 DECL(alGetProcAddress),
182 DECL(alGetEnumValue),
183 DECL(alListenerf),
184 DECL(alListener3f),
185 DECL(alListenerfv),
186 DECL(alListeneri),
187 DECL(alListener3i),
188 DECL(alListeneriv),
189 DECL(alGetListenerf),
190 DECL(alGetListener3f),
191 DECL(alGetListenerfv),
192 DECL(alGetListeneri),
193 DECL(alGetListener3i),
194 DECL(alGetListeneriv),
195 DECL(alGenSources),
196 DECL(alDeleteSources),
197 DECL(alIsSource),
198 DECL(alSourcef),
199 DECL(alSource3f),
200 DECL(alSourcefv),
201 DECL(alSourcei),
202 DECL(alSource3i),
203 DECL(alSourceiv),
204 DECL(alGetSourcef),
205 DECL(alGetSource3f),
206 DECL(alGetSourcefv),
207 DECL(alGetSourcei),
208 DECL(alGetSource3i),
209 DECL(alGetSourceiv),
210 DECL(alSourcePlayv),
211 DECL(alSourceStopv),
212 DECL(alSourceRewindv),
213 DECL(alSourcePausev),
214 DECL(alSourcePlay),
215 DECL(alSourceStop),
216 DECL(alSourceRewind),
217 DECL(alSourcePause),
218 DECL(alSourceQueueBuffers),
219 DECL(alSourceUnqueueBuffers),
220 DECL(alGenBuffers),
221 DECL(alDeleteBuffers),
222 DECL(alIsBuffer),
223 DECL(alBufferData),
224 DECL(alBufferf),
225 DECL(alBuffer3f),
226 DECL(alBufferfv),
227 DECL(alBufferi),
228 DECL(alBuffer3i),
229 DECL(alBufferiv),
230 DECL(alGetBufferf),
231 DECL(alGetBuffer3f),
232 DECL(alGetBufferfv),
233 DECL(alGetBufferi),
234 DECL(alGetBuffer3i),
235 DECL(alGetBufferiv),
236 DECL(alDopplerFactor),
237 DECL(alDopplerVelocity),
238 DECL(alSpeedOfSound),
239 DECL(alDistanceModel),
241 DECL(alGenFilters),
242 DECL(alDeleteFilters),
243 DECL(alIsFilter),
244 DECL(alFilteri),
245 DECL(alFilteriv),
246 DECL(alFilterf),
247 DECL(alFilterfv),
248 DECL(alGetFilteri),
249 DECL(alGetFilteriv),
250 DECL(alGetFilterf),
251 DECL(alGetFilterfv),
252 DECL(alGenEffects),
253 DECL(alDeleteEffects),
254 DECL(alIsEffect),
255 DECL(alEffecti),
256 DECL(alEffectiv),
257 DECL(alEffectf),
258 DECL(alEffectfv),
259 DECL(alGetEffecti),
260 DECL(alGetEffectiv),
261 DECL(alGetEffectf),
262 DECL(alGetEffectfv),
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),
285 DECL(alSourcedSOFT),
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),
298 { NULL, NULL }
300 #undef DECL
302 #define DECL(x) { #x, (x) }
303 static const ALCenums enumeration[] = {
304 DECL(ALC_INVALID),
305 DECL(ALC_FALSE),
306 DECL(ALC_TRUE),
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),
317 DECL(ALC_FREQUENCY),
318 DECL(ALC_REFRESH),
319 DECL(ALC_SYNC),
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),
325 DECL(ALC_CONNECTED),
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),
334 DECL(ALC_MONO_SOFT),
335 DECL(ALC_STEREO_SOFT),
336 DECL(ALC_QUAD_SOFT),
337 DECL(ALC_5POINT1_SOFT),
338 DECL(ALC_6POINT1_SOFT),
339 DECL(ALC_7POINT1_SOFT),
341 DECL(ALC_BYTE_SOFT),
342 DECL(ALC_UNSIGNED_BYTE_SOFT),
343 DECL(ALC_SHORT_SOFT),
344 DECL(ALC_UNSIGNED_SHORT_SOFT),
345 DECL(ALC_INT_SOFT),
346 DECL(ALC_UNSIGNED_INT_SOFT),
347 DECL(ALC_FLOAT_SOFT),
349 DECL(ALC_HRTF_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),
362 DECL(ALC_NO_ERROR),
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),
370 DECL(AL_INVALID),
371 DECL(AL_NONE),
372 DECL(AL_FALSE),
373 DECL(AL_TRUE),
375 DECL(AL_SOURCE_RELATIVE),
376 DECL(AL_CONE_INNER_ANGLE),
377 DECL(AL_CONE_OUTER_ANGLE),
378 DECL(AL_PITCH),
379 DECL(AL_POSITION),
380 DECL(AL_DIRECTION),
381 DECL(AL_VELOCITY),
382 DECL(AL_LOOPING),
383 DECL(AL_BUFFER),
384 DECL(AL_GAIN),
385 DECL(AL_MIN_GAIN),
386 DECL(AL_MAX_GAIN),
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),
392 DECL(AL_SEC_OFFSET),
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),
398 DECL(AL_STATIC),
399 DECL(AL_STREAMING),
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),
415 DECL(AL_INITIAL),
416 DECL(AL_PLAYING),
417 DECL(AL_PAUSED),
418 DECL(AL_STOPPED),
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),
464 DECL(AL_MONO8_SOFT),
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),
470 DECL(AL_QUAD8_SOFT),
471 DECL(AL_QUAD16_SOFT),
472 DECL(AL_QUAD32F_SOFT),
473 DECL(AL_REAR8_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),
494 DECL(AL_MONO_SOFT),
495 DECL(AL_STEREO_SOFT),
496 DECL(AL_QUAD_SOFT),
497 DECL(AL_REAR_SOFT),
498 DECL(AL_5POINT1_SOFT),
499 DECL(AL_6POINT1_SOFT),
500 DECL(AL_7POINT1_SOFT),
502 DECL(AL_BYTE_SOFT),
503 DECL(AL_UNSIGNED_BYTE_SOFT),
504 DECL(AL_SHORT_SOFT),
505 DECL(AL_UNSIGNED_SHORT_SOFT),
506 DECL(AL_INT_SOFT),
507 DECL(AL_UNSIGNED_INT_SOFT),
508 DECL(AL_FLOAT_SOFT),
509 DECL(AL_DOUBLE_SOFT),
510 DECL(AL_BYTE3_SOFT),
511 DECL(AL_UNSIGNED_BYTE3_SOFT),
513 DECL(AL_FREQUENCY),
514 DECL(AL_BITS),
515 DECL(AL_CHANNELS),
516 DECL(AL_SIZE),
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),
524 DECL(AL_UNUSED),
525 DECL(AL_PENDING),
526 DECL(AL_PROCESSED),
528 DECL(AL_NO_ERROR),
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),
535 DECL(AL_VENDOR),
536 DECL(AL_VERSION),
537 DECL(AL_RENDERER),
538 DECL(AL_EXTENSIONS),
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),
578 #if 0
579 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
580 DECL(AL_EFFECT_VOCAL_MORPHER),
581 DECL(AL_EFFECT_PITCH_SHIFTER),
582 #endif
583 DECL(AL_EFFECT_RING_MODULATOR),
584 #if 0
585 DECL(AL_EFFECT_AUTOWAH),
586 #endif
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),
643 DECL(AL_ECHO_DELAY),
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),
660 #if 0
661 DECL(AL_AUTOWAH_ATTACK_TIME),
662 DECL(AL_AUTOWAH_PEAK_GAIN),
663 DECL(AL_AUTOWAH_RELEASE_TIME),
664 DECL(AL_AUTOWAH_RESONANCE),
665 #endif
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),
682 { NULL, (ALCenum)0 }
684 #undef DECL
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 /************************************************
695 * Global variables
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 */
726 ALint RTPrioLevel;
728 FILE *LogFile;
729 #ifdef _DEBUG
730 enum LogLevel LogLevel = LogWarning;
731 #else
732 enum LogLevel LogLevel = LogError;
733 #endif
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
745 * updates.
747 static ALCboolean SuspendDefers = ALC_TRUE;
750 /************************************************
751 * ALC information
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 /************************************************
769 * Device lists
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 ************************************************/
788 #if defined(_WIN32)
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)
796 switch(reason)
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);
802 alc_init();
803 break;
805 case DLL_THREAD_DETACH:
806 break;
808 case DLL_PROCESS_DETACH:
809 if(!lpReserved)
810 alc_deinit();
811 else
812 alc_deinit_safe();
813 break;
815 return TRUE;
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);
826 alc_init();
829 static void alc_destructor(void)
831 alc_deinit();
833 #elif defined(HAVE_GCC_DESTRUCTOR)
834 static void alc_init(void) __attribute__((constructor));
835 static void alc_deinit(void) __attribute__((destructor));
836 #else
837 #error "No static initialization available on this platform!"
838 #endif
840 #elif defined(HAVE_GCC_DESTRUCTOR)
842 static void alc_init(void) __attribute__((constructor));
843 static void alc_deinit(void) __attribute__((destructor));
845 #else
846 #error "No global initialization available on this platform!"
847 #endif
849 static void ReleaseThreadCtx(void *ptr);
850 static void alc_init(void)
852 const char *str;
853 int ret;
855 LogFile = stderr;
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))
862 ConeScale *= 0.5f;
864 str = getenv("__ALSOFT_REVERSE_Z");
865 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
866 ZScale *= -1.0f;
868 ret = altss_create(&LocalContext, ReleaseThreadCtx);
869 assert(ret == althrd_success);
871 ret = almtx_init(&ListLock, almtx_recursive);
872 assert(ret == althrd_success);
874 ThunkInit();
877 static void alc_initconfig(void)
879 const char *devs, *str;
880 ALuint capfilter;
881 float valf;
882 int i, n;
884 str = getenv("ALSOFT_LOGLEVEL");
885 if(str)
887 long lvl = strtol(str, NULL, 0);
888 if(lvl >= NoLog && lvl <= LogRef)
889 LogLevel = lvl;
892 str = getenv("ALSOFT_LOGFILE");
893 if(str && str[0])
895 FILE *logfile = al_fopen(str, "wt");
896 if(logfile) LogFile = logfile;
897 else ERR("Failed to open log file '%s'\n", str);
901 char buf[1024] = "";
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);
907 ReadALConfig();
909 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
910 if(str && *str)
912 if(strcasecmp(str, "ignore") == 0)
914 SuspendDefers = ALC_FALSE;
915 TRACE("Selected context suspend behavior, \"ignore\"\n");
917 else
918 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
921 capfilter = 0;
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;
930 #endif
931 #ifdef HAVE_NEON
932 capfilter |= CPU_CAP_NEON;
933 #endif
934 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
936 if(strcasecmp(str, "all") == 0)
937 capfilter = 0;
938 else
940 size_t len;
941 const char *next = str;
943 do {
944 str = next;
945 while(isspace(str[0]))
946 str++;
947 next = strchr(str, ',');
949 if(!str[0] || str[0] == ',')
950 continue;
952 len = (next ? ((size_t)(next-str)) : strlen(str));
953 while(len > 0 && isspace(str[len-1]))
954 len--;
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;
965 else
966 WARN("Invalid CPU extension \"%s\"\n", str);
967 } while(next++);
970 FillCPUCaps(capfilter);
972 #ifdef _WIN32
973 RTPrioLevel = 1;
974 #else
975 RTPrioLevel = 0;
976 #endif
977 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
979 aluInitMixer();
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;
987 else
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))
1008 int n;
1009 size_t len;
1010 const char *next = devs;
1011 int endlist, delitem;
1013 i = 0;
1014 do {
1015 devs = next;
1016 while(isspace(devs[0]))
1017 devs++;
1018 next = strchr(devs, ',');
1020 delitem = (devs[0] == '-');
1021 if(devs[0] == '-') devs++;
1023 if(!devs[0] || devs[0] == ',')
1025 endlist = 0;
1026 continue;
1028 endlist = 1;
1030 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1031 while(len > 0 && isspace(devs[len-1]))
1032 len--;
1033 for(n = i;BackendList[n].name;n++)
1035 if(len == strlen(BackendList[n].name) &&
1036 strncmp(BackendList[n].name, devs, len) == 0)
1038 if(delitem)
1040 do {
1041 BackendList[n] = BackendList[n+1];
1042 ++n;
1043 } while(BackendList[n].name);
1045 else
1047 struct BackendInfo Bkp = BackendList[n];
1048 while(n > i)
1050 BackendList[n] = BackendList[n-1];
1051 --n;
1053 BackendList[n] = Bkp;
1055 i++;
1057 break;
1060 } while(next++);
1062 if(endlist)
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);
1080 continue;
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);
1095 continue;
1098 if(!BackendList[i].Init(&BackendList[i].Funcs))
1100 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1101 continue;
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();
1118 V0(factory,init)();
1121 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1123 size_t len;
1124 const char *next = str;
1126 do {
1127 str = next;
1128 next = strchr(str, ',');
1130 if(!str[0] || next == str)
1131 continue;
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;
1140 } while(next++);
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)
1158 ALCdevice *dev;
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)
1170 ALCuint num = 0;
1171 do {
1172 num++;
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)
1182 alc_cleanup();
1184 FreeHrtfs();
1185 FreeALConfig();
1187 ThunkExit();
1188 almtx_destroy(&ListLock);
1189 altss_delete(LocalContext);
1191 if(LogFile != stderr)
1192 fclose(LogFile);
1193 LogFile = NULL;
1196 static void alc_deinit(void)
1198 int i;
1200 alc_cleanup();
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();
1209 else
1211 ALCbackendFactory *factory = BackendList[i].getFactory();
1212 V0(factory,deinit)();
1216 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1217 V0(factory,deinit)();
1220 alc_deinit_safe();
1224 /************************************************
1225 * Device enumeration
1226 ************************************************/
1227 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1229 DO_INITCONFIG();
1231 LockLists();
1232 al_string_clear(list);
1234 if(!backendinfo->getFactory)
1235 backendinfo->Probe(type);
1236 else
1238 ALCbackendFactory *factory = backendinfo->getFactory();
1239 V(factory,probe)(type);
1242 UnlockLists();
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);
1252 if(len > 0)
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)
1266 switch(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)
1280 switch(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)
1297 switch(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);
1307 return 0;
1309 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1311 switch(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;
1322 return 0;
1325 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1326 enum DevFmtChannels *chans, enum DevFmtType *type)
1328 static const struct {
1329 ALenum format;
1330 enum DevFmtChannels channels;
1331 enum DevFmtType type;
1332 } list[] = {
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 },
1357 ALuint i;
1359 for(i = 0;i < COUNTOF(list);i++)
1361 if(list[i].format == format)
1363 *chans = list[i].channels;
1364 *type = list[i].type;
1365 return AL_TRUE;
1369 return AL_FALSE;
1372 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1374 switch(type)
1376 case ALC_BYTE_SOFT:
1377 case ALC_UNSIGNED_BYTE_SOFT:
1378 case ALC_SHORT_SOFT:
1379 case ALC_UNSIGNED_SHORT_SOFT:
1380 case ALC_INT_SOFT:
1381 case ALC_UNSIGNED_INT_SOFT:
1382 case ALC_FLOAT_SOFT:
1383 return ALC_TRUE;
1385 return ALC_FALSE;
1388 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1390 switch(channels)
1392 case ALC_MONO_SOFT:
1393 case ALC_STEREO_SOFT:
1394 case ALC_QUAD_SOFT:
1395 case ALC_5POINT1_SOFT:
1396 case ALC_6POINT1_SOFT:
1397 case ALC_7POINT1_SOFT:
1398 return ALC_TRUE;
1400 return ALC_FALSE;
1404 /************************************************
1405 * Miscellaneous ALC helpers
1406 ************************************************/
1407 enum HrtfRequestMode {
1408 Hrtf_Default = 0,
1409 Hrtf_Enable = 1,
1410 Hrtf_Disable = 2,
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)
1433 ALuint i;
1435 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1436 device->RealOut.ChannelName[i] = InvalidChannel;
1438 switch(device->FmtChans)
1440 case DevFmtMono:
1441 device->RealOut.ChannelName[0] = FrontCenter;
1442 break;
1443 case DevFmtStereo:
1444 device->RealOut.ChannelName[0] = FrontLeft;
1445 device->RealOut.ChannelName[1] = FrontRight;
1446 break;
1447 case DevFmtQuad:
1448 device->RealOut.ChannelName[0] = FrontLeft;
1449 device->RealOut.ChannelName[1] = FrontRight;
1450 device->RealOut.ChannelName[2] = BackLeft;
1451 device->RealOut.ChannelName[3] = BackRight;
1452 break;
1453 case DevFmtX51:
1454 device->RealOut.ChannelName[0] = FrontLeft;
1455 device->RealOut.ChannelName[1] = FrontRight;
1456 device->RealOut.ChannelName[2] = FrontCenter;
1457 device->RealOut.ChannelName[3] = LFE;
1458 device->RealOut.ChannelName[4] = SideLeft;
1459 device->RealOut.ChannelName[5] = SideRight;
1460 break;
1461 case DevFmtX51Rear:
1462 device->RealOut.ChannelName[0] = FrontLeft;
1463 device->RealOut.ChannelName[1] = FrontRight;
1464 device->RealOut.ChannelName[2] = FrontCenter;
1465 device->RealOut.ChannelName[3] = LFE;
1466 device->RealOut.ChannelName[4] = BackLeft;
1467 device->RealOut.ChannelName[5] = BackRight;
1468 break;
1469 case DevFmtX61:
1470 device->RealOut.ChannelName[0] = FrontLeft;
1471 device->RealOut.ChannelName[1] = FrontRight;
1472 device->RealOut.ChannelName[2] = FrontCenter;
1473 device->RealOut.ChannelName[3] = LFE;
1474 device->RealOut.ChannelName[4] = BackCenter;
1475 device->RealOut.ChannelName[5] = SideLeft;
1476 device->RealOut.ChannelName[6] = SideRight;
1477 break;
1478 case DevFmtX71:
1479 device->RealOut.ChannelName[0] = FrontLeft;
1480 device->RealOut.ChannelName[1] = FrontRight;
1481 device->RealOut.ChannelName[2] = FrontCenter;
1482 device->RealOut.ChannelName[3] = LFE;
1483 device->RealOut.ChannelName[4] = BackLeft;
1484 device->RealOut.ChannelName[5] = BackRight;
1485 device->RealOut.ChannelName[6] = SideLeft;
1486 device->RealOut.ChannelName[7] = SideRight;
1487 break;
1488 case DevFmtBFormat3D:
1489 device->RealOut.ChannelName[0] = BFormatW;
1490 device->RealOut.ChannelName[1] = BFormatX;
1491 device->RealOut.ChannelName[2] = BFormatY;
1492 device->RealOut.ChannelName[3] = BFormatZ;
1493 break;
1497 /* SetDefaultChannelOrder
1499 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1501 void SetDefaultChannelOrder(ALCdevice *device)
1503 ALuint i;
1505 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1506 device->RealOut.ChannelName[i] = InvalidChannel;
1508 switch(device->FmtChans)
1510 case DevFmtX51Rear:
1511 device->RealOut.ChannelName[0] = FrontLeft;
1512 device->RealOut.ChannelName[1] = FrontRight;
1513 device->RealOut.ChannelName[2] = BackLeft;
1514 device->RealOut.ChannelName[3] = BackRight;
1515 device->RealOut.ChannelName[4] = FrontCenter;
1516 device->RealOut.ChannelName[5] = LFE;
1517 return;
1518 case DevFmtX71:
1519 device->RealOut.ChannelName[0] = FrontLeft;
1520 device->RealOut.ChannelName[1] = FrontRight;
1521 device->RealOut.ChannelName[2] = BackLeft;
1522 device->RealOut.ChannelName[3] = BackRight;
1523 device->RealOut.ChannelName[4] = FrontCenter;
1524 device->RealOut.ChannelName[5] = LFE;
1525 device->RealOut.ChannelName[6] = SideLeft;
1526 device->RealOut.ChannelName[7] = SideRight;
1527 return;
1529 /* Same as WFX order */
1530 case DevFmtMono:
1531 case DevFmtStereo:
1532 case DevFmtQuad:
1533 case DevFmtX51:
1534 case DevFmtX61:
1535 case DevFmtBFormat3D:
1536 SetDefaultWFXChannelOrder(device);
1537 break;
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
1548 * taking effect.
1550 void ALCcontext_DeferUpdates(ALCcontext *context)
1552 ALCdevice *device = context->Device;
1553 FPUCtl oldMode;
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); \
1567 } while(0)
1568 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1569 #undef 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)
1587 ALsizei pos;
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;
1595 ALenum new_state;
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;
1607 if(new_state)
1608 SetSourceState(Source, context, new_state);
1610 UnlockUIntMapRead(&context->SourceMap);
1612 V0(device->Backend,unlock)();
1616 /* alcSetError
1618 * Stores the latest ALC device error
1620 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1622 if(TrapALCError)
1624 #ifdef _WIN32
1625 /* DebugBreak() will cause an exception if there is no debugger */
1626 if(IsDebuggerPresent())
1627 DebugBreak();
1628 #elif defined(SIGTRAP)
1629 raise(SIGTRAP);
1630 #endif
1633 if(device)
1634 ATOMIC_STORE(&device->LastError, errorCode);
1635 else
1636 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1640 /* UpdateClockBase
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;
1664 ALCuint oldFreq;
1665 FPUCtl oldMode;
1666 ALCsizei hrtf_id = -1;
1667 size_t size;
1669 // Check for attributes
1670 if(device->Type == Loopback)
1672 enum {
1673 GotFreq = 1<<0,
1674 GotChans = 1<<1,
1675 GotType = 1<<2,
1676 GotAll = GotFreq|GotChans|GotType
1678 ALCuint freq, numMono, numStereo, numSends;
1679 enum DevFmtChannels schans;
1680 enum DevFmtType stype;
1681 ALCuint attrIdx = 0;
1682 ALCint gotFmt = 0;
1684 if(!attrList)
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;
1704 schans = val;
1705 gotFmt |= GotChans;
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;
1713 stype = val;
1714 gotFmt |= GotType;
1717 if(attrList[attrIdx] == ALC_FREQUENCY)
1719 freq = attrList[attrIdx + 1];
1720 if(freq < MIN_OUTPUT_RATE)
1721 return ALC_INVALID_VALUE;
1722 gotFmt |= GotFreq;
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;
1743 else
1744 hrtf_appreq = Hrtf_Default;
1747 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1748 hrtf_id = attrList[attrIdx + 1];
1750 attrIdx += 2;
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;
1817 else
1818 hrtf_appreq = Hrtf_Default;
1821 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1822 hrtf_id = attrList[attrIdx + 1];
1824 attrIdx += 2;
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 /
1836 device->Frequency;
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->Dry.Buffer);
1857 device->Dry.Buffer = NULL;
1858 device->Dry.NumChannels = 0;
1859 device->VirtOut.Buffer = NULL;
1860 device->VirtOut.NumChannels = 0;
1861 device->RealOut.Buffer = NULL;
1862 device->RealOut.NumChannels = 0;
1864 UpdateClockBase(device);
1866 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1867 if(device->Type != Loopback)
1869 const char *hrtf;
1870 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1872 if(strcasecmp(hrtf, "true") == 0)
1873 hrtf_userreq = Hrtf_Enable;
1874 else if(strcasecmp(hrtf, "false") == 0)
1875 hrtf_userreq = Hrtf_Disable;
1876 else if(strcasecmp(hrtf, "auto") != 0)
1877 ERR("Unexpected hrtf value: %s\n", hrtf);
1880 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1882 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1884 VECTOR_DEINIT(device->Hrtf_List);
1885 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1887 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1889 device->FmtChans = DevFmtStereo;
1890 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1891 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1892 else
1893 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1894 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1896 else
1898 hrtf_userreq = hrtf_appreq = Hrtf_Default;
1899 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1903 else if(hrtf_appreq == Hrtf_Enable)
1905 size_t i;
1906 /* Loopback device. We don't need to match to a specific HRTF entry
1907 * here. If the requested ID matches, we'll pick that later, if not,
1908 * we'll try to auto-select one anyway. */
1909 if(device->FmtChans != DevFmtStereo)
1910 i = VECTOR_SIZE(device->Hrtf_List);
1911 else
1913 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1915 VECTOR_DEINIT(device->Hrtf_List);
1916 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1918 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1920 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1921 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1922 break;
1925 if(i == VECTOR_SIZE(device->Hrtf_List))
1927 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1928 DevFmtChannelsString(device->FmtChans), device->Frequency);
1929 hrtf_appreq = Hrtf_Default;
1930 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1934 oldFreq = device->Frequency;
1935 oldChans = device->FmtChans;
1936 oldType = device->FmtType;
1938 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1939 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1940 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1941 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1942 device->UpdateSize, device->NumUpdates
1945 if(V0(device->Backend,reset)() == ALC_FALSE)
1946 return ALC_INVALID_DEVICE;
1948 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1950 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1951 DevFmtChannelsString(device->FmtChans));
1952 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1954 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1956 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1957 DevFmtTypeString(device->FmtType));
1958 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1960 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1962 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1963 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1966 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1967 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1968 device->Frequency, device->UpdateSize, device->NumUpdates
1971 if((device->UpdateSize&3) != 0)
1973 if((CPUCapFlags&CPU_CAP_SSE))
1974 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1975 if((CPUCapFlags&CPU_CAP_NEON))
1976 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1979 device->Hrtf = NULL;
1980 al_string_clear(&device->Hrtf_Name);
1981 device->Render_Mode = NormalRender;
1982 if(device->FmtChans != DevFmtStereo)
1984 if(hrtf_appreq == Hrtf_Enable)
1985 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1987 else
1989 bool headphones = device->IsHeadphones;
1990 enum RenderMode render_mode = HrtfRender;
1991 ALCenum hrtf_status = device->Hrtf_Status;
1992 const char *mode;
1993 int bs2blevel;
1994 int usehrtf;
1996 if(device->Type != Loopback)
1998 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
2000 if(strcasecmp(mode, "headphones") == 0)
2001 headphones = true;
2002 else if(strcasecmp(mode, "speakers") == 0)
2003 headphones = false;
2004 else if(strcasecmp(mode, "auto") != 0)
2005 ERR("Unexpected stereo-mode: %s\n", mode);
2008 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
2010 if(strcasecmp(mode, "full") == 0)
2011 render_mode = HrtfRender;
2012 else if(strcasecmp(mode, "basic") == 0)
2013 render_mode = NormalRender;
2014 else
2015 ERR("Unexpected hrtf-mode: %s\n", mode);
2020 if(hrtf_userreq == Hrtf_Default)
2022 usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
2023 (hrtf_appreq == Hrtf_Enable);
2024 if(headphones && hrtf_appreq != Hrtf_Disable)
2025 hrtf_status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
2026 else if(usehrtf)
2027 hrtf_status = ALC_HRTF_ENABLED_SOFT;
2029 else
2031 usehrtf = (hrtf_userreq == Hrtf_Enable);
2032 if(!usehrtf)
2033 hrtf_status = ALC_HRTF_DENIED_SOFT;
2034 else
2035 hrtf_status = ALC_HRTF_REQUIRED_SOFT;
2038 if(!usehrtf)
2039 device->Hrtf_Status = hrtf_status;
2040 else
2042 size_t i;
2044 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2045 if(VECTOR_SIZE(device->Hrtf_List) == 0)
2047 VECTOR_DEINIT(device->Hrtf_List);
2048 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2051 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
2053 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, hrtf_id);
2054 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2056 device->Hrtf = entry->hrtf;
2057 al_string_copy(&device->Hrtf_Name, entry->name);
2060 if(!device->Hrtf)
2062 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
2064 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
2065 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2067 device->Hrtf = entry->hrtf;
2068 al_string_copy(&device->Hrtf_Name, entry->name);
2069 break;
2074 if(device->Hrtf)
2076 device->Hrtf_Status = hrtf_status;
2077 device->Render_Mode = render_mode;
2078 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
2080 else
2082 TRACE("HRTF disabled\n");
2084 bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
2085 (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
2086 if(device->Type != Loopback)
2087 ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
2088 if(bs2blevel > 0 && bs2blevel <= 6)
2090 device->Bs2b = al_calloc(16, sizeof(*device->Bs2b));
2091 bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
2092 device->Render_Mode = StereoPair;
2093 TRACE("BS2B enabled\n");
2095 else
2097 TRACE("BS2B disabled\n");
2099 render_mode = NormalRender;
2100 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-panning", &mode))
2102 if(strcasecmp(mode, "paired") == 0)
2103 render_mode = StereoPair;
2104 else if(strcasecmp(mode, "uhj") != 0)
2105 ERR("Unexpected stereo-panning: %s\n", mode);
2107 device->Render_Mode = render_mode;
2108 if(render_mode == NormalRender)
2110 device->Uhj_Encoder = al_calloc(16, sizeof(Uhj2Encoder));
2111 TRACE("UHJ enabled\n");
2113 else
2114 TRACE("UHJ disabled\n");
2119 aluInitPanning(device);
2121 /* With HRTF, allocate two extra channels for the post-filter output. */
2122 size = device->Dry.NumChannels * sizeof(device->Dry.Buffer[0]);
2123 if(device->Hrtf || device->Uhj_Encoder)
2124 size += 2 * sizeof(device->Dry.Buffer[0]);
2125 device->Dry.Buffer = al_calloc(16, size);
2126 if(!device->Dry.Buffer)
2128 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2129 return ALC_INVALID_DEVICE;
2132 if(device->Hrtf || device->Uhj_Encoder)
2134 device->VirtOut.Buffer = device->Dry.Buffer;
2135 device->VirtOut.NumChannels = device->Dry.NumChannels;
2136 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2137 device->RealOut.NumChannels = 2;
2139 else
2141 device->VirtOut.Buffer = NULL;
2142 device->VirtOut.NumChannels = 0;
2143 device->RealOut.Buffer = device->Dry.Buffer;
2144 device->RealOut.NumChannels = device->Dry.NumChannels;
2147 SetMixerFPUMode(&oldMode);
2148 V0(device->Backend,lock)();
2149 context = ATOMIC_LOAD(&device->ContextList);
2150 while(context)
2152 ALsizei pos;
2154 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2155 LockUIntMapRead(&context->EffectSlotMap);
2156 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2158 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2160 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2162 UnlockUIntMapRead(&context->EffectSlotMap);
2163 V0(device->Backend,unlock)();
2164 RestoreFPUMode(&oldMode);
2165 return ALC_INVALID_DEVICE;
2167 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2168 V(slot->EffectState,update)(device, slot);
2170 UnlockUIntMapRead(&context->EffectSlotMap);
2172 LockUIntMapRead(&context->SourceMap);
2173 for(pos = 0;pos < context->SourceMap.size;pos++)
2175 ALsource *source = context->SourceMap.array[pos].value;
2176 ALuint s = device->NumAuxSends;
2177 while(s < MAX_SENDS)
2179 if(source->Send[s].Slot)
2180 DecrementRef(&source->Send[s].Slot->ref);
2181 source->Send[s].Slot = NULL;
2182 source->Send[s].Gain = 1.0f;
2183 source->Send[s].GainHF = 1.0f;
2184 s++;
2186 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2188 UnlockUIntMapRead(&context->SourceMap);
2190 for(pos = 0;pos < context->VoiceCount;pos++)
2192 ALvoice *voice = &context->Voices[pos];
2193 ALsource *source = voice->Source;
2195 if(source)
2197 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2198 voice->Update(voice, source, context);
2202 context = context->next;
2204 if(device->DefaultSlot)
2206 ALeffectslot *slot = device->DefaultSlot;
2208 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2210 V0(device->Backend,unlock)();
2211 RestoreFPUMode(&oldMode);
2212 return ALC_INVALID_DEVICE;
2214 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2215 V(slot->EffectState,update)(device, slot);
2217 V0(device->Backend,unlock)();
2218 RestoreFPUMode(&oldMode);
2220 if(!(device->Flags&DEVICE_PAUSED))
2222 if(V0(device->Backend,start)() == ALC_FALSE)
2223 return ALC_INVALID_DEVICE;
2224 device->Flags |= DEVICE_RUNNING;
2227 return ALC_NO_ERROR;
2230 /* FreeDevice
2232 * Frees the device structure, and destroys any objects the app failed to
2233 * delete. Called once there's no more references on the device.
2235 static ALCvoid FreeDevice(ALCdevice *device)
2237 TRACE("%p\n", device);
2239 V0(device->Backend,close)();
2240 DELETE_OBJ(device->Backend);
2241 device->Backend = NULL;
2243 if(device->DefaultSlot)
2245 ALeffectState *state = device->DefaultSlot->EffectState;
2246 device->DefaultSlot = NULL;
2247 DELETE_OBJ(state);
2250 if(device->BufferMap.size > 0)
2252 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2253 ReleaseALBuffers(device);
2255 ResetUIntMap(&device->BufferMap);
2257 if(device->EffectMap.size > 0)
2259 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2260 ReleaseALEffects(device);
2262 ResetUIntMap(&device->EffectMap);
2264 if(device->FilterMap.size > 0)
2266 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2267 ReleaseALFilters(device);
2269 ResetUIntMap(&device->FilterMap);
2271 AL_STRING_DEINIT(device->Hrtf_Name);
2272 FreeHrtfList(&device->Hrtf_List);
2274 al_free(device->Bs2b);
2275 device->Bs2b = NULL;
2277 al_free(device->Uhj_Encoder);
2278 device->Uhj_Encoder = NULL;
2280 AL_STRING_DEINIT(device->DeviceName);
2282 al_free(device->Dry.Buffer);
2283 device->Dry.Buffer = NULL;
2284 device->Dry.NumChannels = 0;
2285 device->VirtOut.Buffer = NULL;
2286 device->VirtOut.NumChannels = 0;
2287 device->RealOut.Buffer = NULL;
2288 device->RealOut.NumChannels = 0;
2290 al_free(device);
2294 void ALCdevice_IncRef(ALCdevice *device)
2296 uint ref;
2297 ref = IncrementRef(&device->ref);
2298 TRACEREF("%p increasing refcount to %u\n", device, ref);
2301 void ALCdevice_DecRef(ALCdevice *device)
2303 uint ref;
2304 ref = DecrementRef(&device->ref);
2305 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2306 if(ref == 0) FreeDevice(device);
2309 /* VerifyDevice
2311 * Checks if the device handle is valid, and increments its ref count if so.
2313 static ALCboolean VerifyDevice(ALCdevice **device)
2315 ALCdevice *tmpDevice;
2317 LockLists();
2318 tmpDevice = ATOMIC_LOAD(&DeviceList);
2319 while(tmpDevice)
2321 if(tmpDevice == *device)
2323 ALCdevice_IncRef(tmpDevice);
2324 UnlockLists();
2325 return ALC_TRUE;
2327 tmpDevice = tmpDevice->next;
2329 UnlockLists();
2331 *device = NULL;
2332 return ALC_FALSE;
2336 /* InitContext
2338 * Initializes context fields
2340 static ALvoid InitContext(ALCcontext *Context)
2342 ALlistener *listener = Context->Listener;
2343 //Initialise listener
2344 listener->Gain = 1.0f;
2345 listener->MetersPerUnit = 1.0f;
2346 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2347 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2348 listener->Forward[0] = 0.0f;
2349 listener->Forward[1] = 0.0f;
2350 listener->Forward[2] = -1.0f;
2351 listener->Up[0] = 0.0f;
2352 listener->Up[1] = 1.0f;
2353 listener->Up[2] = 0.0f;
2354 aluMatrixdSet(&listener->Params.Matrix,
2355 1.0, 0.0, 0.0, 0.0,
2356 0.0, 1.0, 0.0, 0.0,
2357 0.0, 0.0, 1.0, 0.0,
2358 0.0, 0.0, 0.0, 1.0
2360 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2362 //Validate Context
2363 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2364 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2365 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2366 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2368 //Set globals
2369 Context->DistanceModel = DefaultDistanceModel;
2370 Context->SourceDistanceModel = AL_FALSE;
2371 Context->DopplerFactor = 1.0f;
2372 Context->DopplerVelocity = 1.0f;
2373 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2374 Context->DeferUpdates = AL_FALSE;
2376 Context->ExtensionList = alExtList;
2380 /* FreeContext
2382 * Cleans up the context, and destroys any remaining objects the app failed to
2383 * delete. Called once there's no more references on the context.
2385 static void FreeContext(ALCcontext *context)
2387 TRACE("%p\n", context);
2389 if(context->SourceMap.size > 0)
2391 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2392 ReleaseALSources(context);
2394 ResetUIntMap(&context->SourceMap);
2396 if(context->EffectSlotMap.size > 0)
2398 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2399 ReleaseALAuxiliaryEffectSlots(context);
2401 ResetUIntMap(&context->EffectSlotMap);
2403 al_free(context->Voices);
2404 context->Voices = NULL;
2405 context->VoiceCount = 0;
2406 context->MaxVoices = 0;
2408 VECTOR_DEINIT(context->ActiveAuxSlots);
2410 ALCdevice_DecRef(context->Device);
2411 context->Device = NULL;
2413 //Invalidate context
2414 memset(context, 0, sizeof(ALCcontext));
2415 al_free(context);
2418 /* ReleaseContext
2420 * Removes the context reference from the given device and removes it from
2421 * being current on the running thread or globally.
2423 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2425 ALCcontext *nextctx;
2426 ALCcontext *origctx;
2428 if(altss_get(LocalContext) == context)
2430 WARN("%p released while current on thread\n", context);
2431 altss_set(LocalContext, NULL);
2432 ALCcontext_DecRef(context);
2435 origctx = context;
2436 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2437 ALCcontext_DecRef(context);
2439 ALCdevice_Lock(device);
2440 origctx = context;
2441 nextctx = context->next;
2442 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2444 ALCcontext *list;
2445 do {
2446 list = origctx;
2447 origctx = context;
2448 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2450 ALCdevice_Unlock(device);
2452 ALCcontext_DecRef(context);
2455 void ALCcontext_IncRef(ALCcontext *context)
2457 uint ref;
2458 ref = IncrementRef(&context->ref);
2459 TRACEREF("%p increasing refcount to %u\n", context, ref);
2462 void ALCcontext_DecRef(ALCcontext *context)
2464 uint ref;
2465 ref = DecrementRef(&context->ref);
2466 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2467 if(ref == 0) FreeContext(context);
2470 static void ReleaseThreadCtx(void *ptr)
2472 WARN("%p current for thread being destroyed\n", ptr);
2473 ALCcontext_DecRef(ptr);
2476 /* VerifyContext
2478 * Checks that the given context is valid, and increments its reference count.
2480 static ALCboolean VerifyContext(ALCcontext **context)
2482 ALCdevice *dev;
2484 LockLists();
2485 dev = ATOMIC_LOAD(&DeviceList);
2486 while(dev)
2488 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2489 while(ctx)
2491 if(ctx == *context)
2493 ALCcontext_IncRef(ctx);
2494 UnlockLists();
2495 return ALC_TRUE;
2497 ctx = ctx->next;
2499 dev = dev->next;
2501 UnlockLists();
2503 *context = NULL;
2504 return ALC_FALSE;
2508 /* GetContextRef
2510 * Returns the currently active context for this thread, and adds a reference
2511 * without locking it.
2513 ALCcontext *GetContextRef(void)
2515 ALCcontext *context;
2517 context = altss_get(LocalContext);
2518 if(context)
2519 ALCcontext_IncRef(context);
2520 else
2522 LockLists();
2523 context = ATOMIC_LOAD(&GlobalContext);
2524 if(context)
2525 ALCcontext_IncRef(context);
2526 UnlockLists();
2529 return context;
2533 /************************************************
2534 * Standard ALC functions
2535 ************************************************/
2537 /* alcGetError
2539 * Return last ALC generated error code for the given device
2541 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2543 ALCenum errorCode;
2545 if(VerifyDevice(&device))
2547 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2548 ALCdevice_DecRef(device);
2550 else
2551 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2553 return errorCode;
2557 /* alcSuspendContext
2559 * Suspends updates for the given context
2561 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2563 if(!SuspendDefers)
2564 return;
2566 if(!VerifyContext(&context))
2567 alcSetError(NULL, ALC_INVALID_CONTEXT);
2568 else
2570 ALCcontext_DeferUpdates(context);
2571 ALCcontext_DecRef(context);
2575 /* alcProcessContext
2577 * Resumes processing updates for the given context
2579 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2581 if(!SuspendDefers)
2582 return;
2584 if(!VerifyContext(&context))
2585 alcSetError(NULL, ALC_INVALID_CONTEXT);
2586 else
2588 ALCcontext_ProcessUpdates(context);
2589 ALCcontext_DecRef(context);
2594 /* alcGetString
2596 * Returns information about the device, and error strings
2598 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2600 const ALCchar *value = NULL;
2602 switch(param)
2604 case ALC_NO_ERROR:
2605 value = alcNoError;
2606 break;
2608 case ALC_INVALID_ENUM:
2609 value = alcErrInvalidEnum;
2610 break;
2612 case ALC_INVALID_VALUE:
2613 value = alcErrInvalidValue;
2614 break;
2616 case ALC_INVALID_DEVICE:
2617 value = alcErrInvalidDevice;
2618 break;
2620 case ALC_INVALID_CONTEXT:
2621 value = alcErrInvalidContext;
2622 break;
2624 case ALC_OUT_OF_MEMORY:
2625 value = alcErrOutOfMemory;
2626 break;
2628 case ALC_DEVICE_SPECIFIER:
2629 value = alcDefaultName;
2630 break;
2632 case ALC_ALL_DEVICES_SPECIFIER:
2633 if(VerifyDevice(&Device))
2635 value = al_string_get_cstr(Device->DeviceName);
2636 ALCdevice_DecRef(Device);
2638 else
2640 ProbeAllDevicesList();
2641 value = al_string_get_cstr(alcAllDevicesList);
2643 break;
2645 case ALC_CAPTURE_DEVICE_SPECIFIER:
2646 if(VerifyDevice(&Device))
2648 value = al_string_get_cstr(Device->DeviceName);
2649 ALCdevice_DecRef(Device);
2651 else
2653 ProbeCaptureDeviceList();
2654 value = al_string_get_cstr(alcCaptureDeviceList);
2656 break;
2658 /* Default devices are always first in the list */
2659 case ALC_DEFAULT_DEVICE_SPECIFIER:
2660 value = alcDefaultName;
2661 break;
2663 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2664 if(al_string_empty(alcAllDevicesList))
2665 ProbeAllDevicesList();
2667 VerifyDevice(&Device);
2669 free(alcDefaultAllDevicesSpecifier);
2670 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2671 if(!alcDefaultAllDevicesSpecifier)
2672 alcSetError(Device, ALC_OUT_OF_MEMORY);
2674 value = alcDefaultAllDevicesSpecifier;
2675 if(Device) ALCdevice_DecRef(Device);
2676 break;
2678 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2679 if(al_string_empty(alcCaptureDeviceList))
2680 ProbeCaptureDeviceList();
2682 VerifyDevice(&Device);
2684 free(alcCaptureDefaultDeviceSpecifier);
2685 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2686 if(!alcCaptureDefaultDeviceSpecifier)
2687 alcSetError(Device, ALC_OUT_OF_MEMORY);
2689 value = alcCaptureDefaultDeviceSpecifier;
2690 if(Device) ALCdevice_DecRef(Device);
2691 break;
2693 case ALC_EXTENSIONS:
2694 if(!VerifyDevice(&Device))
2695 value = alcNoDeviceExtList;
2696 else
2698 value = alcExtensionList;
2699 ALCdevice_DecRef(Device);
2701 break;
2703 case ALC_HRTF_SPECIFIER_SOFT:
2704 if(!VerifyDevice(&Device))
2705 alcSetError(NULL, ALC_INVALID_DEVICE);
2706 else
2708 LockLists();
2709 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2710 UnlockLists();
2711 ALCdevice_DecRef(Device);
2713 break;
2715 default:
2716 VerifyDevice(&Device);
2717 alcSetError(Device, ALC_INVALID_ENUM);
2718 if(Device) ALCdevice_DecRef(Device);
2719 break;
2722 return value;
2726 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2728 ALCsizei i;
2730 if(size <= 0 || values == NULL)
2732 alcSetError(device, ALC_INVALID_VALUE);
2733 return 0;
2736 if(!device)
2738 switch(param)
2740 case ALC_MAJOR_VERSION:
2741 values[0] = alcMajorVersion;
2742 return 1;
2743 case ALC_MINOR_VERSION:
2744 values[0] = alcMinorVersion;
2745 return 1;
2747 case ALC_ATTRIBUTES_SIZE:
2748 case ALC_ALL_ATTRIBUTES:
2749 case ALC_FREQUENCY:
2750 case ALC_REFRESH:
2751 case ALC_SYNC:
2752 case ALC_MONO_SOURCES:
2753 case ALC_STEREO_SOURCES:
2754 case ALC_CAPTURE_SAMPLES:
2755 case ALC_FORMAT_CHANNELS_SOFT:
2756 case ALC_FORMAT_TYPE_SOFT:
2757 alcSetError(NULL, ALC_INVALID_DEVICE);
2758 return 0;
2760 default:
2761 alcSetError(NULL, ALC_INVALID_ENUM);
2762 return 0;
2764 return 0;
2767 if(device->Type == Capture)
2769 switch(param)
2771 case ALC_CAPTURE_SAMPLES:
2772 V0(device->Backend,lock)();
2773 values[0] = V0(device->Backend,availableSamples)();
2774 V0(device->Backend,unlock)();
2775 return 1;
2777 case ALC_CONNECTED:
2778 values[0] = device->Connected;
2779 return 1;
2781 default:
2782 alcSetError(device, ALC_INVALID_ENUM);
2783 return 0;
2785 return 0;
2788 /* render device */
2789 switch(param)
2791 case ALC_MAJOR_VERSION:
2792 values[0] = alcMajorVersion;
2793 return 1;
2795 case ALC_MINOR_VERSION:
2796 values[0] = alcMinorVersion;
2797 return 1;
2799 case ALC_EFX_MAJOR_VERSION:
2800 values[0] = alcEFXMajorVersion;
2801 return 1;
2803 case ALC_EFX_MINOR_VERSION:
2804 values[0] = alcEFXMinorVersion;
2805 return 1;
2807 case ALC_ATTRIBUTES_SIZE:
2808 values[0] = 17;
2809 return 1;
2811 case ALC_ALL_ATTRIBUTES:
2812 if(size < 17)
2814 alcSetError(device, ALC_INVALID_VALUE);
2815 return 0;
2818 i = 0;
2819 values[i++] = ALC_FREQUENCY;
2820 values[i++] = device->Frequency;
2822 if(device->Type != Loopback)
2824 values[i++] = ALC_REFRESH;
2825 values[i++] = device->Frequency / device->UpdateSize;
2827 values[i++] = ALC_SYNC;
2828 values[i++] = ALC_FALSE;
2830 else
2832 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2833 values[i++] = device->FmtChans;
2835 values[i++] = ALC_FORMAT_TYPE_SOFT;
2836 values[i++] = device->FmtType;
2839 values[i++] = ALC_MONO_SOURCES;
2840 values[i++] = device->NumMonoSources;
2842 values[i++] = ALC_STEREO_SOURCES;
2843 values[i++] = device->NumStereoSources;
2845 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2846 values[i++] = device->NumAuxSends;
2848 values[i++] = ALC_HRTF_SOFT;
2849 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2851 values[i++] = ALC_HRTF_STATUS_SOFT;
2852 values[i++] = device->Hrtf_Status;
2854 values[i++] = 0;
2855 return i;
2857 case ALC_FREQUENCY:
2858 values[0] = device->Frequency;
2859 return 1;
2861 case ALC_REFRESH:
2862 if(device->Type == Loopback)
2864 alcSetError(device, ALC_INVALID_DEVICE);
2865 return 0;
2867 values[0] = device->Frequency / device->UpdateSize;
2868 return 1;
2870 case ALC_SYNC:
2871 if(device->Type == Loopback)
2873 alcSetError(device, ALC_INVALID_DEVICE);
2874 return 0;
2876 values[0] = ALC_FALSE;
2877 return 1;
2879 case ALC_FORMAT_CHANNELS_SOFT:
2880 if(device->Type != Loopback)
2882 alcSetError(device, ALC_INVALID_DEVICE);
2883 return 0;
2885 values[0] = device->FmtChans;
2886 return 1;
2888 case ALC_FORMAT_TYPE_SOFT:
2889 if(device->Type != Loopback)
2891 alcSetError(device, ALC_INVALID_DEVICE);
2892 return 0;
2894 values[0] = device->FmtType;
2895 return 1;
2897 case ALC_MONO_SOURCES:
2898 values[0] = device->NumMonoSources;
2899 return 1;
2901 case ALC_STEREO_SOURCES:
2902 values[0] = device->NumStereoSources;
2903 return 1;
2905 case ALC_MAX_AUXILIARY_SENDS:
2906 values[0] = device->NumAuxSends;
2907 return 1;
2909 case ALC_CONNECTED:
2910 values[0] = device->Connected;
2911 return 1;
2913 case ALC_HRTF_SOFT:
2914 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2915 return 1;
2917 case ALC_HRTF_STATUS_SOFT:
2918 values[0] = device->Hrtf_Status;
2919 return 1;
2921 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2922 FreeHrtfList(&device->Hrtf_List);
2923 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2924 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2925 return 1;
2927 default:
2928 alcSetError(device, ALC_INVALID_ENUM);
2929 return 0;
2931 return 0;
2934 /* alcGetIntegerv
2936 * Returns information about the device and the version of OpenAL
2938 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2940 VerifyDevice(&device);
2941 if(size <= 0 || values == NULL)
2942 alcSetError(device, ALC_INVALID_VALUE);
2943 else
2944 GetIntegerv(device, param, size, values);
2945 if(device) ALCdevice_DecRef(device);
2948 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2950 ALCint *ivals;
2951 ALsizei i;
2953 VerifyDevice(&device);
2954 if(size <= 0 || values == NULL)
2955 alcSetError(device, ALC_INVALID_VALUE);
2956 else if(!device || device->Type == Capture)
2958 ivals = malloc(size * sizeof(ALCint));
2959 size = GetIntegerv(device, pname, size, ivals);
2960 for(i = 0;i < size;i++)
2961 values[i] = ivals[i];
2962 free(ivals);
2964 else /* render device */
2966 switch(pname)
2968 case ALC_ATTRIBUTES_SIZE:
2969 *values = 19;
2970 break;
2972 case ALC_ALL_ATTRIBUTES:
2973 if(size < 19)
2974 alcSetError(device, ALC_INVALID_VALUE);
2975 else
2977 int i = 0;
2979 V0(device->Backend,lock)();
2980 values[i++] = ALC_FREQUENCY;
2981 values[i++] = device->Frequency;
2983 if(device->Type != Loopback)
2985 values[i++] = ALC_REFRESH;
2986 values[i++] = device->Frequency / device->UpdateSize;
2988 values[i++] = ALC_SYNC;
2989 values[i++] = ALC_FALSE;
2991 else
2993 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2994 values[i++] = device->FmtChans;
2996 values[i++] = ALC_FORMAT_TYPE_SOFT;
2997 values[i++] = device->FmtType;
3000 values[i++] = ALC_MONO_SOURCES;
3001 values[i++] = device->NumMonoSources;
3003 values[i++] = ALC_STEREO_SOURCES;
3004 values[i++] = device->NumStereoSources;
3006 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3007 values[i++] = device->NumAuxSends;
3009 values[i++] = ALC_HRTF_SOFT;
3010 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
3012 values[i++] = ALC_HRTF_STATUS_SOFT;
3013 values[i++] = device->Hrtf_Status;
3015 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3016 values[i++] = device->ClockBase +
3017 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
3019 values[i++] = 0;
3020 V0(device->Backend,unlock)();
3022 break;
3024 case ALC_DEVICE_CLOCK_SOFT:
3025 V0(device->Backend,lock)();
3026 *values = device->ClockBase +
3027 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
3028 V0(device->Backend,unlock)();
3029 break;
3031 default:
3032 ivals = malloc(size * sizeof(ALCint));
3033 size = GetIntegerv(device, pname, size, ivals);
3034 for(i = 0;i < size;i++)
3035 values[i] = ivals[i];
3036 free(ivals);
3037 break;
3040 if(device)
3041 ALCdevice_DecRef(device);
3045 /* alcIsExtensionPresent
3047 * Determines if there is support for a particular extension
3049 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3051 ALCboolean bResult = ALC_FALSE;
3053 VerifyDevice(&device);
3055 if(!extName)
3056 alcSetError(device, ALC_INVALID_VALUE);
3057 else
3059 size_t len = strlen(extName);
3060 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3061 while(ptr && *ptr)
3063 if(strncasecmp(ptr, extName, len) == 0 &&
3064 (ptr[len] == '\0' || isspace(ptr[len])))
3066 bResult = ALC_TRUE;
3067 break;
3069 if((ptr=strchr(ptr, ' ')) != NULL)
3071 do {
3072 ++ptr;
3073 } while(isspace(*ptr));
3077 if(device)
3078 ALCdevice_DecRef(device);
3079 return bResult;
3083 /* alcGetProcAddress
3085 * Retrieves the function address for a particular extension function
3087 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3089 ALCvoid *ptr = NULL;
3091 if(!funcName)
3093 VerifyDevice(&device);
3094 alcSetError(device, ALC_INVALID_VALUE);
3095 if(device) ALCdevice_DecRef(device);
3097 else
3099 ALsizei i = 0;
3100 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3101 i++;
3102 ptr = alcFunctions[i].address;
3105 return ptr;
3109 /* alcGetEnumValue
3111 * Get the value for a particular ALC enumeration name
3113 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3115 ALCenum val = 0;
3117 if(!enumName)
3119 VerifyDevice(&device);
3120 alcSetError(device, ALC_INVALID_VALUE);
3121 if(device) ALCdevice_DecRef(device);
3123 else
3125 ALsizei i = 0;
3126 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3127 i++;
3128 val = enumeration[i].value;
3131 return val;
3135 /* alcCreateContext
3137 * Create and attach a context to the given device.
3139 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3141 ALCcontext *ALContext;
3142 ALCenum err;
3144 LockLists();
3145 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3147 UnlockLists();
3148 alcSetError(device, ALC_INVALID_DEVICE);
3149 if(device) ALCdevice_DecRef(device);
3150 return NULL;
3153 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3155 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3157 UnlockLists();
3158 alcSetError(device, err);
3159 if(err == ALC_INVALID_DEVICE)
3161 V0(device->Backend,lock)();
3162 aluHandleDisconnect(device);
3163 V0(device->Backend,unlock)();
3165 ALCdevice_DecRef(device);
3166 return NULL;
3169 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3170 if(ALContext)
3172 InitRef(&ALContext->ref, 1);
3173 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3175 VECTOR_INIT(ALContext->ActiveAuxSlots);
3177 ALContext->VoiceCount = 0;
3178 ALContext->MaxVoices = 256;
3179 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3181 if(!ALContext || !ALContext->Voices)
3183 if(!ATOMIC_LOAD(&device->ContextList))
3185 V0(device->Backend,stop)();
3186 device->Flags &= ~DEVICE_RUNNING;
3188 UnlockLists();
3190 if(ALContext)
3192 al_free(ALContext->Voices);
3193 ALContext->Voices = NULL;
3195 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3197 al_free(ALContext);
3198 ALContext = NULL;
3201 alcSetError(device, ALC_OUT_OF_MEMORY);
3202 ALCdevice_DecRef(device);
3203 return NULL;
3206 ALContext->Device = device;
3207 ALCdevice_IncRef(device);
3208 InitContext(ALContext);
3211 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3212 do {
3213 ALContext->next = head;
3214 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3216 UnlockLists();
3218 ALCdevice_DecRef(device);
3220 TRACE("Created context %p\n", ALContext);
3221 return ALContext;
3224 /* alcDestroyContext
3226 * Remove a context from its device
3228 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3230 ALCdevice *Device;
3232 LockLists();
3233 /* alcGetContextsDevice sets an error for invalid contexts */
3234 Device = alcGetContextsDevice(context);
3235 if(Device)
3237 ReleaseContext(context, Device);
3238 if(!ATOMIC_LOAD(&Device->ContextList))
3240 V0(Device->Backend,stop)();
3241 Device->Flags &= ~DEVICE_RUNNING;
3244 UnlockLists();
3248 /* alcGetCurrentContext
3250 * Returns the currently active context on the calling thread
3252 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3254 ALCcontext *Context = altss_get(LocalContext);
3255 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3256 return Context;
3259 /* alcGetThreadContext
3261 * Returns the currently active thread-local context
3263 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3265 return altss_get(LocalContext);
3269 /* alcMakeContextCurrent
3271 * Makes the given context the active process-wide context, and removes the
3272 * thread-local context for the calling thread.
3274 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3276 /* context must be valid or NULL */
3277 if(context && !VerifyContext(&context))
3279 alcSetError(NULL, ALC_INVALID_CONTEXT);
3280 return ALC_FALSE;
3282 /* context's reference count is already incremented */
3283 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3284 if(context) ALCcontext_DecRef(context);
3286 if((context=altss_get(LocalContext)) != NULL)
3288 altss_set(LocalContext, NULL);
3289 ALCcontext_DecRef(context);
3292 return ALC_TRUE;
3295 /* alcSetThreadContext
3297 * Makes the given context the active context for the current thread
3299 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3301 ALCcontext *old;
3303 /* context must be valid or NULL */
3304 if(context && !VerifyContext(&context))
3306 alcSetError(NULL, ALC_INVALID_CONTEXT);
3307 return ALC_FALSE;
3309 /* context's reference count is already incremented */
3310 old = altss_get(LocalContext);
3311 altss_set(LocalContext, context);
3312 if(old) ALCcontext_DecRef(old);
3314 return ALC_TRUE;
3318 /* alcGetContextsDevice
3320 * Returns the device that a particular context is attached to
3322 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3324 ALCdevice *Device;
3326 if(!VerifyContext(&Context))
3328 alcSetError(NULL, ALC_INVALID_CONTEXT);
3329 return NULL;
3331 Device = Context->Device;
3332 ALCcontext_DecRef(Context);
3334 return Device;
3338 /* alcOpenDevice
3340 * Opens the named device.
3342 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3344 const ALCchar *fmt;
3345 ALCdevice *device;
3346 ALCenum err;
3348 DO_INITCONFIG();
3350 if(!PlaybackBackend.name)
3352 alcSetError(NULL, ALC_INVALID_VALUE);
3353 return NULL;
3356 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3357 #ifdef _WIN32
3358 /* Some old Windows apps hardcode these expecting OpenAL to use a
3359 * specific audio API, even when they're not enumerated. Creative's
3360 * router effectively ignores them too.
3362 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3363 || strcasecmp(deviceName, "MMSYSTEM") == 0
3364 #endif
3366 deviceName = NULL;
3368 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3369 if(!device)
3371 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3372 return NULL;
3375 //Validate device
3376 InitRef(&device->ref, 1);
3377 device->Connected = ALC_TRUE;
3378 device->Type = Playback;
3379 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3381 device->Flags = 0;
3382 device->Bs2b = NULL;
3383 device->Uhj_Encoder = NULL;
3384 VECTOR_INIT(device->Hrtf_List);
3385 AL_STRING_INIT(device->Hrtf_Name);
3386 device->Render_Mode = NormalRender;
3387 AL_STRING_INIT(device->DeviceName);
3388 device->Dry.Buffer = NULL;
3389 device->Dry.NumChannels = 0;
3390 device->VirtOut.Buffer = NULL;
3391 device->VirtOut.NumChannels = 0;
3392 device->RealOut.Buffer = NULL;
3393 device->RealOut.NumChannels = 0;
3395 ATOMIC_INIT(&device->ContextList, NULL);
3397 device->ClockBase = 0;
3398 device->SamplesDone = 0;
3400 device->MaxNoOfSources = 256;
3401 device->AuxiliaryEffectSlotMax = 4;
3402 device->NumAuxSends = MAX_SENDS;
3404 InitUIntMap(&device->BufferMap, ~0);
3405 InitUIntMap(&device->EffectMap, ~0);
3406 InitUIntMap(&device->FilterMap, ~0);
3408 //Set output format
3409 device->FmtChans = DevFmtChannelsDefault;
3410 device->FmtType = DevFmtTypeDefault;
3411 device->Frequency = DEFAULT_OUTPUT_RATE;
3412 device->IsHeadphones = AL_FALSE;
3413 device->NumUpdates = 4;
3414 device->UpdateSize = 1024;
3416 if(!PlaybackBackend.getFactory)
3417 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3418 ALCbackend_Playback);
3419 else
3421 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3422 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3424 if(!device->Backend)
3426 al_free(device);
3427 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3428 return NULL;
3432 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3434 static const struct {
3435 const char name[16];
3436 enum DevFmtChannels chans;
3437 } chanlist[] = {
3438 { "mono", DevFmtMono },
3439 { "stereo", DevFmtStereo },
3440 { "quad", DevFmtQuad },
3441 { "surround51", DevFmtX51 },
3442 { "surround61", DevFmtX61 },
3443 { "surround71", DevFmtX71 },
3444 { "surround51rear", DevFmtX51Rear },
3446 size_t i;
3448 for(i = 0;i < COUNTOF(chanlist);i++)
3450 if(strcasecmp(chanlist[i].name, fmt) == 0)
3452 device->FmtChans = chanlist[i].chans;
3453 device->Flags |= DEVICE_CHANNELS_REQUEST;
3454 break;
3457 if(i == COUNTOF(chanlist))
3458 ERR("Unsupported channels: %s\n", fmt);
3460 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3462 static const struct {
3463 const char name[16];
3464 enum DevFmtType type;
3465 } typelist[] = {
3466 { "int8", DevFmtByte },
3467 { "uint8", DevFmtUByte },
3468 { "int16", DevFmtShort },
3469 { "uint16", DevFmtUShort },
3470 { "int32", DevFmtInt },
3471 { "uint32", DevFmtUInt },
3472 { "float32", DevFmtFloat },
3474 size_t i;
3476 for(i = 0;i < COUNTOF(typelist);i++)
3478 if(strcasecmp(typelist[i].name, fmt) == 0)
3480 device->FmtType = typelist[i].type;
3481 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3482 break;
3485 if(i == COUNTOF(typelist))
3486 ERR("Unsupported sample-type: %s\n", fmt);
3489 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3491 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3492 if(device->Frequency < MIN_OUTPUT_RATE)
3493 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3494 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3497 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3498 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3500 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3501 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3502 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3503 device->UpdateSize = (device->UpdateSize+3)&~3;
3505 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3506 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3508 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3509 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3511 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3512 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3514 device->NumStereoSources = 1;
3515 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3517 // Find a playback device to open
3518 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3520 DELETE_OBJ(device->Backend);
3521 al_free(device);
3522 alcSetError(NULL, err);
3523 return NULL;
3526 if(DefaultEffect.type != AL_EFFECT_NULL)
3528 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3529 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3531 device->DefaultSlot = NULL;
3532 ERR("Failed to initialize the default effect slot\n");
3534 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3536 ALeffectState *state = device->DefaultSlot->EffectState;
3537 device->DefaultSlot = NULL;
3538 DELETE_OBJ(state);
3539 ERR("Failed to initialize the default effect\n");
3541 else
3542 aluInitEffectPanning(device->DefaultSlot);
3546 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3547 do {
3548 device->next = head;
3549 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3552 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3553 return device;
3556 /* alcCloseDevice
3558 * Closes the given device.
3560 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3562 ALCdevice *list, *origdev, *nextdev;
3563 ALCcontext *ctx;
3565 LockLists();
3566 list = ATOMIC_LOAD(&DeviceList);
3567 do {
3568 if(list == device)
3569 break;
3570 } while((list=list->next) != NULL);
3571 if(!list || list->Type == Capture)
3573 alcSetError(list, ALC_INVALID_DEVICE);
3574 UnlockLists();
3575 return ALC_FALSE;
3578 origdev = device;
3579 nextdev = device->next;
3580 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3582 do {
3583 list = origdev;
3584 origdev = device;
3585 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3587 UnlockLists();
3589 ctx = ATOMIC_LOAD(&device->ContextList);
3590 while(ctx != NULL)
3592 ALCcontext *next = ctx->next;
3593 WARN("Releasing context %p\n", ctx);
3594 ReleaseContext(ctx, device);
3595 ctx = next;
3597 if((device->Flags&DEVICE_RUNNING))
3598 V0(device->Backend,stop)();
3599 device->Flags &= ~DEVICE_RUNNING;
3601 ALCdevice_DecRef(device);
3603 return ALC_TRUE;
3607 /************************************************
3608 * ALC capture functions
3609 ************************************************/
3610 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3612 ALCdevice *device = NULL;
3613 ALCenum err;
3615 DO_INITCONFIG();
3617 if(!CaptureBackend.name)
3619 alcSetError(NULL, ALC_INVALID_VALUE);
3620 return NULL;
3623 if(samples <= 0)
3625 alcSetError(NULL, ALC_INVALID_VALUE);
3626 return NULL;
3629 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3630 deviceName = NULL;
3632 device = al_calloc(16, sizeof(ALCdevice));
3633 if(!device)
3635 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3636 return NULL;
3639 //Validate device
3640 InitRef(&device->ref, 1);
3641 device->Connected = ALC_TRUE;
3642 device->Type = Capture;
3644 VECTOR_INIT(device->Hrtf_List);
3645 AL_STRING_INIT(device->Hrtf_Name);
3647 AL_STRING_INIT(device->DeviceName);
3648 device->Dry.Buffer = NULL;
3649 device->Dry.NumChannels = 0;
3650 device->VirtOut.Buffer = NULL;
3651 device->VirtOut.NumChannels = 0;
3652 device->RealOut.Buffer = NULL;
3653 device->RealOut.NumChannels = 0;
3655 InitUIntMap(&device->BufferMap, ~0);
3656 InitUIntMap(&device->EffectMap, ~0);
3657 InitUIntMap(&device->FilterMap, ~0);
3659 if(!CaptureBackend.getFactory)
3660 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3661 ALCbackend_Capture);
3662 else
3664 ALCbackendFactory *factory = CaptureBackend.getFactory();
3665 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3667 if(!device->Backend)
3669 al_free(device);
3670 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3671 return NULL;
3674 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3675 device->Frequency = frequency;
3677 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3678 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3680 al_free(device);
3681 alcSetError(NULL, ALC_INVALID_ENUM);
3682 return NULL;
3684 device->IsHeadphones = AL_FALSE;
3686 device->UpdateSize = samples;
3687 device->NumUpdates = 1;
3689 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3691 al_free(device);
3692 alcSetError(NULL, err);
3693 return NULL;
3697 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3698 do {
3699 device->next = head;
3700 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3703 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3704 return device;
3707 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3709 ALCdevice *list, *next, *nextdev;
3711 LockLists();
3712 list = ATOMIC_LOAD(&DeviceList);
3713 do {
3714 if(list == device)
3715 break;
3716 } while((list=list->next) != NULL);
3717 if(!list || list->Type != Capture)
3719 alcSetError(list, ALC_INVALID_DEVICE);
3720 UnlockLists();
3721 return ALC_FALSE;
3724 next = device;
3725 nextdev = device->next;
3726 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3728 do {
3729 list = next;
3730 next = device;
3731 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3733 UnlockLists();
3735 ALCdevice_DecRef(device);
3737 return ALC_TRUE;
3740 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3742 if(!VerifyDevice(&device) || device->Type != Capture)
3743 alcSetError(device, ALC_INVALID_DEVICE);
3744 else
3746 V0(device->Backend,lock)();
3747 if(!device->Connected)
3748 alcSetError(device, ALC_INVALID_DEVICE);
3749 else if(!(device->Flags&DEVICE_RUNNING))
3751 if(V0(device->Backend,start)())
3752 device->Flags |= DEVICE_RUNNING;
3753 else
3755 aluHandleDisconnect(device);
3756 alcSetError(device, ALC_INVALID_DEVICE);
3759 V0(device->Backend,unlock)();
3762 if(device) ALCdevice_DecRef(device);
3765 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3767 if(!VerifyDevice(&device) || device->Type != Capture)
3768 alcSetError(device, ALC_INVALID_DEVICE);
3769 else
3771 V0(device->Backend,lock)();
3772 if((device->Flags&DEVICE_RUNNING))
3773 V0(device->Backend,stop)();
3774 device->Flags &= ~DEVICE_RUNNING;
3775 V0(device->Backend,unlock)();
3778 if(device) ALCdevice_DecRef(device);
3781 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3783 if(!VerifyDevice(&device) || device->Type != Capture)
3784 alcSetError(device, ALC_INVALID_DEVICE);
3785 else
3787 ALCenum err = ALC_INVALID_VALUE;
3789 V0(device->Backend,lock)();
3790 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3791 err = V(device->Backend,captureSamples)(buffer, samples);
3792 V0(device->Backend,unlock)();
3794 if(err != ALC_NO_ERROR)
3795 alcSetError(device, err);
3797 if(device) ALCdevice_DecRef(device);
3801 /************************************************
3802 * ALC loopback functions
3803 ************************************************/
3805 /* alcLoopbackOpenDeviceSOFT
3807 * Open a loopback device, for manual rendering.
3809 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3811 ALCbackendFactory *factory;
3812 ALCdevice *device;
3814 DO_INITCONFIG();
3816 /* Make sure the device name, if specified, is us. */
3817 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3819 alcSetError(NULL, ALC_INVALID_VALUE);
3820 return NULL;
3823 device = al_calloc(16, sizeof(ALCdevice));
3824 if(!device)
3826 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3827 return NULL;
3830 //Validate device
3831 InitRef(&device->ref, 1);
3832 device->Connected = ALC_TRUE;
3833 device->Type = Loopback;
3834 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3836 device->Flags = 0;
3837 VECTOR_INIT(device->Hrtf_List);
3838 AL_STRING_INIT(device->Hrtf_Name);
3839 device->Bs2b = NULL;
3840 device->Uhj_Encoder = NULL;
3841 device->Render_Mode = NormalRender;
3842 AL_STRING_INIT(device->DeviceName);
3843 device->Dry.Buffer = NULL;
3844 device->Dry.NumChannels = 0;
3845 device->VirtOut.Buffer = NULL;
3846 device->VirtOut.NumChannels = 0;
3847 device->RealOut.Buffer = NULL;
3848 device->RealOut.NumChannels = 0;
3850 ATOMIC_INIT(&device->ContextList, NULL);
3852 device->ClockBase = 0;
3853 device->SamplesDone = 0;
3855 device->MaxNoOfSources = 256;
3856 device->AuxiliaryEffectSlotMax = 4;
3857 device->NumAuxSends = MAX_SENDS;
3859 InitUIntMap(&device->BufferMap, ~0);
3860 InitUIntMap(&device->EffectMap, ~0);
3861 InitUIntMap(&device->FilterMap, ~0);
3863 factory = ALCloopbackFactory_getFactory();
3864 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3865 if(!device->Backend)
3867 al_free(device);
3868 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3869 return NULL;
3872 //Set output format
3873 device->NumUpdates = 0;
3874 device->UpdateSize = 0;
3876 device->Frequency = DEFAULT_OUTPUT_RATE;
3877 device->FmtChans = DevFmtChannelsDefault;
3878 device->FmtType = DevFmtTypeDefault;
3879 device->IsHeadphones = AL_FALSE;
3881 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3882 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3884 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3885 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3887 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3888 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3890 device->NumStereoSources = 1;
3891 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3893 // Open the "backend"
3894 V(device->Backend,open)("Loopback");
3897 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3898 do {
3899 device->next = head;
3900 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3903 TRACE("Created device %p\n", device);
3904 return device;
3907 /* alcIsRenderFormatSupportedSOFT
3909 * Determines if the loopback device supports the given format for rendering.
3911 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3913 ALCboolean ret = ALC_FALSE;
3915 if(!VerifyDevice(&device) || device->Type != Loopback)
3916 alcSetError(device, ALC_INVALID_DEVICE);
3917 else if(freq <= 0)
3918 alcSetError(device, ALC_INVALID_VALUE);
3919 else
3921 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3922 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3923 freq >= MIN_OUTPUT_RATE)
3924 ret = ALC_TRUE;
3926 if(device) ALCdevice_DecRef(device);
3928 return ret;
3931 /* alcRenderSamplesSOFT
3933 * Renders some samples into a buffer, using the format last set by the
3934 * attributes given to alcCreateContext.
3936 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3938 if(!VerifyDevice(&device) || device->Type != Loopback)
3939 alcSetError(device, ALC_INVALID_DEVICE);
3940 else if(samples < 0 || (samples > 0 && buffer == NULL))
3941 alcSetError(device, ALC_INVALID_VALUE);
3942 else
3943 aluMixData(device, buffer, samples);
3944 if(device) ALCdevice_DecRef(device);
3948 /************************************************
3949 * ALC DSP pause/resume functions
3950 ************************************************/
3952 /* alcDevicePauseSOFT
3954 * Pause the DSP to stop audio processing.
3956 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3958 if(!VerifyDevice(&device) || device->Type != Playback)
3959 alcSetError(device, ALC_INVALID_DEVICE);
3960 else
3962 LockLists();
3963 if((device->Flags&DEVICE_RUNNING))
3964 V0(device->Backend,stop)();
3965 device->Flags &= ~DEVICE_RUNNING;
3966 device->Flags |= DEVICE_PAUSED;
3967 UnlockLists();
3969 if(device) ALCdevice_DecRef(device);
3972 /* alcDeviceResumeSOFT
3974 * Resume the DSP to restart audio processing.
3976 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3978 if(!VerifyDevice(&device) || device->Type != Playback)
3979 alcSetError(device, ALC_INVALID_DEVICE);
3980 else
3982 LockLists();
3983 if((device->Flags&DEVICE_PAUSED))
3985 device->Flags &= ~DEVICE_PAUSED;
3986 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3988 if(V0(device->Backend,start)() != ALC_FALSE)
3989 device->Flags |= DEVICE_RUNNING;
3990 else
3992 alcSetError(device, ALC_INVALID_DEVICE);
3993 V0(device->Backend,lock)();
3994 aluHandleDisconnect(device);
3995 V0(device->Backend,unlock)();
3999 UnlockLists();
4001 if(device) ALCdevice_DecRef(device);
4005 /************************************************
4006 * ALC HRTF functions
4007 ************************************************/
4009 /* alcGetStringiSOFT
4011 * Gets a string parameter at the given index.
4013 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4015 const ALCchar *str = NULL;
4017 if(!VerifyDevice(&device) || device->Type == Capture)
4018 alcSetError(device, ALC_INVALID_DEVICE);
4019 else switch(paramName)
4021 case ALC_HRTF_SPECIFIER_SOFT:
4022 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
4023 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
4024 else
4025 alcSetError(device, ALC_INVALID_VALUE);
4026 break;
4028 default:
4029 alcSetError(device, ALC_INVALID_ENUM);
4030 break;
4032 if(device) ALCdevice_DecRef(device);
4034 return str;
4037 /* alcResetDeviceSOFT
4039 * Resets the given device output, using the specified attribute list.
4041 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4043 ALCenum err;
4045 LockLists();
4046 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4048 UnlockLists();
4049 alcSetError(device, ALC_INVALID_DEVICE);
4050 if(device) ALCdevice_DecRef(device);
4051 return ALC_FALSE;
4054 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
4056 UnlockLists();
4057 alcSetError(device, err);
4058 if(err == ALC_INVALID_DEVICE)
4060 V0(device->Backend,lock)();
4061 aluHandleDisconnect(device);
4062 V0(device->Backend,unlock)();
4064 ALCdevice_DecRef(device);
4065 return ALC_FALSE;
4067 UnlockLists();
4068 ALCdevice_DecRef(device);
4070 return ALC_TRUE;