Use the "decoder" config section instead of "ambisonics"
[openal-soft.git] / Alc / ALc.c
blob7c3afa0c8ee37e77fd0ca247bbc764f5f0f0db68
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 "bformatdec.h"
41 #include "ambdec.h"
42 #include "alu.h"
44 #include "compat.h"
45 #include "threads.h"
46 #include "alstring.h"
48 #include "backends/base.h"
51 /************************************************
52 * Backends
53 ************************************************/
54 struct BackendInfo {
55 const char *name;
56 ALCbackendFactory* (*getFactory)(void);
57 ALCboolean (*Init)(BackendFuncs*);
58 void (*Deinit)(void);
59 void (*Probe)(enum DevProbe);
60 BackendFuncs Funcs;
63 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
64 static struct BackendInfo BackendList[] = {
65 #ifdef HAVE_JACK
66 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
67 #endif
68 #ifdef HAVE_PULSEAUDIO
69 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
70 #endif
71 #ifdef HAVE_ALSA
72 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
73 #endif
74 #ifdef HAVE_COREAUDIO
75 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
76 #endif
77 #ifdef HAVE_OSS
78 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
79 #endif
80 #ifdef HAVE_SOLARIS
81 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
82 #endif
83 #ifdef HAVE_SNDIO
84 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
85 #endif
86 #ifdef HAVE_QSA
87 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
88 #endif
89 #ifdef HAVE_MMDEVAPI
90 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
91 #endif
92 #ifdef HAVE_DSOUND
93 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
94 #endif
95 #ifdef HAVE_WINMM
96 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
97 #endif
98 #ifdef HAVE_PORTAUDIO
99 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
100 #endif
101 #ifdef HAVE_OPENSL
102 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
103 #endif
105 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
106 #ifdef HAVE_WAVE
107 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
108 #endif
110 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
112 #undef EmptyFuncs
114 static struct BackendInfo PlaybackBackend;
115 static struct BackendInfo CaptureBackend;
118 /************************************************
119 * Functions, enums, and errors
120 ************************************************/
121 typedef struct ALCfunction {
122 const ALCchar *funcName;
123 ALCvoid *address;
124 } ALCfunction;
126 typedef struct ALCenums {
127 const ALCchar *enumName;
128 ALCenum value;
129 } ALCenums;
131 #define DECL(x) { #x, (ALCvoid*)(x) }
132 static const ALCfunction alcFunctions[] = {
133 DECL(alcCreateContext),
134 DECL(alcMakeContextCurrent),
135 DECL(alcProcessContext),
136 DECL(alcSuspendContext),
137 DECL(alcDestroyContext),
138 DECL(alcGetCurrentContext),
139 DECL(alcGetContextsDevice),
140 DECL(alcOpenDevice),
141 DECL(alcCloseDevice),
142 DECL(alcGetError),
143 DECL(alcIsExtensionPresent),
144 DECL(alcGetProcAddress),
145 DECL(alcGetEnumValue),
146 DECL(alcGetString),
147 DECL(alcGetIntegerv),
148 DECL(alcCaptureOpenDevice),
149 DECL(alcCaptureCloseDevice),
150 DECL(alcCaptureStart),
151 DECL(alcCaptureStop),
152 DECL(alcCaptureSamples),
154 DECL(alcSetThreadContext),
155 DECL(alcGetThreadContext),
157 DECL(alcLoopbackOpenDeviceSOFT),
158 DECL(alcIsRenderFormatSupportedSOFT),
159 DECL(alcRenderSamplesSOFT),
161 DECL(alcDevicePauseSOFT),
162 DECL(alcDeviceResumeSOFT),
164 DECL(alcGetStringiSOFT),
165 DECL(alcResetDeviceSOFT),
167 DECL(alcGetInteger64vSOFT),
169 DECL(alEnable),
170 DECL(alDisable),
171 DECL(alIsEnabled),
172 DECL(alGetString),
173 DECL(alGetBooleanv),
174 DECL(alGetIntegerv),
175 DECL(alGetFloatv),
176 DECL(alGetDoublev),
177 DECL(alGetBoolean),
178 DECL(alGetInteger),
179 DECL(alGetFloat),
180 DECL(alGetDouble),
181 DECL(alGetError),
182 DECL(alIsExtensionPresent),
183 DECL(alGetProcAddress),
184 DECL(alGetEnumValue),
185 DECL(alListenerf),
186 DECL(alListener3f),
187 DECL(alListenerfv),
188 DECL(alListeneri),
189 DECL(alListener3i),
190 DECL(alListeneriv),
191 DECL(alGetListenerf),
192 DECL(alGetListener3f),
193 DECL(alGetListenerfv),
194 DECL(alGetListeneri),
195 DECL(alGetListener3i),
196 DECL(alGetListeneriv),
197 DECL(alGenSources),
198 DECL(alDeleteSources),
199 DECL(alIsSource),
200 DECL(alSourcef),
201 DECL(alSource3f),
202 DECL(alSourcefv),
203 DECL(alSourcei),
204 DECL(alSource3i),
205 DECL(alSourceiv),
206 DECL(alGetSourcef),
207 DECL(alGetSource3f),
208 DECL(alGetSourcefv),
209 DECL(alGetSourcei),
210 DECL(alGetSource3i),
211 DECL(alGetSourceiv),
212 DECL(alSourcePlayv),
213 DECL(alSourceStopv),
214 DECL(alSourceRewindv),
215 DECL(alSourcePausev),
216 DECL(alSourcePlay),
217 DECL(alSourceStop),
218 DECL(alSourceRewind),
219 DECL(alSourcePause),
220 DECL(alSourceQueueBuffers),
221 DECL(alSourceUnqueueBuffers),
222 DECL(alGenBuffers),
223 DECL(alDeleteBuffers),
224 DECL(alIsBuffer),
225 DECL(alBufferData),
226 DECL(alBufferf),
227 DECL(alBuffer3f),
228 DECL(alBufferfv),
229 DECL(alBufferi),
230 DECL(alBuffer3i),
231 DECL(alBufferiv),
232 DECL(alGetBufferf),
233 DECL(alGetBuffer3f),
234 DECL(alGetBufferfv),
235 DECL(alGetBufferi),
236 DECL(alGetBuffer3i),
237 DECL(alGetBufferiv),
238 DECL(alDopplerFactor),
239 DECL(alDopplerVelocity),
240 DECL(alSpeedOfSound),
241 DECL(alDistanceModel),
243 DECL(alGenFilters),
244 DECL(alDeleteFilters),
245 DECL(alIsFilter),
246 DECL(alFilteri),
247 DECL(alFilteriv),
248 DECL(alFilterf),
249 DECL(alFilterfv),
250 DECL(alGetFilteri),
251 DECL(alGetFilteriv),
252 DECL(alGetFilterf),
253 DECL(alGetFilterfv),
254 DECL(alGenEffects),
255 DECL(alDeleteEffects),
256 DECL(alIsEffect),
257 DECL(alEffecti),
258 DECL(alEffectiv),
259 DECL(alEffectf),
260 DECL(alEffectfv),
261 DECL(alGetEffecti),
262 DECL(alGetEffectiv),
263 DECL(alGetEffectf),
264 DECL(alGetEffectfv),
265 DECL(alGenAuxiliaryEffectSlots),
266 DECL(alDeleteAuxiliaryEffectSlots),
267 DECL(alIsAuxiliaryEffectSlot),
268 DECL(alAuxiliaryEffectSloti),
269 DECL(alAuxiliaryEffectSlotiv),
270 DECL(alAuxiliaryEffectSlotf),
271 DECL(alAuxiliaryEffectSlotfv),
272 DECL(alGetAuxiliaryEffectSloti),
273 DECL(alGetAuxiliaryEffectSlotiv),
274 DECL(alGetAuxiliaryEffectSlotf),
275 DECL(alGetAuxiliaryEffectSlotfv),
277 DECL(alBufferSubDataSOFT),
279 DECL(alBufferSamplesSOFT),
280 DECL(alBufferSubSamplesSOFT),
281 DECL(alGetBufferSamplesSOFT),
282 DECL(alIsBufferFormatSupportedSOFT),
284 DECL(alDeferUpdatesSOFT),
285 DECL(alProcessUpdatesSOFT),
287 DECL(alSourcedSOFT),
288 DECL(alSource3dSOFT),
289 DECL(alSourcedvSOFT),
290 DECL(alGetSourcedSOFT),
291 DECL(alGetSource3dSOFT),
292 DECL(alGetSourcedvSOFT),
293 DECL(alSourcei64SOFT),
294 DECL(alSource3i64SOFT),
295 DECL(alSourcei64vSOFT),
296 DECL(alGetSourcei64SOFT),
297 DECL(alGetSource3i64SOFT),
298 DECL(alGetSourcei64vSOFT),
300 { NULL, NULL }
302 #undef DECL
304 #define DECL(x) { #x, (x) }
305 static const ALCenums enumeration[] = {
306 DECL(ALC_INVALID),
307 DECL(ALC_FALSE),
308 DECL(ALC_TRUE),
310 DECL(ALC_MAJOR_VERSION),
311 DECL(ALC_MINOR_VERSION),
312 DECL(ALC_ATTRIBUTES_SIZE),
313 DECL(ALC_ALL_ATTRIBUTES),
314 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
315 DECL(ALC_DEVICE_SPECIFIER),
316 DECL(ALC_ALL_DEVICES_SPECIFIER),
317 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
318 DECL(ALC_EXTENSIONS),
319 DECL(ALC_FREQUENCY),
320 DECL(ALC_REFRESH),
321 DECL(ALC_SYNC),
322 DECL(ALC_MONO_SOURCES),
323 DECL(ALC_STEREO_SOURCES),
324 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
325 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
326 DECL(ALC_CAPTURE_SAMPLES),
327 DECL(ALC_CONNECTED),
329 DECL(ALC_EFX_MAJOR_VERSION),
330 DECL(ALC_EFX_MINOR_VERSION),
331 DECL(ALC_MAX_AUXILIARY_SENDS),
333 DECL(ALC_FORMAT_CHANNELS_SOFT),
334 DECL(ALC_FORMAT_TYPE_SOFT),
336 DECL(ALC_MONO_SOFT),
337 DECL(ALC_STEREO_SOFT),
338 DECL(ALC_QUAD_SOFT),
339 DECL(ALC_5POINT1_SOFT),
340 DECL(ALC_6POINT1_SOFT),
341 DECL(ALC_7POINT1_SOFT),
343 DECL(ALC_BYTE_SOFT),
344 DECL(ALC_UNSIGNED_BYTE_SOFT),
345 DECL(ALC_SHORT_SOFT),
346 DECL(ALC_UNSIGNED_SHORT_SOFT),
347 DECL(ALC_INT_SOFT),
348 DECL(ALC_UNSIGNED_INT_SOFT),
349 DECL(ALC_FLOAT_SOFT),
351 DECL(ALC_HRTF_SOFT),
352 DECL(ALC_DONT_CARE_SOFT),
353 DECL(ALC_HRTF_STATUS_SOFT),
354 DECL(ALC_HRTF_DISABLED_SOFT),
355 DECL(ALC_HRTF_ENABLED_SOFT),
356 DECL(ALC_HRTF_DENIED_SOFT),
357 DECL(ALC_HRTF_REQUIRED_SOFT),
358 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
359 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
360 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
361 DECL(ALC_HRTF_SPECIFIER_SOFT),
362 DECL(ALC_HRTF_ID_SOFT),
364 DECL(ALC_NO_ERROR),
365 DECL(ALC_INVALID_DEVICE),
366 DECL(ALC_INVALID_CONTEXT),
367 DECL(ALC_INVALID_ENUM),
368 DECL(ALC_INVALID_VALUE),
369 DECL(ALC_OUT_OF_MEMORY),
372 DECL(AL_INVALID),
373 DECL(AL_NONE),
374 DECL(AL_FALSE),
375 DECL(AL_TRUE),
377 DECL(AL_SOURCE_RELATIVE),
378 DECL(AL_CONE_INNER_ANGLE),
379 DECL(AL_CONE_OUTER_ANGLE),
380 DECL(AL_PITCH),
381 DECL(AL_POSITION),
382 DECL(AL_DIRECTION),
383 DECL(AL_VELOCITY),
384 DECL(AL_LOOPING),
385 DECL(AL_BUFFER),
386 DECL(AL_GAIN),
387 DECL(AL_MIN_GAIN),
388 DECL(AL_MAX_GAIN),
389 DECL(AL_ORIENTATION),
390 DECL(AL_REFERENCE_DISTANCE),
391 DECL(AL_ROLLOFF_FACTOR),
392 DECL(AL_CONE_OUTER_GAIN),
393 DECL(AL_MAX_DISTANCE),
394 DECL(AL_SEC_OFFSET),
395 DECL(AL_SAMPLE_OFFSET),
396 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
397 DECL(AL_BYTE_OFFSET),
398 DECL(AL_BYTE_RW_OFFSETS_SOFT),
399 DECL(AL_SOURCE_TYPE),
400 DECL(AL_STATIC),
401 DECL(AL_STREAMING),
402 DECL(AL_UNDETERMINED),
403 DECL(AL_METERS_PER_UNIT),
404 DECL(AL_LOOP_POINTS_SOFT),
405 DECL(AL_DIRECT_CHANNELS_SOFT),
407 DECL(AL_DIRECT_FILTER),
408 DECL(AL_AUXILIARY_SEND_FILTER),
409 DECL(AL_AIR_ABSORPTION_FACTOR),
410 DECL(AL_ROOM_ROLLOFF_FACTOR),
411 DECL(AL_CONE_OUTER_GAINHF),
412 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
413 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
414 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
416 DECL(AL_SOURCE_STATE),
417 DECL(AL_INITIAL),
418 DECL(AL_PLAYING),
419 DECL(AL_PAUSED),
420 DECL(AL_STOPPED),
422 DECL(AL_BUFFERS_QUEUED),
423 DECL(AL_BUFFERS_PROCESSED),
425 DECL(AL_FORMAT_MONO8),
426 DECL(AL_FORMAT_MONO16),
427 DECL(AL_FORMAT_MONO_FLOAT32),
428 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
429 DECL(AL_FORMAT_STEREO8),
430 DECL(AL_FORMAT_STEREO16),
431 DECL(AL_FORMAT_STEREO_FLOAT32),
432 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
433 DECL(AL_FORMAT_MONO_IMA4),
434 DECL(AL_FORMAT_STEREO_IMA4),
435 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
436 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
437 DECL(AL_FORMAT_QUAD8_LOKI),
438 DECL(AL_FORMAT_QUAD16_LOKI),
439 DECL(AL_FORMAT_QUAD8),
440 DECL(AL_FORMAT_QUAD16),
441 DECL(AL_FORMAT_QUAD32),
442 DECL(AL_FORMAT_51CHN8),
443 DECL(AL_FORMAT_51CHN16),
444 DECL(AL_FORMAT_51CHN32),
445 DECL(AL_FORMAT_61CHN8),
446 DECL(AL_FORMAT_61CHN16),
447 DECL(AL_FORMAT_61CHN32),
448 DECL(AL_FORMAT_71CHN8),
449 DECL(AL_FORMAT_71CHN16),
450 DECL(AL_FORMAT_71CHN32),
451 DECL(AL_FORMAT_REAR8),
452 DECL(AL_FORMAT_REAR16),
453 DECL(AL_FORMAT_REAR32),
454 DECL(AL_FORMAT_MONO_MULAW),
455 DECL(AL_FORMAT_MONO_MULAW_EXT),
456 DECL(AL_FORMAT_STEREO_MULAW),
457 DECL(AL_FORMAT_STEREO_MULAW_EXT),
458 DECL(AL_FORMAT_QUAD_MULAW),
459 DECL(AL_FORMAT_51CHN_MULAW),
460 DECL(AL_FORMAT_61CHN_MULAW),
461 DECL(AL_FORMAT_71CHN_MULAW),
462 DECL(AL_FORMAT_REAR_MULAW),
463 DECL(AL_FORMAT_MONO_ALAW_EXT),
464 DECL(AL_FORMAT_STEREO_ALAW_EXT),
466 DECL(AL_MONO8_SOFT),
467 DECL(AL_MONO16_SOFT),
468 DECL(AL_MONO32F_SOFT),
469 DECL(AL_STEREO8_SOFT),
470 DECL(AL_STEREO16_SOFT),
471 DECL(AL_STEREO32F_SOFT),
472 DECL(AL_QUAD8_SOFT),
473 DECL(AL_QUAD16_SOFT),
474 DECL(AL_QUAD32F_SOFT),
475 DECL(AL_REAR8_SOFT),
476 DECL(AL_REAR16_SOFT),
477 DECL(AL_REAR32F_SOFT),
478 DECL(AL_5POINT1_8_SOFT),
479 DECL(AL_5POINT1_16_SOFT),
480 DECL(AL_5POINT1_32F_SOFT),
481 DECL(AL_6POINT1_8_SOFT),
482 DECL(AL_6POINT1_16_SOFT),
483 DECL(AL_6POINT1_32F_SOFT),
484 DECL(AL_7POINT1_8_SOFT),
485 DECL(AL_7POINT1_16_SOFT),
486 DECL(AL_7POINT1_32F_SOFT),
487 DECL(AL_FORMAT_BFORMAT2D_8),
488 DECL(AL_FORMAT_BFORMAT2D_16),
489 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
490 DECL(AL_FORMAT_BFORMAT2D_MULAW),
491 DECL(AL_FORMAT_BFORMAT3D_8),
492 DECL(AL_FORMAT_BFORMAT3D_16),
493 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
494 DECL(AL_FORMAT_BFORMAT3D_MULAW),
496 DECL(AL_MONO_SOFT),
497 DECL(AL_STEREO_SOFT),
498 DECL(AL_QUAD_SOFT),
499 DECL(AL_REAR_SOFT),
500 DECL(AL_5POINT1_SOFT),
501 DECL(AL_6POINT1_SOFT),
502 DECL(AL_7POINT1_SOFT),
504 DECL(AL_BYTE_SOFT),
505 DECL(AL_UNSIGNED_BYTE_SOFT),
506 DECL(AL_SHORT_SOFT),
507 DECL(AL_UNSIGNED_SHORT_SOFT),
508 DECL(AL_INT_SOFT),
509 DECL(AL_UNSIGNED_INT_SOFT),
510 DECL(AL_FLOAT_SOFT),
511 DECL(AL_DOUBLE_SOFT),
512 DECL(AL_BYTE3_SOFT),
513 DECL(AL_UNSIGNED_BYTE3_SOFT),
515 DECL(AL_FREQUENCY),
516 DECL(AL_BITS),
517 DECL(AL_CHANNELS),
518 DECL(AL_SIZE),
519 DECL(AL_INTERNAL_FORMAT_SOFT),
520 DECL(AL_BYTE_LENGTH_SOFT),
521 DECL(AL_SAMPLE_LENGTH_SOFT),
522 DECL(AL_SEC_LENGTH_SOFT),
523 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
524 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
526 DECL(AL_UNUSED),
527 DECL(AL_PENDING),
528 DECL(AL_PROCESSED),
530 DECL(AL_NO_ERROR),
531 DECL(AL_INVALID_NAME),
532 DECL(AL_INVALID_ENUM),
533 DECL(AL_INVALID_VALUE),
534 DECL(AL_INVALID_OPERATION),
535 DECL(AL_OUT_OF_MEMORY),
537 DECL(AL_VENDOR),
538 DECL(AL_VERSION),
539 DECL(AL_RENDERER),
540 DECL(AL_EXTENSIONS),
542 DECL(AL_DOPPLER_FACTOR),
543 DECL(AL_DOPPLER_VELOCITY),
544 DECL(AL_DISTANCE_MODEL),
545 DECL(AL_SPEED_OF_SOUND),
546 DECL(AL_SOURCE_DISTANCE_MODEL),
547 DECL(AL_DEFERRED_UPDATES_SOFT),
549 DECL(AL_INVERSE_DISTANCE),
550 DECL(AL_INVERSE_DISTANCE_CLAMPED),
551 DECL(AL_LINEAR_DISTANCE),
552 DECL(AL_LINEAR_DISTANCE_CLAMPED),
553 DECL(AL_EXPONENT_DISTANCE),
554 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
556 DECL(AL_FILTER_TYPE),
557 DECL(AL_FILTER_NULL),
558 DECL(AL_FILTER_LOWPASS),
559 DECL(AL_FILTER_HIGHPASS),
560 DECL(AL_FILTER_BANDPASS),
562 DECL(AL_LOWPASS_GAIN),
563 DECL(AL_LOWPASS_GAINHF),
565 DECL(AL_HIGHPASS_GAIN),
566 DECL(AL_HIGHPASS_GAINLF),
568 DECL(AL_BANDPASS_GAIN),
569 DECL(AL_BANDPASS_GAINHF),
570 DECL(AL_BANDPASS_GAINLF),
572 DECL(AL_EFFECT_TYPE),
573 DECL(AL_EFFECT_NULL),
574 DECL(AL_EFFECT_REVERB),
575 DECL(AL_EFFECT_EAXREVERB),
576 DECL(AL_EFFECT_CHORUS),
577 DECL(AL_EFFECT_DISTORTION),
578 DECL(AL_EFFECT_ECHO),
579 DECL(AL_EFFECT_FLANGER),
580 #if 0
581 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
582 DECL(AL_EFFECT_VOCAL_MORPHER),
583 DECL(AL_EFFECT_PITCH_SHIFTER),
584 #endif
585 DECL(AL_EFFECT_RING_MODULATOR),
586 #if 0
587 DECL(AL_EFFECT_AUTOWAH),
588 #endif
589 DECL(AL_EFFECT_COMPRESSOR),
590 DECL(AL_EFFECT_EQUALIZER),
591 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
592 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
594 DECL(AL_EAXREVERB_DENSITY),
595 DECL(AL_EAXREVERB_DIFFUSION),
596 DECL(AL_EAXREVERB_GAIN),
597 DECL(AL_EAXREVERB_GAINHF),
598 DECL(AL_EAXREVERB_GAINLF),
599 DECL(AL_EAXREVERB_DECAY_TIME),
600 DECL(AL_EAXREVERB_DECAY_HFRATIO),
601 DECL(AL_EAXREVERB_DECAY_LFRATIO),
602 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
603 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
604 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
605 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
606 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
607 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
608 DECL(AL_EAXREVERB_ECHO_TIME),
609 DECL(AL_EAXREVERB_ECHO_DEPTH),
610 DECL(AL_EAXREVERB_MODULATION_TIME),
611 DECL(AL_EAXREVERB_MODULATION_DEPTH),
612 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
613 DECL(AL_EAXREVERB_HFREFERENCE),
614 DECL(AL_EAXREVERB_LFREFERENCE),
615 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
616 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
618 DECL(AL_REVERB_DENSITY),
619 DECL(AL_REVERB_DIFFUSION),
620 DECL(AL_REVERB_GAIN),
621 DECL(AL_REVERB_GAINHF),
622 DECL(AL_REVERB_DECAY_TIME),
623 DECL(AL_REVERB_DECAY_HFRATIO),
624 DECL(AL_REVERB_REFLECTIONS_GAIN),
625 DECL(AL_REVERB_REFLECTIONS_DELAY),
626 DECL(AL_REVERB_LATE_REVERB_GAIN),
627 DECL(AL_REVERB_LATE_REVERB_DELAY),
628 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
629 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
630 DECL(AL_REVERB_DECAY_HFLIMIT),
632 DECL(AL_CHORUS_WAVEFORM),
633 DECL(AL_CHORUS_PHASE),
634 DECL(AL_CHORUS_RATE),
635 DECL(AL_CHORUS_DEPTH),
636 DECL(AL_CHORUS_FEEDBACK),
637 DECL(AL_CHORUS_DELAY),
639 DECL(AL_DISTORTION_EDGE),
640 DECL(AL_DISTORTION_GAIN),
641 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
642 DECL(AL_DISTORTION_EQCENTER),
643 DECL(AL_DISTORTION_EQBANDWIDTH),
645 DECL(AL_ECHO_DELAY),
646 DECL(AL_ECHO_LRDELAY),
647 DECL(AL_ECHO_DAMPING),
648 DECL(AL_ECHO_FEEDBACK),
649 DECL(AL_ECHO_SPREAD),
651 DECL(AL_FLANGER_WAVEFORM),
652 DECL(AL_FLANGER_PHASE),
653 DECL(AL_FLANGER_RATE),
654 DECL(AL_FLANGER_DEPTH),
655 DECL(AL_FLANGER_FEEDBACK),
656 DECL(AL_FLANGER_DELAY),
658 DECL(AL_RING_MODULATOR_FREQUENCY),
659 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
660 DECL(AL_RING_MODULATOR_WAVEFORM),
662 #if 0
663 DECL(AL_AUTOWAH_ATTACK_TIME),
664 DECL(AL_AUTOWAH_PEAK_GAIN),
665 DECL(AL_AUTOWAH_RELEASE_TIME),
666 DECL(AL_AUTOWAH_RESONANCE),
667 #endif
669 DECL(AL_COMPRESSOR_ONOFF),
671 DECL(AL_EQUALIZER_LOW_GAIN),
672 DECL(AL_EQUALIZER_LOW_CUTOFF),
673 DECL(AL_EQUALIZER_MID1_GAIN),
674 DECL(AL_EQUALIZER_MID1_CENTER),
675 DECL(AL_EQUALIZER_MID1_WIDTH),
676 DECL(AL_EQUALIZER_MID2_GAIN),
677 DECL(AL_EQUALIZER_MID2_CENTER),
678 DECL(AL_EQUALIZER_MID2_WIDTH),
679 DECL(AL_EQUALIZER_HIGH_GAIN),
680 DECL(AL_EQUALIZER_HIGH_CUTOFF),
682 DECL(AL_DEDICATED_GAIN),
684 { NULL, (ALCenum)0 }
686 #undef DECL
688 static const ALCchar alcNoError[] = "No Error";
689 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
690 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
691 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
692 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
693 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
696 /************************************************
697 * Global variables
698 ************************************************/
700 /* Enumerated device names */
701 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
703 static al_string alcAllDevicesList;
704 static al_string alcCaptureDeviceList;
706 /* Default is always the first in the list */
707 static ALCchar *alcDefaultAllDevicesSpecifier;
708 static ALCchar *alcCaptureDefaultDeviceSpecifier;
710 /* Default context extensions */
711 static const ALchar alExtList[] =
712 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
713 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
714 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
715 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
716 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
717 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
718 "AL_SOFT_source_latency AL_SOFT_source_length";
720 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
722 /* Thread-local current context */
723 static altss_t LocalContext;
724 /* Process-wide current context */
725 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
727 /* Mixing thread piority level */
728 ALint RTPrioLevel;
730 FILE *LogFile;
731 #ifdef _DEBUG
732 enum LogLevel LogLevel = LogWarning;
733 #else
734 enum LogLevel LogLevel = LogError;
735 #endif
737 /* Flag to trap ALC device errors */
738 static ALCboolean TrapALCError = ALC_FALSE;
740 /* One-time configuration init control */
741 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
743 /* Default effect that applies to sources that don't have an effect on send 0 */
744 static ALeffect DefaultEffect;
746 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
747 * updates.
749 static ALCboolean SuspendDefers = ALC_TRUE;
752 /************************************************
753 * ALC information
754 ************************************************/
755 static const ALCchar alcNoDeviceExtList[] =
756 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
757 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
758 static const ALCchar alcExtensionList[] =
759 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
760 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
761 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
762 "ALC_SOFT_loopback ALC_SOFT_pause_device";
763 static const ALCint alcMajorVersion = 1;
764 static const ALCint alcMinorVersion = 1;
766 static const ALCint alcEFXMajorVersion = 1;
767 static const ALCint alcEFXMinorVersion = 0;
770 /************************************************
771 * Device lists
772 ************************************************/
773 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
775 static almtx_t ListLock;
776 static inline void LockLists(void)
778 int lockret = almtx_lock(&ListLock);
779 assert(lockret == althrd_success);
781 static inline void UnlockLists(void)
783 int unlockret = almtx_unlock(&ListLock);
784 assert(unlockret == althrd_success);
787 /************************************************
788 * Library initialization
789 ************************************************/
790 #if defined(_WIN32)
791 static void alc_init(void);
792 static void alc_deinit(void);
793 static void alc_deinit_safe(void);
795 #ifndef AL_LIBTYPE_STATIC
796 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
798 switch(reason)
800 case DLL_PROCESS_ATTACH:
801 /* Pin the DLL so we won't get unloaded until the process terminates */
802 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
803 (WCHAR*)hModule, &hModule);
804 alc_init();
805 break;
807 case DLL_THREAD_DETACH:
808 break;
810 case DLL_PROCESS_DETACH:
811 if(!lpReserved)
812 alc_deinit();
813 else
814 alc_deinit_safe();
815 break;
817 return TRUE;
819 #elif defined(_MSC_VER)
820 #pragma section(".CRT$XCU",read)
821 static void alc_constructor(void);
822 static void alc_destructor(void);
823 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
825 static void alc_constructor(void)
827 atexit(alc_destructor);
828 alc_init();
831 static void alc_destructor(void)
833 alc_deinit();
835 #elif defined(HAVE_GCC_DESTRUCTOR)
836 static void alc_init(void) __attribute__((constructor));
837 static void alc_deinit(void) __attribute__((destructor));
838 #else
839 #error "No static initialization available on this platform!"
840 #endif
842 #elif defined(HAVE_GCC_DESTRUCTOR)
844 static void alc_init(void) __attribute__((constructor));
845 static void alc_deinit(void) __attribute__((destructor));
847 #else
848 #error "No global initialization available on this platform!"
849 #endif
851 static void ReleaseThreadCtx(void *ptr);
852 static void alc_init(void)
854 const char *str;
855 int ret;
857 LogFile = stderr;
859 AL_STRING_INIT(alcAllDevicesList);
860 AL_STRING_INIT(alcCaptureDeviceList);
862 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
863 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
864 ConeScale *= 0.5f;
866 str = getenv("__ALSOFT_REVERSE_Z");
867 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
868 ZScale *= -1.0f;
870 ret = altss_create(&LocalContext, ReleaseThreadCtx);
871 assert(ret == althrd_success);
873 ret = almtx_init(&ListLock, almtx_recursive);
874 assert(ret == althrd_success);
876 ThunkInit();
879 static void alc_initconfig(void)
881 const char *devs, *str;
882 ALuint capfilter;
883 float valf;
884 int i, n;
886 str = getenv("ALSOFT_LOGLEVEL");
887 if(str)
889 long lvl = strtol(str, NULL, 0);
890 if(lvl >= NoLog && lvl <= LogRef)
891 LogLevel = lvl;
894 str = getenv("ALSOFT_LOGFILE");
895 if(str && str[0])
897 FILE *logfile = al_fopen(str, "wt");
898 if(logfile) LogFile = logfile;
899 else ERR("Failed to open log file '%s'\n", str);
903 char buf[1024] = "";
904 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
905 for(i = 1;BackendList[i].name;i++)
906 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
907 TRACE("Supported backends: %s\n", buf);
909 ReadALConfig();
911 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
912 if(str && *str)
914 if(strcasecmp(str, "ignore") == 0)
916 SuspendDefers = ALC_FALSE;
917 TRACE("Selected context suspend behavior, \"ignore\"\n");
919 else
920 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
923 capfilter = 0;
924 #if defined(HAVE_SSE4_1)
925 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
926 #elif defined(HAVE_SSE3)
927 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
928 #elif defined(HAVE_SSE2)
929 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
930 #elif defined(HAVE_SSE)
931 capfilter |= CPU_CAP_SSE;
932 #endif
933 #ifdef HAVE_NEON
934 capfilter |= CPU_CAP_NEON;
935 #endif
936 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
938 if(strcasecmp(str, "all") == 0)
939 capfilter = 0;
940 else
942 size_t len;
943 const char *next = str;
945 do {
946 str = next;
947 while(isspace(str[0]))
948 str++;
949 next = strchr(str, ',');
951 if(!str[0] || str[0] == ',')
952 continue;
954 len = (next ? ((size_t)(next-str)) : strlen(str));
955 while(len > 0 && isspace(str[len-1]))
956 len--;
957 if(len == 3 && strncasecmp(str, "sse", len) == 0)
958 capfilter &= ~CPU_CAP_SSE;
959 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
960 capfilter &= ~CPU_CAP_SSE2;
961 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
962 capfilter &= ~CPU_CAP_SSE3;
963 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
964 capfilter &= ~CPU_CAP_SSE4_1;
965 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
966 capfilter &= ~CPU_CAP_NEON;
967 else
968 WARN("Invalid CPU extension \"%s\"\n", str);
969 } while(next++);
972 FillCPUCaps(capfilter);
974 #ifdef _WIN32
975 RTPrioLevel = 1;
976 #else
977 RTPrioLevel = 0;
978 #endif
979 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
981 aluInitMixer();
983 str = getenv("ALSOFT_TRAP_ERROR");
984 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
986 TrapALError = AL_TRUE;
987 TrapALCError = AL_TRUE;
989 else
991 str = getenv("ALSOFT_TRAP_AL_ERROR");
992 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
993 TrapALError = AL_TRUE;
994 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
996 str = getenv("ALSOFT_TRAP_ALC_ERROR");
997 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
998 TrapALCError = ALC_TRUE;
999 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1002 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1003 ReverbBoost *= powf(10.0f, valf / 20.0f);
1005 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1007 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1008 ConfigValueStr(NULL, NULL, "drivers", &devs))
1010 int n;
1011 size_t len;
1012 const char *next = devs;
1013 int endlist, delitem;
1015 i = 0;
1016 do {
1017 devs = next;
1018 while(isspace(devs[0]))
1019 devs++;
1020 next = strchr(devs, ',');
1022 delitem = (devs[0] == '-');
1023 if(devs[0] == '-') devs++;
1025 if(!devs[0] || devs[0] == ',')
1027 endlist = 0;
1028 continue;
1030 endlist = 1;
1032 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1033 while(len > 0 && isspace(devs[len-1]))
1034 len--;
1035 for(n = i;BackendList[n].name;n++)
1037 if(len == strlen(BackendList[n].name) &&
1038 strncmp(BackendList[n].name, devs, len) == 0)
1040 if(delitem)
1042 do {
1043 BackendList[n] = BackendList[n+1];
1044 ++n;
1045 } while(BackendList[n].name);
1047 else
1049 struct BackendInfo Bkp = BackendList[n];
1050 while(n > i)
1052 BackendList[n] = BackendList[n-1];
1053 --n;
1055 BackendList[n] = Bkp;
1057 i++;
1059 break;
1062 } while(next++);
1064 if(endlist)
1066 BackendList[i].name = NULL;
1067 BackendList[i].getFactory = NULL;
1068 BackendList[i].Init = NULL;
1069 BackendList[i].Deinit = NULL;
1070 BackendList[i].Probe = NULL;
1074 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1076 if(BackendList[i].getFactory)
1078 ALCbackendFactory *factory = BackendList[i].getFactory();
1079 if(!V0(factory,init)())
1081 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1082 continue;
1085 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1086 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1088 PlaybackBackend = BackendList[i];
1089 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1091 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1093 CaptureBackend = BackendList[i];
1094 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1097 continue;
1100 if(!BackendList[i].Init(&BackendList[i].Funcs))
1102 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1103 continue;
1106 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1107 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1109 PlaybackBackend = BackendList[i];
1110 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1112 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1114 CaptureBackend = BackendList[i];
1115 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1119 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1120 V0(factory,init)();
1123 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1125 size_t len;
1126 const char *next = str;
1128 do {
1129 str = next;
1130 next = strchr(str, ',');
1132 if(!str[0] || next == str)
1133 continue;
1135 len = (next ? ((size_t)(next-str)) : strlen(str));
1136 for(n = 0;EffectList[n].name;n++)
1138 if(len == strlen(EffectList[n].name) &&
1139 strncmp(EffectList[n].name, str, len) == 0)
1140 DisabledEffects[EffectList[n].type] = AL_TRUE;
1142 } while(next++);
1145 InitEffectFactoryMap();
1147 InitEffect(&DefaultEffect);
1148 str = getenv("ALSOFT_DEFAULT_REVERB");
1149 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1150 LoadReverbPreset(str, &DefaultEffect);
1152 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1155 /************************************************
1156 * Library deinitialization
1157 ************************************************/
1158 static void alc_cleanup(void)
1160 ALCdevice *dev;
1162 AL_STRING_DEINIT(alcAllDevicesList);
1163 AL_STRING_DEINIT(alcCaptureDeviceList);
1165 free(alcDefaultAllDevicesSpecifier);
1166 alcDefaultAllDevicesSpecifier = NULL;
1167 free(alcCaptureDefaultDeviceSpecifier);
1168 alcCaptureDefaultDeviceSpecifier = NULL;
1170 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1172 ALCuint num = 0;
1173 do {
1174 num++;
1175 } while((dev=dev->next) != NULL);
1176 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1179 DeinitEffectFactoryMap();
1182 static void alc_deinit_safe(void)
1184 alc_cleanup();
1186 FreeHrtfs();
1187 FreeALConfig();
1189 ThunkExit();
1190 almtx_destroy(&ListLock);
1191 altss_delete(LocalContext);
1193 if(LogFile != stderr)
1194 fclose(LogFile);
1195 LogFile = NULL;
1198 static void alc_deinit(void)
1200 int i;
1202 alc_cleanup();
1204 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1205 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1207 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1209 if(!BackendList[i].getFactory)
1210 BackendList[i].Deinit();
1211 else
1213 ALCbackendFactory *factory = BackendList[i].getFactory();
1214 V0(factory,deinit)();
1218 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1219 V0(factory,deinit)();
1222 alc_deinit_safe();
1226 /************************************************
1227 * Device enumeration
1228 ************************************************/
1229 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1231 DO_INITCONFIG();
1233 LockLists();
1234 al_string_clear(list);
1236 if(!backendinfo->getFactory)
1237 backendinfo->Probe(type);
1238 else
1240 ALCbackendFactory *factory = backendinfo->getFactory();
1241 V(factory,probe)(type);
1244 UnlockLists();
1246 static void ProbeAllDevicesList(void)
1247 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1248 static void ProbeCaptureDeviceList(void)
1249 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1251 static void AppendDevice(const ALCchar *name, al_string *devnames)
1253 size_t len = strlen(name);
1254 if(len > 0)
1255 al_string_append_range(devnames, name, name+len+1);
1257 void AppendAllDevicesList(const ALCchar *name)
1258 { AppendDevice(name, &alcAllDevicesList); }
1259 void AppendCaptureDeviceList(const ALCchar *name)
1260 { AppendDevice(name, &alcCaptureDeviceList); }
1263 /************************************************
1264 * Device format information
1265 ************************************************/
1266 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1268 switch(type)
1270 case DevFmtByte: return "Signed Byte";
1271 case DevFmtUByte: return "Unsigned Byte";
1272 case DevFmtShort: return "Signed Short";
1273 case DevFmtUShort: return "Unsigned Short";
1274 case DevFmtInt: return "Signed Int";
1275 case DevFmtUInt: return "Unsigned Int";
1276 case DevFmtFloat: return "Float";
1278 return "(unknown type)";
1280 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1282 switch(chans)
1284 case DevFmtMono: return "Mono";
1285 case DevFmtStereo: return "Stereo";
1286 case DevFmtQuad: return "Quadraphonic";
1287 case DevFmtX51: return "5.1 Surround";
1288 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1289 case DevFmtX61: return "6.1 Surround";
1290 case DevFmtX71: return "7.1 Surround";
1291 case DevFmtBFormat3D: return "B-Format 3D";
1293 return "(unknown channels)";
1296 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1297 ALuint BytesFromDevFmt(enum DevFmtType type)
1299 switch(type)
1301 case DevFmtByte: return sizeof(ALbyte);
1302 case DevFmtUByte: return sizeof(ALubyte);
1303 case DevFmtShort: return sizeof(ALshort);
1304 case DevFmtUShort: return sizeof(ALushort);
1305 case DevFmtInt: return sizeof(ALint);
1306 case DevFmtUInt: return sizeof(ALuint);
1307 case DevFmtFloat: return sizeof(ALfloat);
1309 return 0;
1311 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1313 switch(chans)
1315 case DevFmtMono: return 1;
1316 case DevFmtStereo: return 2;
1317 case DevFmtQuad: return 4;
1318 case DevFmtX51: return 6;
1319 case DevFmtX51Rear: return 6;
1320 case DevFmtX61: return 7;
1321 case DevFmtX71: return 8;
1322 case DevFmtBFormat3D: return 4;
1324 return 0;
1327 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1328 enum DevFmtChannels *chans, enum DevFmtType *type)
1330 static const struct {
1331 ALenum format;
1332 enum DevFmtChannels channels;
1333 enum DevFmtType type;
1334 } list[] = {
1335 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1336 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1337 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1339 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1340 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1341 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1343 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1344 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1345 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1347 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1348 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1349 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1351 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1352 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1353 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1355 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1356 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1357 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1359 ALuint i;
1361 for(i = 0;i < COUNTOF(list);i++)
1363 if(list[i].format == format)
1365 *chans = list[i].channels;
1366 *type = list[i].type;
1367 return AL_TRUE;
1371 return AL_FALSE;
1374 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1376 switch(type)
1378 case ALC_BYTE_SOFT:
1379 case ALC_UNSIGNED_BYTE_SOFT:
1380 case ALC_SHORT_SOFT:
1381 case ALC_UNSIGNED_SHORT_SOFT:
1382 case ALC_INT_SOFT:
1383 case ALC_UNSIGNED_INT_SOFT:
1384 case ALC_FLOAT_SOFT:
1385 return ALC_TRUE;
1387 return ALC_FALSE;
1390 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1392 switch(channels)
1394 case ALC_MONO_SOFT:
1395 case ALC_STEREO_SOFT:
1396 case ALC_QUAD_SOFT:
1397 case ALC_5POINT1_SOFT:
1398 case ALC_6POINT1_SOFT:
1399 case ALC_7POINT1_SOFT:
1400 return ALC_TRUE;
1402 return ALC_FALSE;
1406 /************************************************
1407 * Miscellaneous ALC helpers
1408 ************************************************/
1409 enum HrtfRequestMode {
1410 Hrtf_Default = 0,
1411 Hrtf_Enable = 1,
1412 Hrtf_Disable = 2,
1415 extern inline void LockContext(ALCcontext *context);
1416 extern inline void UnlockContext(ALCcontext *context);
1418 void ALCdevice_Lock(ALCdevice *device)
1420 V0(device->Backend,lock)();
1423 void ALCdevice_Unlock(ALCdevice *device)
1425 V0(device->Backend,unlock)();
1429 /* SetDefaultWFXChannelOrder
1431 * Sets the default channel order used by WaveFormatEx.
1433 void SetDefaultWFXChannelOrder(ALCdevice *device)
1435 ALuint i;
1437 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1438 device->RealOut.ChannelName[i] = InvalidChannel;
1440 switch(device->FmtChans)
1442 case DevFmtMono:
1443 device->RealOut.ChannelName[0] = FrontCenter;
1444 break;
1445 case DevFmtStereo:
1446 device->RealOut.ChannelName[0] = FrontLeft;
1447 device->RealOut.ChannelName[1] = FrontRight;
1448 break;
1449 case DevFmtQuad:
1450 device->RealOut.ChannelName[0] = FrontLeft;
1451 device->RealOut.ChannelName[1] = FrontRight;
1452 device->RealOut.ChannelName[2] = BackLeft;
1453 device->RealOut.ChannelName[3] = BackRight;
1454 break;
1455 case DevFmtX51:
1456 device->RealOut.ChannelName[0] = FrontLeft;
1457 device->RealOut.ChannelName[1] = FrontRight;
1458 device->RealOut.ChannelName[2] = FrontCenter;
1459 device->RealOut.ChannelName[3] = LFE;
1460 device->RealOut.ChannelName[4] = SideLeft;
1461 device->RealOut.ChannelName[5] = SideRight;
1462 break;
1463 case DevFmtX51Rear:
1464 device->RealOut.ChannelName[0] = FrontLeft;
1465 device->RealOut.ChannelName[1] = FrontRight;
1466 device->RealOut.ChannelName[2] = FrontCenter;
1467 device->RealOut.ChannelName[3] = LFE;
1468 device->RealOut.ChannelName[4] = BackLeft;
1469 device->RealOut.ChannelName[5] = BackRight;
1470 break;
1471 case DevFmtX61:
1472 device->RealOut.ChannelName[0] = FrontLeft;
1473 device->RealOut.ChannelName[1] = FrontRight;
1474 device->RealOut.ChannelName[2] = FrontCenter;
1475 device->RealOut.ChannelName[3] = LFE;
1476 device->RealOut.ChannelName[4] = BackCenter;
1477 device->RealOut.ChannelName[5] = SideLeft;
1478 device->RealOut.ChannelName[6] = SideRight;
1479 break;
1480 case DevFmtX71:
1481 device->RealOut.ChannelName[0] = FrontLeft;
1482 device->RealOut.ChannelName[1] = FrontRight;
1483 device->RealOut.ChannelName[2] = FrontCenter;
1484 device->RealOut.ChannelName[3] = LFE;
1485 device->RealOut.ChannelName[4] = BackLeft;
1486 device->RealOut.ChannelName[5] = BackRight;
1487 device->RealOut.ChannelName[6] = SideLeft;
1488 device->RealOut.ChannelName[7] = SideRight;
1489 break;
1490 case DevFmtBFormat3D:
1491 device->RealOut.ChannelName[0] = Aux0;
1492 device->RealOut.ChannelName[1] = Aux1;
1493 device->RealOut.ChannelName[2] = Aux2;
1494 device->RealOut.ChannelName[3] = Aux3;
1495 break;
1499 /* SetDefaultChannelOrder
1501 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1503 void SetDefaultChannelOrder(ALCdevice *device)
1505 ALuint i;
1507 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1508 device->RealOut.ChannelName[i] = InvalidChannel;
1510 switch(device->FmtChans)
1512 case DevFmtX51Rear:
1513 device->RealOut.ChannelName[0] = FrontLeft;
1514 device->RealOut.ChannelName[1] = FrontRight;
1515 device->RealOut.ChannelName[2] = BackLeft;
1516 device->RealOut.ChannelName[3] = BackRight;
1517 device->RealOut.ChannelName[4] = FrontCenter;
1518 device->RealOut.ChannelName[5] = LFE;
1519 return;
1520 case DevFmtX71:
1521 device->RealOut.ChannelName[0] = FrontLeft;
1522 device->RealOut.ChannelName[1] = FrontRight;
1523 device->RealOut.ChannelName[2] = BackLeft;
1524 device->RealOut.ChannelName[3] = BackRight;
1525 device->RealOut.ChannelName[4] = FrontCenter;
1526 device->RealOut.ChannelName[5] = LFE;
1527 device->RealOut.ChannelName[6] = SideLeft;
1528 device->RealOut.ChannelName[7] = SideRight;
1529 return;
1531 /* Same as WFX order */
1532 case DevFmtMono:
1533 case DevFmtStereo:
1534 case DevFmtQuad:
1535 case DevFmtX51:
1536 case DevFmtX61:
1537 case DevFmtBFormat3D:
1538 SetDefaultWFXChannelOrder(device);
1539 break;
1543 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1546 /* ALCcontext_DeferUpdates
1548 * Defers/suspends updates for the given context's listener and sources. This
1549 * does *NOT* stop mixing, but rather prevents certain property changes from
1550 * taking effect.
1552 void ALCcontext_DeferUpdates(ALCcontext *context)
1554 ALCdevice *device = context->Device;
1555 FPUCtl oldMode;
1557 SetMixerFPUMode(&oldMode);
1559 V0(device->Backend,lock)();
1560 if(!context->DeferUpdates)
1562 context->DeferUpdates = AL_TRUE;
1564 /* Make sure all pending updates are performed */
1565 UpdateContextSources(context);
1566 #define UPDATE_SLOT(iter) do { \
1567 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1568 V((*iter)->EffectState,update)(device, *iter); \
1569 } while(0)
1570 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1571 #undef UPDATE_SLOT
1573 V0(device->Backend,unlock)();
1575 RestoreFPUMode(&oldMode);
1578 /* ALCcontext_ProcessUpdates
1580 * Resumes update processing after being deferred.
1582 void ALCcontext_ProcessUpdates(ALCcontext *context)
1584 ALCdevice *device = context->Device;
1586 V0(device->Backend,lock)();
1587 if(context->DeferUpdates)
1589 ALsizei pos;
1591 context->DeferUpdates = AL_FALSE;
1593 LockUIntMapRead(&context->SourceMap);
1594 for(pos = 0;pos < context->SourceMap.size;pos++)
1596 ALsource *Source = context->SourceMap.array[pos].value;
1597 ALenum new_state;
1599 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1600 Source->Offset >= 0.0)
1602 WriteLock(&Source->queue_lock);
1603 ApplyOffset(Source);
1604 WriteUnlock(&Source->queue_lock);
1607 new_state = Source->new_state;
1608 Source->new_state = AL_NONE;
1609 if(new_state)
1610 SetSourceState(Source, context, new_state);
1612 UnlockUIntMapRead(&context->SourceMap);
1614 V0(device->Backend,unlock)();
1618 /* alcSetError
1620 * Stores the latest ALC device error
1622 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1624 if(TrapALCError)
1626 #ifdef _WIN32
1627 /* DebugBreak() will cause an exception if there is no debugger */
1628 if(IsDebuggerPresent())
1629 DebugBreak();
1630 #elif defined(SIGTRAP)
1631 raise(SIGTRAP);
1632 #endif
1635 if(device)
1636 ATOMIC_STORE(&device->LastError, errorCode);
1637 else
1638 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1642 /* UpdateClockBase
1644 * Updates the device's base clock time with however many samples have been
1645 * done. This is used so frequency changes on the device don't cause the time
1646 * to jump forward or back.
1648 static inline void UpdateClockBase(ALCdevice *device)
1650 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1651 device->SamplesDone = 0;
1654 /* UpdateDeviceParams
1656 * Updates device parameters according to the attribute list (caller is
1657 * responsible for holding the list lock).
1659 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1661 ALCcontext *context;
1662 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1663 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1664 enum DevFmtChannels oldChans;
1665 enum DevFmtType oldType;
1666 ALCuint oldFreq;
1667 FPUCtl oldMode;
1668 ALCsizei hrtf_id = -1;
1669 size_t size;
1671 // Check for attributes
1672 if(device->Type == Loopback)
1674 enum {
1675 GotFreq = 1<<0,
1676 GotChans = 1<<1,
1677 GotType = 1<<2,
1678 GotAll = GotFreq|GotChans|GotType
1680 ALCuint freq, numMono, numStereo, numSends;
1681 enum DevFmtChannels schans;
1682 enum DevFmtType stype;
1683 ALCuint attrIdx = 0;
1684 ALCint gotFmt = 0;
1686 if(!attrList)
1688 WARN("Missing attributes for loopback device\n");
1689 return ALC_INVALID_VALUE;
1692 numMono = device->NumMonoSources;
1693 numStereo = device->NumStereoSources;
1694 numSends = device->NumAuxSends;
1695 schans = device->FmtChans;
1696 stype = device->FmtType;
1697 freq = device->Frequency;
1699 while(attrList[attrIdx])
1701 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1703 ALCint val = attrList[attrIdx + 1];
1704 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1705 return ALC_INVALID_VALUE;
1706 schans = val;
1707 gotFmt |= GotChans;
1710 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1712 ALCint val = attrList[attrIdx + 1];
1713 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1714 return ALC_INVALID_VALUE;
1715 stype = val;
1716 gotFmt |= GotType;
1719 if(attrList[attrIdx] == ALC_FREQUENCY)
1721 freq = attrList[attrIdx + 1];
1722 if(freq < MIN_OUTPUT_RATE)
1723 return ALC_INVALID_VALUE;
1724 gotFmt |= GotFreq;
1727 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1729 numStereo = attrList[attrIdx + 1];
1730 if(numStereo > device->MaxNoOfSources)
1731 numStereo = device->MaxNoOfSources;
1733 numMono = device->MaxNoOfSources - numStereo;
1736 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1737 numSends = attrList[attrIdx + 1];
1739 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1741 if(attrList[attrIdx + 1] == ALC_FALSE)
1742 hrtf_appreq = Hrtf_Disable;
1743 else if(attrList[attrIdx + 1] == ALC_TRUE)
1744 hrtf_appreq = Hrtf_Enable;
1745 else
1746 hrtf_appreq = Hrtf_Default;
1749 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1750 hrtf_id = attrList[attrIdx + 1];
1752 attrIdx += 2;
1755 if(gotFmt != GotAll)
1757 WARN("Missing format for loopback device\n");
1758 return ALC_INVALID_VALUE;
1761 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1762 numSends = minu(MAX_SENDS, numSends);
1764 if((device->Flags&DEVICE_RUNNING))
1765 V0(device->Backend,stop)();
1766 device->Flags &= ~DEVICE_RUNNING;
1768 UpdateClockBase(device);
1770 device->Frequency = freq;
1771 device->FmtChans = schans;
1772 device->FmtType = stype;
1773 device->NumMonoSources = numMono;
1774 device->NumStereoSources = numStereo;
1775 device->NumAuxSends = numSends;
1777 else if(attrList && attrList[0])
1779 ALCuint freq, numMono, numStereo, numSends;
1780 ALCuint attrIdx = 0;
1782 /* If a context is already running on the device, stop playback so the
1783 * device attributes can be updated. */
1784 if((device->Flags&DEVICE_RUNNING))
1785 V0(device->Backend,stop)();
1786 device->Flags &= ~DEVICE_RUNNING;
1788 freq = device->Frequency;
1789 numMono = device->NumMonoSources;
1790 numStereo = device->NumStereoSources;
1791 numSends = device->NumAuxSends;
1793 while(attrList[attrIdx])
1795 if(attrList[attrIdx] == ALC_FREQUENCY)
1797 freq = attrList[attrIdx + 1];
1798 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1801 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1803 numStereo = attrList[attrIdx + 1];
1804 if(numStereo > device->MaxNoOfSources)
1805 numStereo = device->MaxNoOfSources;
1807 numMono = device->MaxNoOfSources - numStereo;
1810 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1811 numSends = attrList[attrIdx + 1];
1813 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1815 if(attrList[attrIdx + 1] == ALC_FALSE)
1816 hrtf_appreq = Hrtf_Disable;
1817 else if(attrList[attrIdx + 1] == ALC_TRUE)
1818 hrtf_appreq = Hrtf_Enable;
1819 else
1820 hrtf_appreq = Hrtf_Default;
1823 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1824 hrtf_id = attrList[attrIdx + 1];
1826 attrIdx += 2;
1829 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1830 freq = maxu(freq, MIN_OUTPUT_RATE);
1832 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1833 numSends = minu(MAX_SENDS, numSends);
1835 UpdateClockBase(device);
1837 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1838 device->Frequency;
1839 /* SSE and Neon do best with the update size being a multiple of 4 */
1840 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1841 device->UpdateSize = (device->UpdateSize+3)&~3;
1843 device->Frequency = freq;
1844 device->NumMonoSources = numMono;
1845 device->NumStereoSources = numStereo;
1846 device->NumAuxSends = numSends;
1849 if((device->Flags&DEVICE_RUNNING))
1850 return ALC_NO_ERROR;
1852 al_free(device->Uhj_Encoder);
1853 device->Uhj_Encoder = NULL;
1855 al_free(device->Bs2b);
1856 device->Bs2b = NULL;
1858 al_free(device->Dry.Buffer);
1859 device->Dry.Buffer = NULL;
1860 device->Dry.NumChannels = 0;
1861 device->VirtOut.Buffer = NULL;
1862 device->VirtOut.NumChannels = 0;
1863 device->RealOut.Buffer = NULL;
1864 device->RealOut.NumChannels = 0;
1866 UpdateClockBase(device);
1868 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1869 if(device->Type != Loopback)
1871 const char *hrtf;
1872 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1874 if(strcasecmp(hrtf, "true") == 0)
1875 hrtf_userreq = Hrtf_Enable;
1876 else if(strcasecmp(hrtf, "false") == 0)
1877 hrtf_userreq = Hrtf_Disable;
1878 else if(strcasecmp(hrtf, "auto") != 0)
1879 ERR("Unexpected hrtf value: %s\n", hrtf);
1882 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1884 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1886 VECTOR_DEINIT(device->Hrtf_List);
1887 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1889 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1891 device->FmtChans = DevFmtStereo;
1892 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1893 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1894 else
1895 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1896 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1898 else
1900 hrtf_userreq = hrtf_appreq = Hrtf_Default;
1901 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1905 else if(hrtf_appreq == Hrtf_Enable)
1907 size_t i;
1908 /* Loopback device. We don't need to match to a specific HRTF entry
1909 * here. If the requested ID matches, we'll pick that later, if not,
1910 * we'll try to auto-select one anyway. */
1911 if(device->FmtChans != DevFmtStereo)
1912 i = VECTOR_SIZE(device->Hrtf_List);
1913 else
1915 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1917 VECTOR_DEINIT(device->Hrtf_List);
1918 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1920 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1922 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1923 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1924 break;
1927 if(i == VECTOR_SIZE(device->Hrtf_List))
1929 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1930 DevFmtChannelsString(device->FmtChans), device->Frequency);
1931 hrtf_appreq = Hrtf_Default;
1932 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1936 oldFreq = device->Frequency;
1937 oldChans = device->FmtChans;
1938 oldType = device->FmtType;
1940 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1941 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1942 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1943 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1944 device->UpdateSize, device->NumUpdates
1947 if(V0(device->Backend,reset)() == ALC_FALSE)
1948 return ALC_INVALID_DEVICE;
1950 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1952 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1953 DevFmtChannelsString(device->FmtChans));
1954 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1956 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1958 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1959 DevFmtTypeString(device->FmtType));
1960 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1962 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1964 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1965 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1968 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1969 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1970 device->Frequency, device->UpdateSize, device->NumUpdates
1973 if((device->UpdateSize&3) != 0)
1975 if((CPUCapFlags&CPU_CAP_SSE))
1976 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1977 if((CPUCapFlags&CPU_CAP_NEON))
1978 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1981 device->Hrtf = NULL;
1982 al_string_clear(&device->Hrtf_Name);
1983 device->Render_Mode = NormalRender;
1984 if(device->FmtChans != DevFmtStereo)
1986 if(hrtf_appreq == Hrtf_Enable)
1987 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1989 else
1991 bool headphones = device->IsHeadphones;
1992 enum RenderMode render_mode = HrtfRender;
1993 ALCenum hrtf_status = device->Hrtf_Status;
1994 const char *mode;
1995 int bs2blevel;
1996 int usehrtf;
1998 if(device->Type != Loopback)
2000 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
2002 if(strcasecmp(mode, "headphones") == 0)
2003 headphones = true;
2004 else if(strcasecmp(mode, "speakers") == 0)
2005 headphones = false;
2006 else if(strcasecmp(mode, "auto") != 0)
2007 ERR("Unexpected stereo-mode: %s\n", mode);
2010 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
2012 if(strcasecmp(mode, "full") == 0)
2013 render_mode = HrtfRender;
2014 else if(strcasecmp(mode, "basic") == 0)
2015 render_mode = NormalRender;
2016 else
2017 ERR("Unexpected hrtf-mode: %s\n", mode);
2022 if(hrtf_userreq == Hrtf_Default)
2024 usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
2025 (hrtf_appreq == Hrtf_Enable);
2026 if(headphones && hrtf_appreq != Hrtf_Disable)
2027 hrtf_status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
2028 else if(usehrtf)
2029 hrtf_status = ALC_HRTF_ENABLED_SOFT;
2031 else
2033 usehrtf = (hrtf_userreq == Hrtf_Enable);
2034 if(!usehrtf)
2035 hrtf_status = ALC_HRTF_DENIED_SOFT;
2036 else
2037 hrtf_status = ALC_HRTF_REQUIRED_SOFT;
2040 if(!usehrtf)
2041 device->Hrtf_Status = hrtf_status;
2042 else
2044 size_t i;
2046 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2047 if(VECTOR_SIZE(device->Hrtf_List) == 0)
2049 VECTOR_DEINIT(device->Hrtf_List);
2050 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2053 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
2055 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, hrtf_id);
2056 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2058 device->Hrtf = entry->hrtf;
2059 al_string_copy(&device->Hrtf_Name, entry->name);
2062 if(!device->Hrtf)
2064 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
2066 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
2067 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2069 device->Hrtf = entry->hrtf;
2070 al_string_copy(&device->Hrtf_Name, entry->name);
2071 break;
2076 if(device->Hrtf)
2078 device->Hrtf_Status = hrtf_status;
2079 device->Render_Mode = render_mode;
2080 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
2082 else
2084 TRACE("HRTF disabled\n");
2086 bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
2087 (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
2088 if(device->Type != Loopback)
2089 ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
2090 if(bs2blevel > 0 && bs2blevel <= 6)
2092 device->Bs2b = al_calloc(16, sizeof(*device->Bs2b));
2093 bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
2094 device->Render_Mode = StereoPair;
2095 TRACE("BS2B enabled\n");
2097 else
2099 TRACE("BS2B disabled\n");
2101 render_mode = NormalRender;
2102 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-panning", &mode))
2104 if(strcasecmp(mode, "paired") == 0)
2105 render_mode = StereoPair;
2106 else if(strcasecmp(mode, "uhj") != 0)
2107 ERR("Unexpected stereo-panning: %s\n", mode);
2109 device->Render_Mode = render_mode;
2110 if(render_mode == NormalRender)
2112 device->Uhj_Encoder = al_calloc(16, sizeof(Uhj2Encoder));
2113 TRACE("UHJ enabled\n");
2115 else
2116 TRACE("UHJ disabled\n");
2121 if(!device->Hrtf && !device->Uhj_Encoder &&
2122 GetConfigValueBool(al_string_get_cstr(device->DeviceName), "decoder", "hq-mode", 1))
2124 if(!device->AmbiDecoder)
2125 device->AmbiDecoder = bformatdec_alloc();
2127 else
2129 bformatdec_free(device->AmbiDecoder);
2130 device->AmbiDecoder = NULL;
2132 aluInitPanning(device);
2134 /* Allocate extra channels for any post-filter output. */
2135 size = device->Dry.NumChannels * sizeof(device->Dry.Buffer[0]);
2136 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2137 size += (ChannelsFromDevFmt(device->FmtChans)+4) * sizeof(device->Dry.Buffer[0]);
2138 else if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2139 size += ChannelsFromDevFmt(device->FmtChans) * sizeof(device->Dry.Buffer[0]);
2140 device->Dry.Buffer = al_calloc(16, size);
2141 if(!device->Dry.Buffer)
2143 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2144 return ALC_INVALID_DEVICE;
2147 if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2149 device->VirtOut.Buffer = device->Dry.Buffer;
2150 device->VirtOut.NumChannels = device->Dry.NumChannels;
2151 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2152 device->RealOut.NumChannels = ChannelsFromDevFmt(device->FmtChans);
2154 else
2156 device->VirtOut.Buffer = NULL;
2157 device->VirtOut.NumChannels = 0;
2158 device->RealOut.Buffer = device->Dry.Buffer;
2159 device->RealOut.NumChannels = device->Dry.NumChannels;
2162 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2164 /* Higher-order high quality decoding requires upsampling first-order
2165 * content, so make sure to mix it separately.
2167 device->FOAOut.Buffer = device->RealOut.Buffer + device->RealOut.NumChannels;
2168 device->FOAOut.NumChannels = 4;
2170 else
2172 device->FOAOut.Buffer = device->Dry.Buffer;
2173 device->FOAOut.NumChannels = device->Dry.NumChannels;
2174 memcpy(device->FOAOut.AmbiCoeffs, device->Dry.AmbiCoeffs,
2175 sizeof(device->FOAOut.AmbiCoeffs));
2178 SetMixerFPUMode(&oldMode);
2179 V0(device->Backend,lock)();
2180 context = ATOMIC_LOAD(&device->ContextList);
2181 while(context)
2183 ALsizei pos;
2185 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2186 LockUIntMapRead(&context->EffectSlotMap);
2187 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2189 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2191 slot->EffectState->OutBuffer = device->Dry.Buffer;
2192 slot->EffectState->OutChannels = device->Dry.NumChannels;
2193 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2195 UnlockUIntMapRead(&context->EffectSlotMap);
2196 V0(device->Backend,unlock)();
2197 RestoreFPUMode(&oldMode);
2198 return ALC_INVALID_DEVICE;
2200 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2201 V(slot->EffectState,update)(device, slot);
2203 UnlockUIntMapRead(&context->EffectSlotMap);
2205 LockUIntMapRead(&context->SourceMap);
2206 for(pos = 0;pos < context->SourceMap.size;pos++)
2208 ALsource *source = context->SourceMap.array[pos].value;
2209 ALuint s = device->NumAuxSends;
2210 while(s < MAX_SENDS)
2212 if(source->Send[s].Slot)
2213 DecrementRef(&source->Send[s].Slot->ref);
2214 source->Send[s].Slot = NULL;
2215 source->Send[s].Gain = 1.0f;
2216 source->Send[s].GainHF = 1.0f;
2217 s++;
2219 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2221 UnlockUIntMapRead(&context->SourceMap);
2223 for(pos = 0;pos < context->VoiceCount;pos++)
2225 ALvoice *voice = &context->Voices[pos];
2226 ALsource *source = voice->Source;
2228 if(source)
2230 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2231 voice->Update(voice, source, context);
2235 context = context->next;
2237 if(device->DefaultSlot)
2239 ALeffectslot *slot = device->DefaultSlot;
2240 ALeffectState *state = slot->EffectState;
2242 state->OutBuffer = device->Dry.Buffer;
2243 state->OutChannels = device->Dry.NumChannels;
2244 if(V(state,deviceUpdate)(device) == AL_FALSE)
2246 V0(device->Backend,unlock)();
2247 RestoreFPUMode(&oldMode);
2248 return ALC_INVALID_DEVICE;
2250 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2251 V(slot->EffectState,update)(device, slot);
2253 V0(device->Backend,unlock)();
2254 RestoreFPUMode(&oldMode);
2256 if(!(device->Flags&DEVICE_PAUSED))
2258 if(V0(device->Backend,start)() == ALC_FALSE)
2259 return ALC_INVALID_DEVICE;
2260 device->Flags |= DEVICE_RUNNING;
2263 return ALC_NO_ERROR;
2266 /* FreeDevice
2268 * Frees the device structure, and destroys any objects the app failed to
2269 * delete. Called once there's no more references on the device.
2271 static ALCvoid FreeDevice(ALCdevice *device)
2273 TRACE("%p\n", device);
2275 V0(device->Backend,close)();
2276 DELETE_OBJ(device->Backend);
2277 device->Backend = NULL;
2279 if(device->DefaultSlot)
2281 ALeffectState *state = device->DefaultSlot->EffectState;
2282 device->DefaultSlot = NULL;
2283 DELETE_OBJ(state);
2286 if(device->BufferMap.size > 0)
2288 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2289 ReleaseALBuffers(device);
2291 ResetUIntMap(&device->BufferMap);
2293 if(device->EffectMap.size > 0)
2295 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2296 ReleaseALEffects(device);
2298 ResetUIntMap(&device->EffectMap);
2300 if(device->FilterMap.size > 0)
2302 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2303 ReleaseALFilters(device);
2305 ResetUIntMap(&device->FilterMap);
2307 AL_STRING_DEINIT(device->Hrtf_Name);
2308 FreeHrtfList(&device->Hrtf_List);
2310 al_free(device->Bs2b);
2311 device->Bs2b = NULL;
2313 al_free(device->Uhj_Encoder);
2314 device->Uhj_Encoder = NULL;
2316 bformatdec_free(device->AmbiDecoder);
2317 device->AmbiDecoder = NULL;
2319 AL_STRING_DEINIT(device->DeviceName);
2321 al_free(device->Dry.Buffer);
2322 device->Dry.Buffer = NULL;
2323 device->Dry.NumChannels = 0;
2324 device->VirtOut.Buffer = NULL;
2325 device->VirtOut.NumChannels = 0;
2326 device->RealOut.Buffer = NULL;
2327 device->RealOut.NumChannels = 0;
2329 al_free(device);
2333 void ALCdevice_IncRef(ALCdevice *device)
2335 uint ref;
2336 ref = IncrementRef(&device->ref);
2337 TRACEREF("%p increasing refcount to %u\n", device, ref);
2340 void ALCdevice_DecRef(ALCdevice *device)
2342 uint ref;
2343 ref = DecrementRef(&device->ref);
2344 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2345 if(ref == 0) FreeDevice(device);
2348 /* VerifyDevice
2350 * Checks if the device handle is valid, and increments its ref count if so.
2352 static ALCboolean VerifyDevice(ALCdevice **device)
2354 ALCdevice *tmpDevice;
2356 LockLists();
2357 tmpDevice = ATOMIC_LOAD(&DeviceList);
2358 while(tmpDevice)
2360 if(tmpDevice == *device)
2362 ALCdevice_IncRef(tmpDevice);
2363 UnlockLists();
2364 return ALC_TRUE;
2366 tmpDevice = tmpDevice->next;
2368 UnlockLists();
2370 *device = NULL;
2371 return ALC_FALSE;
2375 /* InitContext
2377 * Initializes context fields
2379 static ALvoid InitContext(ALCcontext *Context)
2381 ALlistener *listener = Context->Listener;
2382 //Initialise listener
2383 listener->Gain = 1.0f;
2384 listener->MetersPerUnit = 1.0f;
2385 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2386 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2387 listener->Forward[0] = 0.0f;
2388 listener->Forward[1] = 0.0f;
2389 listener->Forward[2] = -1.0f;
2390 listener->Up[0] = 0.0f;
2391 listener->Up[1] = 1.0f;
2392 listener->Up[2] = 0.0f;
2393 aluMatrixdSet(&listener->Params.Matrix,
2394 1.0, 0.0, 0.0, 0.0,
2395 0.0, 1.0, 0.0, 0.0,
2396 0.0, 0.0, 1.0, 0.0,
2397 0.0, 0.0, 0.0, 1.0
2399 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2401 //Validate Context
2402 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2403 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2404 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2405 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2407 //Set globals
2408 Context->DistanceModel = DefaultDistanceModel;
2409 Context->SourceDistanceModel = AL_FALSE;
2410 Context->DopplerFactor = 1.0f;
2411 Context->DopplerVelocity = 1.0f;
2412 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2413 Context->DeferUpdates = AL_FALSE;
2415 Context->ExtensionList = alExtList;
2419 /* FreeContext
2421 * Cleans up the context, and destroys any remaining objects the app failed to
2422 * delete. Called once there's no more references on the context.
2424 static void FreeContext(ALCcontext *context)
2426 TRACE("%p\n", context);
2428 if(context->SourceMap.size > 0)
2430 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2431 ReleaseALSources(context);
2433 ResetUIntMap(&context->SourceMap);
2435 if(context->EffectSlotMap.size > 0)
2437 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2438 ReleaseALAuxiliaryEffectSlots(context);
2440 ResetUIntMap(&context->EffectSlotMap);
2442 al_free(context->Voices);
2443 context->Voices = NULL;
2444 context->VoiceCount = 0;
2445 context->MaxVoices = 0;
2447 VECTOR_DEINIT(context->ActiveAuxSlots);
2449 ALCdevice_DecRef(context->Device);
2450 context->Device = NULL;
2452 //Invalidate context
2453 memset(context, 0, sizeof(ALCcontext));
2454 al_free(context);
2457 /* ReleaseContext
2459 * Removes the context reference from the given device and removes it from
2460 * being current on the running thread or globally.
2462 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2464 ALCcontext *nextctx;
2465 ALCcontext *origctx;
2467 if(altss_get(LocalContext) == context)
2469 WARN("%p released while current on thread\n", context);
2470 altss_set(LocalContext, NULL);
2471 ALCcontext_DecRef(context);
2474 origctx = context;
2475 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2476 ALCcontext_DecRef(context);
2478 ALCdevice_Lock(device);
2479 origctx = context;
2480 nextctx = context->next;
2481 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2483 ALCcontext *list;
2484 do {
2485 list = origctx;
2486 origctx = context;
2487 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2489 ALCdevice_Unlock(device);
2491 ALCcontext_DecRef(context);
2494 void ALCcontext_IncRef(ALCcontext *context)
2496 uint ref;
2497 ref = IncrementRef(&context->ref);
2498 TRACEREF("%p increasing refcount to %u\n", context, ref);
2501 void ALCcontext_DecRef(ALCcontext *context)
2503 uint ref;
2504 ref = DecrementRef(&context->ref);
2505 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2506 if(ref == 0) FreeContext(context);
2509 static void ReleaseThreadCtx(void *ptr)
2511 WARN("%p current for thread being destroyed\n", ptr);
2512 ALCcontext_DecRef(ptr);
2515 /* VerifyContext
2517 * Checks that the given context is valid, and increments its reference count.
2519 static ALCboolean VerifyContext(ALCcontext **context)
2521 ALCdevice *dev;
2523 LockLists();
2524 dev = ATOMIC_LOAD(&DeviceList);
2525 while(dev)
2527 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2528 while(ctx)
2530 if(ctx == *context)
2532 ALCcontext_IncRef(ctx);
2533 UnlockLists();
2534 return ALC_TRUE;
2536 ctx = ctx->next;
2538 dev = dev->next;
2540 UnlockLists();
2542 *context = NULL;
2543 return ALC_FALSE;
2547 /* GetContextRef
2549 * Returns the currently active context for this thread, and adds a reference
2550 * without locking it.
2552 ALCcontext *GetContextRef(void)
2554 ALCcontext *context;
2556 context = altss_get(LocalContext);
2557 if(context)
2558 ALCcontext_IncRef(context);
2559 else
2561 LockLists();
2562 context = ATOMIC_LOAD(&GlobalContext);
2563 if(context)
2564 ALCcontext_IncRef(context);
2565 UnlockLists();
2568 return context;
2572 /************************************************
2573 * Standard ALC functions
2574 ************************************************/
2576 /* alcGetError
2578 * Return last ALC generated error code for the given device
2580 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2582 ALCenum errorCode;
2584 if(VerifyDevice(&device))
2586 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2587 ALCdevice_DecRef(device);
2589 else
2590 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2592 return errorCode;
2596 /* alcSuspendContext
2598 * Suspends updates for the given context
2600 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2602 if(!SuspendDefers)
2603 return;
2605 if(!VerifyContext(&context))
2606 alcSetError(NULL, ALC_INVALID_CONTEXT);
2607 else
2609 ALCcontext_DeferUpdates(context);
2610 ALCcontext_DecRef(context);
2614 /* alcProcessContext
2616 * Resumes processing updates for the given context
2618 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2620 if(!SuspendDefers)
2621 return;
2623 if(!VerifyContext(&context))
2624 alcSetError(NULL, ALC_INVALID_CONTEXT);
2625 else
2627 ALCcontext_ProcessUpdates(context);
2628 ALCcontext_DecRef(context);
2633 /* alcGetString
2635 * Returns information about the device, and error strings
2637 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2639 const ALCchar *value = NULL;
2641 switch(param)
2643 case ALC_NO_ERROR:
2644 value = alcNoError;
2645 break;
2647 case ALC_INVALID_ENUM:
2648 value = alcErrInvalidEnum;
2649 break;
2651 case ALC_INVALID_VALUE:
2652 value = alcErrInvalidValue;
2653 break;
2655 case ALC_INVALID_DEVICE:
2656 value = alcErrInvalidDevice;
2657 break;
2659 case ALC_INVALID_CONTEXT:
2660 value = alcErrInvalidContext;
2661 break;
2663 case ALC_OUT_OF_MEMORY:
2664 value = alcErrOutOfMemory;
2665 break;
2667 case ALC_DEVICE_SPECIFIER:
2668 value = alcDefaultName;
2669 break;
2671 case ALC_ALL_DEVICES_SPECIFIER:
2672 if(VerifyDevice(&Device))
2674 value = al_string_get_cstr(Device->DeviceName);
2675 ALCdevice_DecRef(Device);
2677 else
2679 ProbeAllDevicesList();
2680 value = al_string_get_cstr(alcAllDevicesList);
2682 break;
2684 case ALC_CAPTURE_DEVICE_SPECIFIER:
2685 if(VerifyDevice(&Device))
2687 value = al_string_get_cstr(Device->DeviceName);
2688 ALCdevice_DecRef(Device);
2690 else
2692 ProbeCaptureDeviceList();
2693 value = al_string_get_cstr(alcCaptureDeviceList);
2695 break;
2697 /* Default devices are always first in the list */
2698 case ALC_DEFAULT_DEVICE_SPECIFIER:
2699 value = alcDefaultName;
2700 break;
2702 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2703 if(al_string_empty(alcAllDevicesList))
2704 ProbeAllDevicesList();
2706 VerifyDevice(&Device);
2708 free(alcDefaultAllDevicesSpecifier);
2709 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2710 if(!alcDefaultAllDevicesSpecifier)
2711 alcSetError(Device, ALC_OUT_OF_MEMORY);
2713 value = alcDefaultAllDevicesSpecifier;
2714 if(Device) ALCdevice_DecRef(Device);
2715 break;
2717 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2718 if(al_string_empty(alcCaptureDeviceList))
2719 ProbeCaptureDeviceList();
2721 VerifyDevice(&Device);
2723 free(alcCaptureDefaultDeviceSpecifier);
2724 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2725 if(!alcCaptureDefaultDeviceSpecifier)
2726 alcSetError(Device, ALC_OUT_OF_MEMORY);
2728 value = alcCaptureDefaultDeviceSpecifier;
2729 if(Device) ALCdevice_DecRef(Device);
2730 break;
2732 case ALC_EXTENSIONS:
2733 if(!VerifyDevice(&Device))
2734 value = alcNoDeviceExtList;
2735 else
2737 value = alcExtensionList;
2738 ALCdevice_DecRef(Device);
2740 break;
2742 case ALC_HRTF_SPECIFIER_SOFT:
2743 if(!VerifyDevice(&Device))
2744 alcSetError(NULL, ALC_INVALID_DEVICE);
2745 else
2747 LockLists();
2748 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2749 UnlockLists();
2750 ALCdevice_DecRef(Device);
2752 break;
2754 default:
2755 VerifyDevice(&Device);
2756 alcSetError(Device, ALC_INVALID_ENUM);
2757 if(Device) ALCdevice_DecRef(Device);
2758 break;
2761 return value;
2765 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2767 ALCsizei i;
2769 if(size <= 0 || values == NULL)
2771 alcSetError(device, ALC_INVALID_VALUE);
2772 return 0;
2775 if(!device)
2777 switch(param)
2779 case ALC_MAJOR_VERSION:
2780 values[0] = alcMajorVersion;
2781 return 1;
2782 case ALC_MINOR_VERSION:
2783 values[0] = alcMinorVersion;
2784 return 1;
2786 case ALC_ATTRIBUTES_SIZE:
2787 case ALC_ALL_ATTRIBUTES:
2788 case ALC_FREQUENCY:
2789 case ALC_REFRESH:
2790 case ALC_SYNC:
2791 case ALC_MONO_SOURCES:
2792 case ALC_STEREO_SOURCES:
2793 case ALC_CAPTURE_SAMPLES:
2794 case ALC_FORMAT_CHANNELS_SOFT:
2795 case ALC_FORMAT_TYPE_SOFT:
2796 alcSetError(NULL, ALC_INVALID_DEVICE);
2797 return 0;
2799 default:
2800 alcSetError(NULL, ALC_INVALID_ENUM);
2801 return 0;
2803 return 0;
2806 if(device->Type == Capture)
2808 switch(param)
2810 case ALC_CAPTURE_SAMPLES:
2811 V0(device->Backend,lock)();
2812 values[0] = V0(device->Backend,availableSamples)();
2813 V0(device->Backend,unlock)();
2814 return 1;
2816 case ALC_CONNECTED:
2817 values[0] = device->Connected;
2818 return 1;
2820 default:
2821 alcSetError(device, ALC_INVALID_ENUM);
2822 return 0;
2824 return 0;
2827 /* render device */
2828 switch(param)
2830 case ALC_MAJOR_VERSION:
2831 values[0] = alcMajorVersion;
2832 return 1;
2834 case ALC_MINOR_VERSION:
2835 values[0] = alcMinorVersion;
2836 return 1;
2838 case ALC_EFX_MAJOR_VERSION:
2839 values[0] = alcEFXMajorVersion;
2840 return 1;
2842 case ALC_EFX_MINOR_VERSION:
2843 values[0] = alcEFXMinorVersion;
2844 return 1;
2846 case ALC_ATTRIBUTES_SIZE:
2847 values[0] = 17;
2848 return 1;
2850 case ALC_ALL_ATTRIBUTES:
2851 if(size < 17)
2853 alcSetError(device, ALC_INVALID_VALUE);
2854 return 0;
2857 i = 0;
2858 values[i++] = ALC_FREQUENCY;
2859 values[i++] = device->Frequency;
2861 if(device->Type != Loopback)
2863 values[i++] = ALC_REFRESH;
2864 values[i++] = device->Frequency / device->UpdateSize;
2866 values[i++] = ALC_SYNC;
2867 values[i++] = ALC_FALSE;
2869 else
2871 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2872 values[i++] = device->FmtChans;
2874 values[i++] = ALC_FORMAT_TYPE_SOFT;
2875 values[i++] = device->FmtType;
2878 values[i++] = ALC_MONO_SOURCES;
2879 values[i++] = device->NumMonoSources;
2881 values[i++] = ALC_STEREO_SOURCES;
2882 values[i++] = device->NumStereoSources;
2884 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2885 values[i++] = device->NumAuxSends;
2887 values[i++] = ALC_HRTF_SOFT;
2888 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2890 values[i++] = ALC_HRTF_STATUS_SOFT;
2891 values[i++] = device->Hrtf_Status;
2893 values[i++] = 0;
2894 return i;
2896 case ALC_FREQUENCY:
2897 values[0] = device->Frequency;
2898 return 1;
2900 case ALC_REFRESH:
2901 if(device->Type == Loopback)
2903 alcSetError(device, ALC_INVALID_DEVICE);
2904 return 0;
2906 values[0] = device->Frequency / device->UpdateSize;
2907 return 1;
2909 case ALC_SYNC:
2910 if(device->Type == Loopback)
2912 alcSetError(device, ALC_INVALID_DEVICE);
2913 return 0;
2915 values[0] = ALC_FALSE;
2916 return 1;
2918 case ALC_FORMAT_CHANNELS_SOFT:
2919 if(device->Type != Loopback)
2921 alcSetError(device, ALC_INVALID_DEVICE);
2922 return 0;
2924 values[0] = device->FmtChans;
2925 return 1;
2927 case ALC_FORMAT_TYPE_SOFT:
2928 if(device->Type != Loopback)
2930 alcSetError(device, ALC_INVALID_DEVICE);
2931 return 0;
2933 values[0] = device->FmtType;
2934 return 1;
2936 case ALC_MONO_SOURCES:
2937 values[0] = device->NumMonoSources;
2938 return 1;
2940 case ALC_STEREO_SOURCES:
2941 values[0] = device->NumStereoSources;
2942 return 1;
2944 case ALC_MAX_AUXILIARY_SENDS:
2945 values[0] = device->NumAuxSends;
2946 return 1;
2948 case ALC_CONNECTED:
2949 values[0] = device->Connected;
2950 return 1;
2952 case ALC_HRTF_SOFT:
2953 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2954 return 1;
2956 case ALC_HRTF_STATUS_SOFT:
2957 values[0] = device->Hrtf_Status;
2958 return 1;
2960 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2961 FreeHrtfList(&device->Hrtf_List);
2962 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2963 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2964 return 1;
2966 default:
2967 alcSetError(device, ALC_INVALID_ENUM);
2968 return 0;
2970 return 0;
2973 /* alcGetIntegerv
2975 * Returns information about the device and the version of OpenAL
2977 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2979 VerifyDevice(&device);
2980 if(size <= 0 || values == NULL)
2981 alcSetError(device, ALC_INVALID_VALUE);
2982 else
2983 GetIntegerv(device, param, size, values);
2984 if(device) ALCdevice_DecRef(device);
2987 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2989 ALCint *ivals;
2990 ALsizei i;
2992 VerifyDevice(&device);
2993 if(size <= 0 || values == NULL)
2994 alcSetError(device, ALC_INVALID_VALUE);
2995 else if(!device || device->Type == Capture)
2997 ivals = malloc(size * sizeof(ALCint));
2998 size = GetIntegerv(device, pname, size, ivals);
2999 for(i = 0;i < size;i++)
3000 values[i] = ivals[i];
3001 free(ivals);
3003 else /* render device */
3005 switch(pname)
3007 case ALC_ATTRIBUTES_SIZE:
3008 *values = 19;
3009 break;
3011 case ALC_ALL_ATTRIBUTES:
3012 if(size < 19)
3013 alcSetError(device, ALC_INVALID_VALUE);
3014 else
3016 int i = 0;
3018 V0(device->Backend,lock)();
3019 values[i++] = ALC_FREQUENCY;
3020 values[i++] = device->Frequency;
3022 if(device->Type != Loopback)
3024 values[i++] = ALC_REFRESH;
3025 values[i++] = device->Frequency / device->UpdateSize;
3027 values[i++] = ALC_SYNC;
3028 values[i++] = ALC_FALSE;
3030 else
3032 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3033 values[i++] = device->FmtChans;
3035 values[i++] = ALC_FORMAT_TYPE_SOFT;
3036 values[i++] = device->FmtType;
3039 values[i++] = ALC_MONO_SOURCES;
3040 values[i++] = device->NumMonoSources;
3042 values[i++] = ALC_STEREO_SOURCES;
3043 values[i++] = device->NumStereoSources;
3045 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3046 values[i++] = device->NumAuxSends;
3048 values[i++] = ALC_HRTF_SOFT;
3049 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
3051 values[i++] = ALC_HRTF_STATUS_SOFT;
3052 values[i++] = device->Hrtf_Status;
3054 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3055 values[i++] = device->ClockBase +
3056 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
3058 values[i++] = 0;
3059 V0(device->Backend,unlock)();
3061 break;
3063 case ALC_DEVICE_CLOCK_SOFT:
3064 V0(device->Backend,lock)();
3065 *values = device->ClockBase +
3066 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
3067 V0(device->Backend,unlock)();
3068 break;
3070 default:
3071 ivals = malloc(size * sizeof(ALCint));
3072 size = GetIntegerv(device, pname, size, ivals);
3073 for(i = 0;i < size;i++)
3074 values[i] = ivals[i];
3075 free(ivals);
3076 break;
3079 if(device)
3080 ALCdevice_DecRef(device);
3084 /* alcIsExtensionPresent
3086 * Determines if there is support for a particular extension
3088 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3090 ALCboolean bResult = ALC_FALSE;
3092 VerifyDevice(&device);
3094 if(!extName)
3095 alcSetError(device, ALC_INVALID_VALUE);
3096 else
3098 size_t len = strlen(extName);
3099 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3100 while(ptr && *ptr)
3102 if(strncasecmp(ptr, extName, len) == 0 &&
3103 (ptr[len] == '\0' || isspace(ptr[len])))
3105 bResult = ALC_TRUE;
3106 break;
3108 if((ptr=strchr(ptr, ' ')) != NULL)
3110 do {
3111 ++ptr;
3112 } while(isspace(*ptr));
3116 if(device)
3117 ALCdevice_DecRef(device);
3118 return bResult;
3122 /* alcGetProcAddress
3124 * Retrieves the function address for a particular extension function
3126 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3128 ALCvoid *ptr = NULL;
3130 if(!funcName)
3132 VerifyDevice(&device);
3133 alcSetError(device, ALC_INVALID_VALUE);
3134 if(device) ALCdevice_DecRef(device);
3136 else
3138 ALsizei i = 0;
3139 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3140 i++;
3141 ptr = alcFunctions[i].address;
3144 return ptr;
3148 /* alcGetEnumValue
3150 * Get the value for a particular ALC enumeration name
3152 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3154 ALCenum val = 0;
3156 if(!enumName)
3158 VerifyDevice(&device);
3159 alcSetError(device, ALC_INVALID_VALUE);
3160 if(device) ALCdevice_DecRef(device);
3162 else
3164 ALsizei i = 0;
3165 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3166 i++;
3167 val = enumeration[i].value;
3170 return val;
3174 /* alcCreateContext
3176 * Create and attach a context to the given device.
3178 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3180 ALCcontext *ALContext;
3181 ALCenum err;
3183 LockLists();
3184 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3186 UnlockLists();
3187 alcSetError(device, ALC_INVALID_DEVICE);
3188 if(device) ALCdevice_DecRef(device);
3189 return NULL;
3192 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3194 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3196 UnlockLists();
3197 alcSetError(device, err);
3198 if(err == ALC_INVALID_DEVICE)
3200 V0(device->Backend,lock)();
3201 aluHandleDisconnect(device);
3202 V0(device->Backend,unlock)();
3204 ALCdevice_DecRef(device);
3205 return NULL;
3208 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3209 if(ALContext)
3211 InitRef(&ALContext->ref, 1);
3212 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3214 VECTOR_INIT(ALContext->ActiveAuxSlots);
3216 ALContext->VoiceCount = 0;
3217 ALContext->MaxVoices = 256;
3218 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3220 if(!ALContext || !ALContext->Voices)
3222 if(!ATOMIC_LOAD(&device->ContextList))
3224 V0(device->Backend,stop)();
3225 device->Flags &= ~DEVICE_RUNNING;
3227 UnlockLists();
3229 if(ALContext)
3231 al_free(ALContext->Voices);
3232 ALContext->Voices = NULL;
3234 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3236 al_free(ALContext);
3237 ALContext = NULL;
3240 alcSetError(device, ALC_OUT_OF_MEMORY);
3241 ALCdevice_DecRef(device);
3242 return NULL;
3245 ALContext->Device = device;
3246 ALCdevice_IncRef(device);
3247 InitContext(ALContext);
3250 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3251 do {
3252 ALContext->next = head;
3253 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3255 UnlockLists();
3257 ALCdevice_DecRef(device);
3259 TRACE("Created context %p\n", ALContext);
3260 return ALContext;
3263 /* alcDestroyContext
3265 * Remove a context from its device
3267 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3269 ALCdevice *Device;
3271 LockLists();
3272 /* alcGetContextsDevice sets an error for invalid contexts */
3273 Device = alcGetContextsDevice(context);
3274 if(Device)
3276 ReleaseContext(context, Device);
3277 if(!ATOMIC_LOAD(&Device->ContextList))
3279 V0(Device->Backend,stop)();
3280 Device->Flags &= ~DEVICE_RUNNING;
3283 UnlockLists();
3287 /* alcGetCurrentContext
3289 * Returns the currently active context on the calling thread
3291 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3293 ALCcontext *Context = altss_get(LocalContext);
3294 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3295 return Context;
3298 /* alcGetThreadContext
3300 * Returns the currently active thread-local context
3302 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3304 return altss_get(LocalContext);
3308 /* alcMakeContextCurrent
3310 * Makes the given context the active process-wide context, and removes the
3311 * thread-local context for the calling thread.
3313 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3315 /* context must be valid or NULL */
3316 if(context && !VerifyContext(&context))
3318 alcSetError(NULL, ALC_INVALID_CONTEXT);
3319 return ALC_FALSE;
3321 /* context's reference count is already incremented */
3322 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3323 if(context) ALCcontext_DecRef(context);
3325 if((context=altss_get(LocalContext)) != NULL)
3327 altss_set(LocalContext, NULL);
3328 ALCcontext_DecRef(context);
3331 return ALC_TRUE;
3334 /* alcSetThreadContext
3336 * Makes the given context the active context for the current thread
3338 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3340 ALCcontext *old;
3342 /* context must be valid or NULL */
3343 if(context && !VerifyContext(&context))
3345 alcSetError(NULL, ALC_INVALID_CONTEXT);
3346 return ALC_FALSE;
3348 /* context's reference count is already incremented */
3349 old = altss_get(LocalContext);
3350 altss_set(LocalContext, context);
3351 if(old) ALCcontext_DecRef(old);
3353 return ALC_TRUE;
3357 /* alcGetContextsDevice
3359 * Returns the device that a particular context is attached to
3361 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3363 ALCdevice *Device;
3365 if(!VerifyContext(&Context))
3367 alcSetError(NULL, ALC_INVALID_CONTEXT);
3368 return NULL;
3370 Device = Context->Device;
3371 ALCcontext_DecRef(Context);
3373 return Device;
3377 /* alcOpenDevice
3379 * Opens the named device.
3381 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3383 const ALCchar *fmt;
3384 ALCdevice *device;
3385 ALCenum err;
3387 DO_INITCONFIG();
3389 if(!PlaybackBackend.name)
3391 alcSetError(NULL, ALC_INVALID_VALUE);
3392 return NULL;
3395 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3396 #ifdef _WIN32
3397 /* Some old Windows apps hardcode these expecting OpenAL to use a
3398 * specific audio API, even when they're not enumerated. Creative's
3399 * router effectively ignores them too.
3401 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3402 || strcasecmp(deviceName, "MMSYSTEM") == 0
3403 #endif
3405 deviceName = NULL;
3407 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3408 if(!device)
3410 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3411 return NULL;
3414 //Validate device
3415 InitRef(&device->ref, 1);
3416 device->Connected = ALC_TRUE;
3417 device->Type = Playback;
3418 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3420 device->Flags = 0;
3421 device->Bs2b = NULL;
3422 device->Uhj_Encoder = NULL;
3423 VECTOR_INIT(device->Hrtf_List);
3424 AL_STRING_INIT(device->Hrtf_Name);
3425 device->Render_Mode = NormalRender;
3426 AL_STRING_INIT(device->DeviceName);
3427 device->Dry.Buffer = NULL;
3428 device->Dry.NumChannels = 0;
3429 device->VirtOut.Buffer = NULL;
3430 device->VirtOut.NumChannels = 0;
3431 device->RealOut.Buffer = NULL;
3432 device->RealOut.NumChannels = 0;
3434 ATOMIC_INIT(&device->ContextList, NULL);
3436 device->ClockBase = 0;
3437 device->SamplesDone = 0;
3439 device->MaxNoOfSources = 256;
3440 device->AuxiliaryEffectSlotMax = 4;
3441 device->NumAuxSends = MAX_SENDS;
3443 InitUIntMap(&device->BufferMap, ~0);
3444 InitUIntMap(&device->EffectMap, ~0);
3445 InitUIntMap(&device->FilterMap, ~0);
3447 //Set output format
3448 device->FmtChans = DevFmtChannelsDefault;
3449 device->FmtType = DevFmtTypeDefault;
3450 device->Frequency = DEFAULT_OUTPUT_RATE;
3451 device->IsHeadphones = AL_FALSE;
3452 device->NumUpdates = 4;
3453 device->UpdateSize = 1024;
3455 if(!PlaybackBackend.getFactory)
3456 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3457 ALCbackend_Playback);
3458 else
3460 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3461 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3463 if(!device->Backend)
3465 al_free(device);
3466 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3467 return NULL;
3471 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3473 static const struct {
3474 const char name[16];
3475 enum DevFmtChannels chans;
3476 } chanlist[] = {
3477 { "mono", DevFmtMono },
3478 { "stereo", DevFmtStereo },
3479 { "quad", DevFmtQuad },
3480 { "surround51", DevFmtX51 },
3481 { "surround61", DevFmtX61 },
3482 { "surround71", DevFmtX71 },
3483 { "surround51rear", DevFmtX51Rear },
3485 size_t i;
3487 for(i = 0;i < COUNTOF(chanlist);i++)
3489 if(strcasecmp(chanlist[i].name, fmt) == 0)
3491 device->FmtChans = chanlist[i].chans;
3492 device->Flags |= DEVICE_CHANNELS_REQUEST;
3493 break;
3496 if(i == COUNTOF(chanlist))
3497 ERR("Unsupported channels: %s\n", fmt);
3499 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3501 static const struct {
3502 const char name[16];
3503 enum DevFmtType type;
3504 } typelist[] = {
3505 { "int8", DevFmtByte },
3506 { "uint8", DevFmtUByte },
3507 { "int16", DevFmtShort },
3508 { "uint16", DevFmtUShort },
3509 { "int32", DevFmtInt },
3510 { "uint32", DevFmtUInt },
3511 { "float32", DevFmtFloat },
3513 size_t i;
3515 for(i = 0;i < COUNTOF(typelist);i++)
3517 if(strcasecmp(typelist[i].name, fmt) == 0)
3519 device->FmtType = typelist[i].type;
3520 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3521 break;
3524 if(i == COUNTOF(typelist))
3525 ERR("Unsupported sample-type: %s\n", fmt);
3528 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3530 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3531 if(device->Frequency < MIN_OUTPUT_RATE)
3532 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3533 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3536 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3537 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3539 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3540 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3541 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3542 device->UpdateSize = (device->UpdateSize+3)&~3;
3544 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3545 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3547 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3548 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3550 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3551 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3553 device->NumStereoSources = 1;
3554 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3556 // Find a playback device to open
3557 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3559 DELETE_OBJ(device->Backend);
3560 al_free(device);
3561 alcSetError(NULL, err);
3562 return NULL;
3565 if(DefaultEffect.type != AL_EFFECT_NULL)
3567 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3568 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3570 device->DefaultSlot = NULL;
3571 ERR("Failed to initialize the default effect slot\n");
3573 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3575 ALeffectState *state = device->DefaultSlot->EffectState;
3576 device->DefaultSlot = NULL;
3577 DELETE_OBJ(state);
3578 ERR("Failed to initialize the default effect\n");
3580 else
3581 aluInitEffectPanning(device->DefaultSlot);
3585 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3586 do {
3587 device->next = head;
3588 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3591 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3592 return device;
3595 /* alcCloseDevice
3597 * Closes the given device.
3599 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3601 ALCdevice *list, *origdev, *nextdev;
3602 ALCcontext *ctx;
3604 LockLists();
3605 list = ATOMIC_LOAD(&DeviceList);
3606 do {
3607 if(list == device)
3608 break;
3609 } while((list=list->next) != NULL);
3610 if(!list || list->Type == Capture)
3612 alcSetError(list, ALC_INVALID_DEVICE);
3613 UnlockLists();
3614 return ALC_FALSE;
3617 origdev = device;
3618 nextdev = device->next;
3619 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3621 do {
3622 list = origdev;
3623 origdev = device;
3624 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3626 UnlockLists();
3628 ctx = ATOMIC_LOAD(&device->ContextList);
3629 while(ctx != NULL)
3631 ALCcontext *next = ctx->next;
3632 WARN("Releasing context %p\n", ctx);
3633 ReleaseContext(ctx, device);
3634 ctx = next;
3636 if((device->Flags&DEVICE_RUNNING))
3637 V0(device->Backend,stop)();
3638 device->Flags &= ~DEVICE_RUNNING;
3640 ALCdevice_DecRef(device);
3642 return ALC_TRUE;
3646 /************************************************
3647 * ALC capture functions
3648 ************************************************/
3649 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3651 ALCdevice *device = NULL;
3652 ALCenum err;
3654 DO_INITCONFIG();
3656 if(!CaptureBackend.name)
3658 alcSetError(NULL, ALC_INVALID_VALUE);
3659 return NULL;
3662 if(samples <= 0)
3664 alcSetError(NULL, ALC_INVALID_VALUE);
3665 return NULL;
3668 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3669 deviceName = NULL;
3671 device = al_calloc(16, sizeof(ALCdevice));
3672 if(!device)
3674 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3675 return NULL;
3678 //Validate device
3679 InitRef(&device->ref, 1);
3680 device->Connected = ALC_TRUE;
3681 device->Type = Capture;
3683 VECTOR_INIT(device->Hrtf_List);
3684 AL_STRING_INIT(device->Hrtf_Name);
3686 AL_STRING_INIT(device->DeviceName);
3687 device->Dry.Buffer = NULL;
3688 device->Dry.NumChannels = 0;
3689 device->VirtOut.Buffer = NULL;
3690 device->VirtOut.NumChannels = 0;
3691 device->RealOut.Buffer = NULL;
3692 device->RealOut.NumChannels = 0;
3694 InitUIntMap(&device->BufferMap, ~0);
3695 InitUIntMap(&device->EffectMap, ~0);
3696 InitUIntMap(&device->FilterMap, ~0);
3698 if(!CaptureBackend.getFactory)
3699 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3700 ALCbackend_Capture);
3701 else
3703 ALCbackendFactory *factory = CaptureBackend.getFactory();
3704 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3706 if(!device->Backend)
3708 al_free(device);
3709 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3710 return NULL;
3713 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3714 device->Frequency = frequency;
3716 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3717 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3719 al_free(device);
3720 alcSetError(NULL, ALC_INVALID_ENUM);
3721 return NULL;
3723 device->IsHeadphones = AL_FALSE;
3725 device->UpdateSize = samples;
3726 device->NumUpdates = 1;
3728 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3730 al_free(device);
3731 alcSetError(NULL, err);
3732 return NULL;
3736 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3737 do {
3738 device->next = head;
3739 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3742 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3743 return device;
3746 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3748 ALCdevice *list, *next, *nextdev;
3750 LockLists();
3751 list = ATOMIC_LOAD(&DeviceList);
3752 do {
3753 if(list == device)
3754 break;
3755 } while((list=list->next) != NULL);
3756 if(!list || list->Type != Capture)
3758 alcSetError(list, ALC_INVALID_DEVICE);
3759 UnlockLists();
3760 return ALC_FALSE;
3763 next = device;
3764 nextdev = device->next;
3765 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3767 do {
3768 list = next;
3769 next = device;
3770 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3772 UnlockLists();
3774 ALCdevice_DecRef(device);
3776 return ALC_TRUE;
3779 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3781 if(!VerifyDevice(&device) || device->Type != Capture)
3782 alcSetError(device, ALC_INVALID_DEVICE);
3783 else
3785 V0(device->Backend,lock)();
3786 if(!device->Connected)
3787 alcSetError(device, ALC_INVALID_DEVICE);
3788 else if(!(device->Flags&DEVICE_RUNNING))
3790 if(V0(device->Backend,start)())
3791 device->Flags |= DEVICE_RUNNING;
3792 else
3794 aluHandleDisconnect(device);
3795 alcSetError(device, ALC_INVALID_DEVICE);
3798 V0(device->Backend,unlock)();
3801 if(device) ALCdevice_DecRef(device);
3804 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3806 if(!VerifyDevice(&device) || device->Type != Capture)
3807 alcSetError(device, ALC_INVALID_DEVICE);
3808 else
3810 V0(device->Backend,lock)();
3811 if((device->Flags&DEVICE_RUNNING))
3812 V0(device->Backend,stop)();
3813 device->Flags &= ~DEVICE_RUNNING;
3814 V0(device->Backend,unlock)();
3817 if(device) ALCdevice_DecRef(device);
3820 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3822 if(!VerifyDevice(&device) || device->Type != Capture)
3823 alcSetError(device, ALC_INVALID_DEVICE);
3824 else
3826 ALCenum err = ALC_INVALID_VALUE;
3828 V0(device->Backend,lock)();
3829 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3830 err = V(device->Backend,captureSamples)(buffer, samples);
3831 V0(device->Backend,unlock)();
3833 if(err != ALC_NO_ERROR)
3834 alcSetError(device, err);
3836 if(device) ALCdevice_DecRef(device);
3840 /************************************************
3841 * ALC loopback functions
3842 ************************************************/
3844 /* alcLoopbackOpenDeviceSOFT
3846 * Open a loopback device, for manual rendering.
3848 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3850 ALCbackendFactory *factory;
3851 ALCdevice *device;
3853 DO_INITCONFIG();
3855 /* Make sure the device name, if specified, is us. */
3856 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3858 alcSetError(NULL, ALC_INVALID_VALUE);
3859 return NULL;
3862 device = al_calloc(16, sizeof(ALCdevice));
3863 if(!device)
3865 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3866 return NULL;
3869 //Validate device
3870 InitRef(&device->ref, 1);
3871 device->Connected = ALC_TRUE;
3872 device->Type = Loopback;
3873 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3875 device->Flags = 0;
3876 VECTOR_INIT(device->Hrtf_List);
3877 AL_STRING_INIT(device->Hrtf_Name);
3878 device->Bs2b = NULL;
3879 device->Uhj_Encoder = NULL;
3880 device->Render_Mode = NormalRender;
3881 AL_STRING_INIT(device->DeviceName);
3882 device->Dry.Buffer = NULL;
3883 device->Dry.NumChannels = 0;
3884 device->VirtOut.Buffer = NULL;
3885 device->VirtOut.NumChannels = 0;
3886 device->RealOut.Buffer = NULL;
3887 device->RealOut.NumChannels = 0;
3889 ATOMIC_INIT(&device->ContextList, NULL);
3891 device->ClockBase = 0;
3892 device->SamplesDone = 0;
3894 device->MaxNoOfSources = 256;
3895 device->AuxiliaryEffectSlotMax = 4;
3896 device->NumAuxSends = MAX_SENDS;
3898 InitUIntMap(&device->BufferMap, ~0);
3899 InitUIntMap(&device->EffectMap, ~0);
3900 InitUIntMap(&device->FilterMap, ~0);
3902 factory = ALCloopbackFactory_getFactory();
3903 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3904 if(!device->Backend)
3906 al_free(device);
3907 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3908 return NULL;
3911 //Set output format
3912 device->NumUpdates = 0;
3913 device->UpdateSize = 0;
3915 device->Frequency = DEFAULT_OUTPUT_RATE;
3916 device->FmtChans = DevFmtChannelsDefault;
3917 device->FmtType = DevFmtTypeDefault;
3918 device->IsHeadphones = AL_FALSE;
3920 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3921 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3923 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3924 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3926 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3927 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3929 device->NumStereoSources = 1;
3930 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3932 // Open the "backend"
3933 V(device->Backend,open)("Loopback");
3936 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3937 do {
3938 device->next = head;
3939 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3942 TRACE("Created device %p\n", device);
3943 return device;
3946 /* alcIsRenderFormatSupportedSOFT
3948 * Determines if the loopback device supports the given format for rendering.
3950 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3952 ALCboolean ret = ALC_FALSE;
3954 if(!VerifyDevice(&device) || device->Type != Loopback)
3955 alcSetError(device, ALC_INVALID_DEVICE);
3956 else if(freq <= 0)
3957 alcSetError(device, ALC_INVALID_VALUE);
3958 else
3960 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3961 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3962 freq >= MIN_OUTPUT_RATE)
3963 ret = ALC_TRUE;
3965 if(device) ALCdevice_DecRef(device);
3967 return ret;
3970 /* alcRenderSamplesSOFT
3972 * Renders some samples into a buffer, using the format last set by the
3973 * attributes given to alcCreateContext.
3975 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3977 if(!VerifyDevice(&device) || device->Type != Loopback)
3978 alcSetError(device, ALC_INVALID_DEVICE);
3979 else if(samples < 0 || (samples > 0 && buffer == NULL))
3980 alcSetError(device, ALC_INVALID_VALUE);
3981 else
3982 aluMixData(device, buffer, samples);
3983 if(device) ALCdevice_DecRef(device);
3987 /************************************************
3988 * ALC DSP pause/resume functions
3989 ************************************************/
3991 /* alcDevicePauseSOFT
3993 * Pause the DSP to stop audio processing.
3995 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3997 if(!VerifyDevice(&device) || device->Type != Playback)
3998 alcSetError(device, ALC_INVALID_DEVICE);
3999 else
4001 LockLists();
4002 if((device->Flags&DEVICE_RUNNING))
4003 V0(device->Backend,stop)();
4004 device->Flags &= ~DEVICE_RUNNING;
4005 device->Flags |= DEVICE_PAUSED;
4006 UnlockLists();
4008 if(device) ALCdevice_DecRef(device);
4011 /* alcDeviceResumeSOFT
4013 * Resume the DSP to restart audio processing.
4015 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4017 if(!VerifyDevice(&device) || device->Type != Playback)
4018 alcSetError(device, ALC_INVALID_DEVICE);
4019 else
4021 LockLists();
4022 if((device->Flags&DEVICE_PAUSED))
4024 device->Flags &= ~DEVICE_PAUSED;
4025 if(ATOMIC_LOAD(&device->ContextList) != NULL)
4027 if(V0(device->Backend,start)() != ALC_FALSE)
4028 device->Flags |= DEVICE_RUNNING;
4029 else
4031 alcSetError(device, ALC_INVALID_DEVICE);
4032 V0(device->Backend,lock)();
4033 aluHandleDisconnect(device);
4034 V0(device->Backend,unlock)();
4038 UnlockLists();
4040 if(device) ALCdevice_DecRef(device);
4044 /************************************************
4045 * ALC HRTF functions
4046 ************************************************/
4048 /* alcGetStringiSOFT
4050 * Gets a string parameter at the given index.
4052 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4054 const ALCchar *str = NULL;
4056 if(!VerifyDevice(&device) || device->Type == Capture)
4057 alcSetError(device, ALC_INVALID_DEVICE);
4058 else switch(paramName)
4060 case ALC_HRTF_SPECIFIER_SOFT:
4061 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
4062 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
4063 else
4064 alcSetError(device, ALC_INVALID_VALUE);
4065 break;
4067 default:
4068 alcSetError(device, ALC_INVALID_ENUM);
4069 break;
4071 if(device) ALCdevice_DecRef(device);
4073 return str;
4076 /* alcResetDeviceSOFT
4078 * Resets the given device output, using the specified attribute list.
4080 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4082 ALCenum err;
4084 LockLists();
4085 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4087 UnlockLists();
4088 alcSetError(device, ALC_INVALID_DEVICE);
4089 if(device) ALCdevice_DecRef(device);
4090 return ALC_FALSE;
4093 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
4095 UnlockLists();
4096 alcSetError(device, err);
4097 if(err == ALC_INVALID_DEVICE)
4099 V0(device->Backend,lock)();
4100 aluHandleDisconnect(device);
4101 V0(device->Backend,unlock)();
4103 ALCdevice_DecRef(device);
4104 return ALC_FALSE;
4106 UnlockLists();
4107 ALCdevice_DecRef(device);
4109 return ALC_TRUE;