Provide (mostly) lockless updates for effect slots
[openal-soft.git] / Alc / ALc.c
blobb3d7eb38a3bc9d95036a1e1d423f99868ae646b5
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 "bformatdec.h"
39 #include "alu.h"
41 #include "compat.h"
42 #include "threads.h"
43 #include "alstring.h"
44 #include "almalloc.h"
46 #include "backends/base.h"
49 /************************************************
50 * Backends
51 ************************************************/
52 struct BackendInfo {
53 const char *name;
54 ALCbackendFactory* (*getFactory)(void);
55 ALCboolean (*Init)(BackendFuncs*);
56 void (*Deinit)(void);
57 void (*Probe)(enum DevProbe);
58 BackendFuncs Funcs;
61 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
62 static struct BackendInfo BackendList[] = {
63 #ifdef HAVE_JACK
64 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
65 #endif
66 #ifdef HAVE_PULSEAUDIO
67 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
68 #endif
69 #ifdef HAVE_ALSA
70 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
71 #endif
72 #ifdef HAVE_COREAUDIO
73 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
74 #endif
75 #ifdef HAVE_OSS
76 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
77 #endif
78 #ifdef HAVE_SOLARIS
79 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
80 #endif
81 #ifdef HAVE_SNDIO
82 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
83 #endif
84 #ifdef HAVE_QSA
85 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
86 #endif
87 #ifdef HAVE_MMDEVAPI
88 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
89 #endif
90 #ifdef HAVE_DSOUND
91 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
92 #endif
93 #ifdef HAVE_WINMM
94 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
95 #endif
96 #ifdef HAVE_PORTAUDIO
97 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
98 #endif
99 #ifdef HAVE_OPENSL
100 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
101 #endif
103 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
104 #ifdef HAVE_WAVE
105 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
106 #endif
108 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
110 #undef EmptyFuncs
112 static struct BackendInfo PlaybackBackend;
113 static struct BackendInfo CaptureBackend;
116 /************************************************
117 * Functions, enums, and errors
118 ************************************************/
119 typedef struct ALCfunction {
120 const ALCchar *funcName;
121 ALCvoid *address;
122 } ALCfunction;
124 typedef struct ALCenums {
125 const ALCchar *enumName;
126 ALCenum value;
127 } ALCenums;
129 #define DECL(x) { #x, (ALCvoid*)(x) }
130 static const ALCfunction alcFunctions[] = {
131 DECL(alcCreateContext),
132 DECL(alcMakeContextCurrent),
133 DECL(alcProcessContext),
134 DECL(alcSuspendContext),
135 DECL(alcDestroyContext),
136 DECL(alcGetCurrentContext),
137 DECL(alcGetContextsDevice),
138 DECL(alcOpenDevice),
139 DECL(alcCloseDevice),
140 DECL(alcGetError),
141 DECL(alcIsExtensionPresent),
142 DECL(alcGetProcAddress),
143 DECL(alcGetEnumValue),
144 DECL(alcGetString),
145 DECL(alcGetIntegerv),
146 DECL(alcCaptureOpenDevice),
147 DECL(alcCaptureCloseDevice),
148 DECL(alcCaptureStart),
149 DECL(alcCaptureStop),
150 DECL(alcCaptureSamples),
152 DECL(alcSetThreadContext),
153 DECL(alcGetThreadContext),
155 DECL(alcLoopbackOpenDeviceSOFT),
156 DECL(alcIsRenderFormatSupportedSOFT),
157 DECL(alcRenderSamplesSOFT),
159 DECL(alcDevicePauseSOFT),
160 DECL(alcDeviceResumeSOFT),
162 DECL(alcGetStringiSOFT),
163 DECL(alcResetDeviceSOFT),
165 DECL(alcGetInteger64vSOFT),
167 DECL(alEnable),
168 DECL(alDisable),
169 DECL(alIsEnabled),
170 DECL(alGetString),
171 DECL(alGetBooleanv),
172 DECL(alGetIntegerv),
173 DECL(alGetFloatv),
174 DECL(alGetDoublev),
175 DECL(alGetBoolean),
176 DECL(alGetInteger),
177 DECL(alGetFloat),
178 DECL(alGetDouble),
179 DECL(alGetError),
180 DECL(alIsExtensionPresent),
181 DECL(alGetProcAddress),
182 DECL(alGetEnumValue),
183 DECL(alListenerf),
184 DECL(alListener3f),
185 DECL(alListenerfv),
186 DECL(alListeneri),
187 DECL(alListener3i),
188 DECL(alListeneriv),
189 DECL(alGetListenerf),
190 DECL(alGetListener3f),
191 DECL(alGetListenerfv),
192 DECL(alGetListeneri),
193 DECL(alGetListener3i),
194 DECL(alGetListeneriv),
195 DECL(alGenSources),
196 DECL(alDeleteSources),
197 DECL(alIsSource),
198 DECL(alSourcef),
199 DECL(alSource3f),
200 DECL(alSourcefv),
201 DECL(alSourcei),
202 DECL(alSource3i),
203 DECL(alSourceiv),
204 DECL(alGetSourcef),
205 DECL(alGetSource3f),
206 DECL(alGetSourcefv),
207 DECL(alGetSourcei),
208 DECL(alGetSource3i),
209 DECL(alGetSourceiv),
210 DECL(alSourcePlayv),
211 DECL(alSourceStopv),
212 DECL(alSourceRewindv),
213 DECL(alSourcePausev),
214 DECL(alSourcePlay),
215 DECL(alSourceStop),
216 DECL(alSourceRewind),
217 DECL(alSourcePause),
218 DECL(alSourceQueueBuffers),
219 DECL(alSourceUnqueueBuffers),
220 DECL(alGenBuffers),
221 DECL(alDeleteBuffers),
222 DECL(alIsBuffer),
223 DECL(alBufferData),
224 DECL(alBufferf),
225 DECL(alBuffer3f),
226 DECL(alBufferfv),
227 DECL(alBufferi),
228 DECL(alBuffer3i),
229 DECL(alBufferiv),
230 DECL(alGetBufferf),
231 DECL(alGetBuffer3f),
232 DECL(alGetBufferfv),
233 DECL(alGetBufferi),
234 DECL(alGetBuffer3i),
235 DECL(alGetBufferiv),
236 DECL(alDopplerFactor),
237 DECL(alDopplerVelocity),
238 DECL(alSpeedOfSound),
239 DECL(alDistanceModel),
241 DECL(alGenFilters),
242 DECL(alDeleteFilters),
243 DECL(alIsFilter),
244 DECL(alFilteri),
245 DECL(alFilteriv),
246 DECL(alFilterf),
247 DECL(alFilterfv),
248 DECL(alGetFilteri),
249 DECL(alGetFilteriv),
250 DECL(alGetFilterf),
251 DECL(alGetFilterfv),
252 DECL(alGenEffects),
253 DECL(alDeleteEffects),
254 DECL(alIsEffect),
255 DECL(alEffecti),
256 DECL(alEffectiv),
257 DECL(alEffectf),
258 DECL(alEffectfv),
259 DECL(alGetEffecti),
260 DECL(alGetEffectiv),
261 DECL(alGetEffectf),
262 DECL(alGetEffectfv),
263 DECL(alGenAuxiliaryEffectSlots),
264 DECL(alDeleteAuxiliaryEffectSlots),
265 DECL(alIsAuxiliaryEffectSlot),
266 DECL(alAuxiliaryEffectSloti),
267 DECL(alAuxiliaryEffectSlotiv),
268 DECL(alAuxiliaryEffectSlotf),
269 DECL(alAuxiliaryEffectSlotfv),
270 DECL(alGetAuxiliaryEffectSloti),
271 DECL(alGetAuxiliaryEffectSlotiv),
272 DECL(alGetAuxiliaryEffectSlotf),
273 DECL(alGetAuxiliaryEffectSlotfv),
275 DECL(alDeferUpdatesSOFT),
276 DECL(alProcessUpdatesSOFT),
278 DECL(alSourcedSOFT),
279 DECL(alSource3dSOFT),
280 DECL(alSourcedvSOFT),
281 DECL(alGetSourcedSOFT),
282 DECL(alGetSource3dSOFT),
283 DECL(alGetSourcedvSOFT),
284 DECL(alSourcei64SOFT),
285 DECL(alSource3i64SOFT),
286 DECL(alSourcei64vSOFT),
287 DECL(alGetSourcei64SOFT),
288 DECL(alGetSource3i64SOFT),
289 DECL(alGetSourcei64vSOFT),
291 DECL(alBufferSamplesSOFT),
292 DECL(alGetBufferSamplesSOFT),
293 DECL(alIsBufferFormatSupportedSOFT),
295 { NULL, NULL }
297 #undef DECL
299 #define DECL(x) { #x, (x) }
300 static const ALCenums enumeration[] = {
301 DECL(ALC_INVALID),
302 DECL(ALC_FALSE),
303 DECL(ALC_TRUE),
305 DECL(ALC_MAJOR_VERSION),
306 DECL(ALC_MINOR_VERSION),
307 DECL(ALC_ATTRIBUTES_SIZE),
308 DECL(ALC_ALL_ATTRIBUTES),
309 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
310 DECL(ALC_DEVICE_SPECIFIER),
311 DECL(ALC_ALL_DEVICES_SPECIFIER),
312 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
313 DECL(ALC_EXTENSIONS),
314 DECL(ALC_FREQUENCY),
315 DECL(ALC_REFRESH),
316 DECL(ALC_SYNC),
317 DECL(ALC_MONO_SOURCES),
318 DECL(ALC_STEREO_SOURCES),
319 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
320 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
321 DECL(ALC_CAPTURE_SAMPLES),
322 DECL(ALC_CONNECTED),
324 DECL(ALC_EFX_MAJOR_VERSION),
325 DECL(ALC_EFX_MINOR_VERSION),
326 DECL(ALC_MAX_AUXILIARY_SENDS),
328 DECL(ALC_FORMAT_CHANNELS_SOFT),
329 DECL(ALC_FORMAT_TYPE_SOFT),
331 DECL(ALC_MONO_SOFT),
332 DECL(ALC_STEREO_SOFT),
333 DECL(ALC_QUAD_SOFT),
334 DECL(ALC_5POINT1_SOFT),
335 DECL(ALC_6POINT1_SOFT),
336 DECL(ALC_7POINT1_SOFT),
338 DECL(ALC_BYTE_SOFT),
339 DECL(ALC_UNSIGNED_BYTE_SOFT),
340 DECL(ALC_SHORT_SOFT),
341 DECL(ALC_UNSIGNED_SHORT_SOFT),
342 DECL(ALC_INT_SOFT),
343 DECL(ALC_UNSIGNED_INT_SOFT),
344 DECL(ALC_FLOAT_SOFT),
346 DECL(ALC_HRTF_SOFT),
347 DECL(ALC_DONT_CARE_SOFT),
348 DECL(ALC_HRTF_STATUS_SOFT),
349 DECL(ALC_HRTF_DISABLED_SOFT),
350 DECL(ALC_HRTF_ENABLED_SOFT),
351 DECL(ALC_HRTF_DENIED_SOFT),
352 DECL(ALC_HRTF_REQUIRED_SOFT),
353 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
354 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
355 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
356 DECL(ALC_HRTF_SPECIFIER_SOFT),
357 DECL(ALC_HRTF_ID_SOFT),
359 DECL(ALC_NO_ERROR),
360 DECL(ALC_INVALID_DEVICE),
361 DECL(ALC_INVALID_CONTEXT),
362 DECL(ALC_INVALID_ENUM),
363 DECL(ALC_INVALID_VALUE),
364 DECL(ALC_OUT_OF_MEMORY),
367 DECL(AL_INVALID),
368 DECL(AL_NONE),
369 DECL(AL_FALSE),
370 DECL(AL_TRUE),
372 DECL(AL_SOURCE_RELATIVE),
373 DECL(AL_CONE_INNER_ANGLE),
374 DECL(AL_CONE_OUTER_ANGLE),
375 DECL(AL_PITCH),
376 DECL(AL_POSITION),
377 DECL(AL_DIRECTION),
378 DECL(AL_VELOCITY),
379 DECL(AL_LOOPING),
380 DECL(AL_BUFFER),
381 DECL(AL_GAIN),
382 DECL(AL_MIN_GAIN),
383 DECL(AL_MAX_GAIN),
384 DECL(AL_ORIENTATION),
385 DECL(AL_REFERENCE_DISTANCE),
386 DECL(AL_ROLLOFF_FACTOR),
387 DECL(AL_CONE_OUTER_GAIN),
388 DECL(AL_MAX_DISTANCE),
389 DECL(AL_SEC_OFFSET),
390 DECL(AL_SAMPLE_OFFSET),
391 DECL(AL_BYTE_OFFSET),
392 DECL(AL_SOURCE_TYPE),
393 DECL(AL_STATIC),
394 DECL(AL_STREAMING),
395 DECL(AL_UNDETERMINED),
396 DECL(AL_METERS_PER_UNIT),
397 DECL(AL_LOOP_POINTS_SOFT),
398 DECL(AL_DIRECT_CHANNELS_SOFT),
400 DECL(AL_DIRECT_FILTER),
401 DECL(AL_AUXILIARY_SEND_FILTER),
402 DECL(AL_AIR_ABSORPTION_FACTOR),
403 DECL(AL_ROOM_ROLLOFF_FACTOR),
404 DECL(AL_CONE_OUTER_GAINHF),
405 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
406 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
407 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
409 DECL(AL_SOURCE_STATE),
410 DECL(AL_INITIAL),
411 DECL(AL_PLAYING),
412 DECL(AL_PAUSED),
413 DECL(AL_STOPPED),
415 DECL(AL_BUFFERS_QUEUED),
416 DECL(AL_BUFFERS_PROCESSED),
418 DECL(AL_FORMAT_MONO8),
419 DECL(AL_FORMAT_MONO16),
420 DECL(AL_FORMAT_MONO_FLOAT32),
421 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
422 DECL(AL_FORMAT_STEREO8),
423 DECL(AL_FORMAT_STEREO16),
424 DECL(AL_FORMAT_STEREO_FLOAT32),
425 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
426 DECL(AL_FORMAT_MONO_IMA4),
427 DECL(AL_FORMAT_STEREO_IMA4),
428 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
429 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
430 DECL(AL_FORMAT_QUAD8_LOKI),
431 DECL(AL_FORMAT_QUAD16_LOKI),
432 DECL(AL_FORMAT_QUAD8),
433 DECL(AL_FORMAT_QUAD16),
434 DECL(AL_FORMAT_QUAD32),
435 DECL(AL_FORMAT_51CHN8),
436 DECL(AL_FORMAT_51CHN16),
437 DECL(AL_FORMAT_51CHN32),
438 DECL(AL_FORMAT_61CHN8),
439 DECL(AL_FORMAT_61CHN16),
440 DECL(AL_FORMAT_61CHN32),
441 DECL(AL_FORMAT_71CHN8),
442 DECL(AL_FORMAT_71CHN16),
443 DECL(AL_FORMAT_71CHN32),
444 DECL(AL_FORMAT_REAR8),
445 DECL(AL_FORMAT_REAR16),
446 DECL(AL_FORMAT_REAR32),
447 DECL(AL_FORMAT_MONO_MULAW),
448 DECL(AL_FORMAT_MONO_MULAW_EXT),
449 DECL(AL_FORMAT_STEREO_MULAW),
450 DECL(AL_FORMAT_STEREO_MULAW_EXT),
451 DECL(AL_FORMAT_QUAD_MULAW),
452 DECL(AL_FORMAT_51CHN_MULAW),
453 DECL(AL_FORMAT_61CHN_MULAW),
454 DECL(AL_FORMAT_71CHN_MULAW),
455 DECL(AL_FORMAT_REAR_MULAW),
456 DECL(AL_FORMAT_MONO_ALAW_EXT),
457 DECL(AL_FORMAT_STEREO_ALAW_EXT),
459 DECL(AL_FORMAT_BFORMAT2D_8),
460 DECL(AL_FORMAT_BFORMAT2D_16),
461 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
462 DECL(AL_FORMAT_BFORMAT2D_MULAW),
463 DECL(AL_FORMAT_BFORMAT3D_8),
464 DECL(AL_FORMAT_BFORMAT3D_16),
465 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
466 DECL(AL_FORMAT_BFORMAT3D_MULAW),
468 DECL(AL_MONO8_SOFT),
469 DECL(AL_MONO16_SOFT),
470 DECL(AL_MONO32F_SOFT),
471 DECL(AL_STEREO8_SOFT),
472 DECL(AL_STEREO16_SOFT),
473 DECL(AL_STEREO32F_SOFT),
474 DECL(AL_QUAD8_SOFT),
475 DECL(AL_QUAD16_SOFT),
476 DECL(AL_QUAD32F_SOFT),
477 DECL(AL_REAR8_SOFT),
478 DECL(AL_REAR16_SOFT),
479 DECL(AL_REAR32F_SOFT),
480 DECL(AL_5POINT1_8_SOFT),
481 DECL(AL_5POINT1_16_SOFT),
482 DECL(AL_5POINT1_32F_SOFT),
483 DECL(AL_6POINT1_8_SOFT),
484 DECL(AL_6POINT1_16_SOFT),
485 DECL(AL_6POINT1_32F_SOFT),
486 DECL(AL_7POINT1_8_SOFT),
487 DECL(AL_7POINT1_16_SOFT),
488 DECL(AL_7POINT1_32F_SOFT),
489 DECL(AL_BFORMAT2D_8_SOFT),
490 DECL(AL_BFORMAT2D_16_SOFT),
491 DECL(AL_BFORMAT2D_32F_SOFT),
492 DECL(AL_BFORMAT3D_8_SOFT),
493 DECL(AL_BFORMAT3D_16_SOFT),
494 DECL(AL_BFORMAT3D_32F_SOFT),
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),
503 DECL(AL_BFORMAT2D_SOFT),
504 DECL(AL_BFORMAT3D_SOFT),
506 DECL(AL_BYTE_SOFT),
507 DECL(AL_UNSIGNED_BYTE_SOFT),
508 DECL(AL_SHORT_SOFT),
509 DECL(AL_UNSIGNED_SHORT_SOFT),
510 DECL(AL_INT_SOFT),
511 DECL(AL_UNSIGNED_INT_SOFT),
512 DECL(AL_FLOAT_SOFT),
513 DECL(AL_DOUBLE_SOFT),
514 DECL(AL_BYTE3_SOFT),
515 DECL(AL_UNSIGNED_BYTE3_SOFT),
516 DECL(AL_MULAW_SOFT),
518 DECL(AL_FREQUENCY),
519 DECL(AL_BITS),
520 DECL(AL_CHANNELS),
521 DECL(AL_SIZE),
522 DECL(AL_INTERNAL_FORMAT_SOFT),
523 DECL(AL_BYTE_LENGTH_SOFT),
524 DECL(AL_SAMPLE_LENGTH_SOFT),
525 DECL(AL_SEC_LENGTH_SOFT),
526 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
527 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
529 DECL(AL_SOURCE_RADIUS),
531 DECL(AL_STEREO_ANGLES),
533 DECL(AL_UNUSED),
534 DECL(AL_PENDING),
535 DECL(AL_PROCESSED),
537 DECL(AL_NO_ERROR),
538 DECL(AL_INVALID_NAME),
539 DECL(AL_INVALID_ENUM),
540 DECL(AL_INVALID_VALUE),
541 DECL(AL_INVALID_OPERATION),
542 DECL(AL_OUT_OF_MEMORY),
544 DECL(AL_VENDOR),
545 DECL(AL_VERSION),
546 DECL(AL_RENDERER),
547 DECL(AL_EXTENSIONS),
549 DECL(AL_DOPPLER_FACTOR),
550 DECL(AL_DOPPLER_VELOCITY),
551 DECL(AL_DISTANCE_MODEL),
552 DECL(AL_SPEED_OF_SOUND),
553 DECL(AL_SOURCE_DISTANCE_MODEL),
554 DECL(AL_DEFERRED_UPDATES_SOFT),
556 DECL(AL_INVERSE_DISTANCE),
557 DECL(AL_INVERSE_DISTANCE_CLAMPED),
558 DECL(AL_LINEAR_DISTANCE),
559 DECL(AL_LINEAR_DISTANCE_CLAMPED),
560 DECL(AL_EXPONENT_DISTANCE),
561 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
563 DECL(AL_FILTER_TYPE),
564 DECL(AL_FILTER_NULL),
565 DECL(AL_FILTER_LOWPASS),
566 DECL(AL_FILTER_HIGHPASS),
567 DECL(AL_FILTER_BANDPASS),
569 DECL(AL_LOWPASS_GAIN),
570 DECL(AL_LOWPASS_GAINHF),
572 DECL(AL_HIGHPASS_GAIN),
573 DECL(AL_HIGHPASS_GAINLF),
575 DECL(AL_BANDPASS_GAIN),
576 DECL(AL_BANDPASS_GAINHF),
577 DECL(AL_BANDPASS_GAINLF),
579 DECL(AL_EFFECT_TYPE),
580 DECL(AL_EFFECT_NULL),
581 DECL(AL_EFFECT_REVERB),
582 DECL(AL_EFFECT_EAXREVERB),
583 DECL(AL_EFFECT_CHORUS),
584 DECL(AL_EFFECT_DISTORTION),
585 DECL(AL_EFFECT_ECHO),
586 DECL(AL_EFFECT_FLANGER),
587 #if 0
588 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
589 DECL(AL_EFFECT_VOCAL_MORPHER),
590 DECL(AL_EFFECT_PITCH_SHIFTER),
591 #endif
592 DECL(AL_EFFECT_RING_MODULATOR),
593 #if 0
594 DECL(AL_EFFECT_AUTOWAH),
595 #endif
596 DECL(AL_EFFECT_COMPRESSOR),
597 DECL(AL_EFFECT_EQUALIZER),
598 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
599 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
601 DECL(AL_EAXREVERB_DENSITY),
602 DECL(AL_EAXREVERB_DIFFUSION),
603 DECL(AL_EAXREVERB_GAIN),
604 DECL(AL_EAXREVERB_GAINHF),
605 DECL(AL_EAXREVERB_GAINLF),
606 DECL(AL_EAXREVERB_DECAY_TIME),
607 DECL(AL_EAXREVERB_DECAY_HFRATIO),
608 DECL(AL_EAXREVERB_DECAY_LFRATIO),
609 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
610 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
611 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
612 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
613 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
614 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
615 DECL(AL_EAXREVERB_ECHO_TIME),
616 DECL(AL_EAXREVERB_ECHO_DEPTH),
617 DECL(AL_EAXREVERB_MODULATION_TIME),
618 DECL(AL_EAXREVERB_MODULATION_DEPTH),
619 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
620 DECL(AL_EAXREVERB_HFREFERENCE),
621 DECL(AL_EAXREVERB_LFREFERENCE),
622 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
623 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
625 DECL(AL_REVERB_DENSITY),
626 DECL(AL_REVERB_DIFFUSION),
627 DECL(AL_REVERB_GAIN),
628 DECL(AL_REVERB_GAINHF),
629 DECL(AL_REVERB_DECAY_TIME),
630 DECL(AL_REVERB_DECAY_HFRATIO),
631 DECL(AL_REVERB_REFLECTIONS_GAIN),
632 DECL(AL_REVERB_REFLECTIONS_DELAY),
633 DECL(AL_REVERB_LATE_REVERB_GAIN),
634 DECL(AL_REVERB_LATE_REVERB_DELAY),
635 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
636 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
637 DECL(AL_REVERB_DECAY_HFLIMIT),
639 DECL(AL_CHORUS_WAVEFORM),
640 DECL(AL_CHORUS_PHASE),
641 DECL(AL_CHORUS_RATE),
642 DECL(AL_CHORUS_DEPTH),
643 DECL(AL_CHORUS_FEEDBACK),
644 DECL(AL_CHORUS_DELAY),
646 DECL(AL_DISTORTION_EDGE),
647 DECL(AL_DISTORTION_GAIN),
648 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
649 DECL(AL_DISTORTION_EQCENTER),
650 DECL(AL_DISTORTION_EQBANDWIDTH),
652 DECL(AL_ECHO_DELAY),
653 DECL(AL_ECHO_LRDELAY),
654 DECL(AL_ECHO_DAMPING),
655 DECL(AL_ECHO_FEEDBACK),
656 DECL(AL_ECHO_SPREAD),
658 DECL(AL_FLANGER_WAVEFORM),
659 DECL(AL_FLANGER_PHASE),
660 DECL(AL_FLANGER_RATE),
661 DECL(AL_FLANGER_DEPTH),
662 DECL(AL_FLANGER_FEEDBACK),
663 DECL(AL_FLANGER_DELAY),
665 DECL(AL_RING_MODULATOR_FREQUENCY),
666 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
667 DECL(AL_RING_MODULATOR_WAVEFORM),
669 #if 0
670 DECL(AL_AUTOWAH_ATTACK_TIME),
671 DECL(AL_AUTOWAH_PEAK_GAIN),
672 DECL(AL_AUTOWAH_RELEASE_TIME),
673 DECL(AL_AUTOWAH_RESONANCE),
674 #endif
676 DECL(AL_COMPRESSOR_ONOFF),
678 DECL(AL_EQUALIZER_LOW_GAIN),
679 DECL(AL_EQUALIZER_LOW_CUTOFF),
680 DECL(AL_EQUALIZER_MID1_GAIN),
681 DECL(AL_EQUALIZER_MID1_CENTER),
682 DECL(AL_EQUALIZER_MID1_WIDTH),
683 DECL(AL_EQUALIZER_MID2_GAIN),
684 DECL(AL_EQUALIZER_MID2_CENTER),
685 DECL(AL_EQUALIZER_MID2_WIDTH),
686 DECL(AL_EQUALIZER_HIGH_GAIN),
687 DECL(AL_EQUALIZER_HIGH_CUTOFF),
689 DECL(AL_DEDICATED_GAIN),
691 { NULL, (ALCenum)0 }
693 #undef DECL
695 static const ALCchar alcNoError[] = "No Error";
696 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
697 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
698 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
699 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
700 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
703 /************************************************
704 * Global variables
705 ************************************************/
707 /* Enumerated device names */
708 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
710 static al_string alcAllDevicesList;
711 static al_string alcCaptureDeviceList;
713 /* Default is always the first in the list */
714 static ALCchar *alcDefaultAllDevicesSpecifier;
715 static ALCchar *alcCaptureDefaultDeviceSpecifier;
717 /* Default context extensions */
718 static const ALchar alExtList[] =
719 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
720 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
721 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
722 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
723 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
724 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
725 "AL_SOFT_source_latency AL_SOFT_source_length";
727 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
729 /* Thread-local current context */
730 static altss_t LocalContext;
731 /* Process-wide current context */
732 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
734 /* Mixing thread piority level */
735 ALint RTPrioLevel;
737 FILE *LogFile;
738 #ifdef _DEBUG
739 enum LogLevel LogLevel = LogWarning;
740 #else
741 enum LogLevel LogLevel = LogError;
742 #endif
744 /* Flag to trap ALC device errors */
745 static ALCboolean TrapALCError = ALC_FALSE;
747 /* One-time configuration init control */
748 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
750 /* Default effect that applies to sources that don't have an effect on send 0 */
751 static ALeffect DefaultEffect;
753 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
754 * updates.
756 static ALCboolean SuspendDefers = ALC_TRUE;
759 /************************************************
760 * ALC information
761 ************************************************/
762 static const ALCchar alcNoDeviceExtList[] =
763 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
764 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
765 static const ALCchar alcExtensionList[] =
766 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
767 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
768 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
769 "ALC_SOFT_loopback ALC_SOFT_pause_device";
770 static const ALCint alcMajorVersion = 1;
771 static const ALCint alcMinorVersion = 1;
773 static const ALCint alcEFXMajorVersion = 1;
774 static const ALCint alcEFXMinorVersion = 0;
777 /************************************************
778 * Device lists
779 ************************************************/
780 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
782 static almtx_t ListLock;
783 static inline void LockLists(void)
785 int lockret = almtx_lock(&ListLock);
786 assert(lockret == althrd_success);
788 static inline void UnlockLists(void)
790 int unlockret = almtx_unlock(&ListLock);
791 assert(unlockret == althrd_success);
794 /************************************************
795 * Library initialization
796 ************************************************/
797 #if defined(_WIN32)
798 static void alc_init(void);
799 static void alc_deinit(void);
800 static void alc_deinit_safe(void);
802 #ifndef AL_LIBTYPE_STATIC
803 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
805 switch(reason)
807 case DLL_PROCESS_ATTACH:
808 /* Pin the DLL so we won't get unloaded until the process terminates */
809 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
810 (WCHAR*)hModule, &hModule);
811 alc_init();
812 break;
814 case DLL_THREAD_DETACH:
815 break;
817 case DLL_PROCESS_DETACH:
818 if(!lpReserved)
819 alc_deinit();
820 else
821 alc_deinit_safe();
822 break;
824 return TRUE;
826 #elif defined(_MSC_VER)
827 #pragma section(".CRT$XCU",read)
828 static void alc_constructor(void);
829 static void alc_destructor(void);
830 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
832 static void alc_constructor(void)
834 atexit(alc_destructor);
835 alc_init();
838 static void alc_destructor(void)
840 alc_deinit();
842 #elif defined(HAVE_GCC_DESTRUCTOR)
843 static void alc_init(void) __attribute__((constructor));
844 static void alc_deinit(void) __attribute__((destructor));
845 #else
846 #error "No static initialization available on this platform!"
847 #endif
849 #elif defined(HAVE_GCC_DESTRUCTOR)
851 static void alc_init(void) __attribute__((constructor));
852 static void alc_deinit(void) __attribute__((destructor));
854 #else
855 #error "No global initialization available on this platform!"
856 #endif
858 static void ReleaseThreadCtx(void *ptr);
859 static void alc_init(void)
861 const char *str;
862 int ret;
864 LogFile = stderr;
866 AL_STRING_INIT(alcAllDevicesList);
867 AL_STRING_INIT(alcCaptureDeviceList);
869 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
870 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
871 ConeScale *= 0.5f;
873 str = getenv("__ALSOFT_REVERSE_Z");
874 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
875 ZScale *= -1.0f;
877 ret = altss_create(&LocalContext, ReleaseThreadCtx);
878 assert(ret == althrd_success);
880 ret = almtx_init(&ListLock, almtx_recursive);
881 assert(ret == althrd_success);
883 ThunkInit();
886 static void alc_initconfig(void)
888 const char *devs, *str;
889 ALuint capfilter;
890 float valf;
891 int i, n;
893 str = getenv("ALSOFT_LOGLEVEL");
894 if(str)
896 long lvl = strtol(str, NULL, 0);
897 if(lvl >= NoLog && lvl <= LogRef)
898 LogLevel = lvl;
901 str = getenv("ALSOFT_LOGFILE");
902 if(str && str[0])
904 FILE *logfile = al_fopen(str, "wt");
905 if(logfile) LogFile = logfile;
906 else ERR("Failed to open log file '%s'\n", str);
910 char buf[1024] = "";
911 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
912 for(i = 1;BackendList[i].name;i++)
913 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
914 TRACE("Supported backends: %s\n", buf);
916 ReadALConfig();
918 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
919 if(str && *str)
921 if(strcasecmp(str, "ignore") == 0)
923 SuspendDefers = ALC_FALSE;
924 TRACE("Selected context suspend behavior, \"ignore\"\n");
926 else
927 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
930 capfilter = 0;
931 #if defined(HAVE_SSE4_1)
932 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
933 #elif defined(HAVE_SSE3)
934 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
935 #elif defined(HAVE_SSE2)
936 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
937 #elif defined(HAVE_SSE)
938 capfilter |= CPU_CAP_SSE;
939 #endif
940 #ifdef HAVE_NEON
941 capfilter |= CPU_CAP_NEON;
942 #endif
943 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
945 if(strcasecmp(str, "all") == 0)
946 capfilter = 0;
947 else
949 size_t len;
950 const char *next = str;
952 do {
953 str = next;
954 while(isspace(str[0]))
955 str++;
956 next = strchr(str, ',');
958 if(!str[0] || str[0] == ',')
959 continue;
961 len = (next ? ((size_t)(next-str)) : strlen(str));
962 while(len > 0 && isspace(str[len-1]))
963 len--;
964 if(len == 3 && strncasecmp(str, "sse", len) == 0)
965 capfilter &= ~CPU_CAP_SSE;
966 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
967 capfilter &= ~CPU_CAP_SSE2;
968 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
969 capfilter &= ~CPU_CAP_SSE3;
970 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
971 capfilter &= ~CPU_CAP_SSE4_1;
972 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
973 capfilter &= ~CPU_CAP_NEON;
974 else
975 WARN("Invalid CPU extension \"%s\"\n", str);
976 } while(next++);
979 FillCPUCaps(capfilter);
981 #ifdef _WIN32
982 RTPrioLevel = 1;
983 #else
984 RTPrioLevel = 0;
985 #endif
986 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
988 aluInitMixer();
990 str = getenv("ALSOFT_TRAP_ERROR");
991 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
993 TrapALError = AL_TRUE;
994 TrapALCError = AL_TRUE;
996 else
998 str = getenv("ALSOFT_TRAP_AL_ERROR");
999 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1000 TrapALError = AL_TRUE;
1001 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1003 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1004 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1005 TrapALCError = ALC_TRUE;
1006 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1009 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1010 ReverbBoost *= powf(10.0f, valf / 20.0f);
1012 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1014 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1015 ConfigValueStr(NULL, NULL, "drivers", &devs))
1017 int n;
1018 size_t len;
1019 const char *next = devs;
1020 int endlist, delitem;
1022 i = 0;
1023 do {
1024 devs = next;
1025 while(isspace(devs[0]))
1026 devs++;
1027 next = strchr(devs, ',');
1029 delitem = (devs[0] == '-');
1030 if(devs[0] == '-') devs++;
1032 if(!devs[0] || devs[0] == ',')
1034 endlist = 0;
1035 continue;
1037 endlist = 1;
1039 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1040 while(len > 0 && isspace(devs[len-1]))
1041 len--;
1042 for(n = i;BackendList[n].name;n++)
1044 if(len == strlen(BackendList[n].name) &&
1045 strncmp(BackendList[n].name, devs, len) == 0)
1047 if(delitem)
1049 do {
1050 BackendList[n] = BackendList[n+1];
1051 ++n;
1052 } while(BackendList[n].name);
1054 else
1056 struct BackendInfo Bkp = BackendList[n];
1057 while(n > i)
1059 BackendList[n] = BackendList[n-1];
1060 --n;
1062 BackendList[n] = Bkp;
1064 i++;
1066 break;
1069 } while(next++);
1071 if(endlist)
1073 BackendList[i].name = NULL;
1074 BackendList[i].getFactory = NULL;
1075 BackendList[i].Init = NULL;
1076 BackendList[i].Deinit = NULL;
1077 BackendList[i].Probe = NULL;
1081 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1083 if(BackendList[i].getFactory)
1085 ALCbackendFactory *factory = BackendList[i].getFactory();
1086 if(!V0(factory,init)())
1088 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1089 continue;
1092 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1093 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1095 PlaybackBackend = BackendList[i];
1096 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1098 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1100 CaptureBackend = BackendList[i];
1101 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1104 continue;
1107 if(!BackendList[i].Init(&BackendList[i].Funcs))
1109 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1110 continue;
1113 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1114 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1116 PlaybackBackend = BackendList[i];
1117 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1119 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1121 CaptureBackend = BackendList[i];
1122 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1126 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1127 V0(factory,init)();
1130 if(!PlaybackBackend.name)
1131 WARN("No playback backend available!\n");
1132 if(!CaptureBackend.name)
1133 WARN("No capture backend available!\n");
1135 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1137 size_t len;
1138 const char *next = str;
1140 do {
1141 str = next;
1142 next = strchr(str, ',');
1144 if(!str[0] || next == str)
1145 continue;
1147 len = (next ? ((size_t)(next-str)) : strlen(str));
1148 for(n = 0;EffectList[n].name;n++)
1150 if(len == strlen(EffectList[n].name) &&
1151 strncmp(EffectList[n].name, str, len) == 0)
1152 DisabledEffects[EffectList[n].type] = AL_TRUE;
1154 } while(next++);
1157 InitEffectFactoryMap();
1159 InitEffect(&DefaultEffect);
1160 str = getenv("ALSOFT_DEFAULT_REVERB");
1161 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1162 LoadReverbPreset(str, &DefaultEffect);
1164 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1167 /************************************************
1168 * Library deinitialization
1169 ************************************************/
1170 static void alc_cleanup(void)
1172 ALCdevice *dev;
1174 AL_STRING_DEINIT(alcAllDevicesList);
1175 AL_STRING_DEINIT(alcCaptureDeviceList);
1177 free(alcDefaultAllDevicesSpecifier);
1178 alcDefaultAllDevicesSpecifier = NULL;
1179 free(alcCaptureDefaultDeviceSpecifier);
1180 alcCaptureDefaultDeviceSpecifier = NULL;
1182 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1184 ALCuint num = 0;
1185 do {
1186 num++;
1187 } while((dev=dev->next) != NULL);
1188 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1191 DeinitEffectFactoryMap();
1194 static void alc_deinit_safe(void)
1196 alc_cleanup();
1198 FreeHrtfs();
1199 FreeALConfig();
1201 ThunkExit();
1202 almtx_destroy(&ListLock);
1203 altss_delete(LocalContext);
1205 if(LogFile != stderr)
1206 fclose(LogFile);
1207 LogFile = NULL;
1210 static void alc_deinit(void)
1212 int i;
1214 alc_cleanup();
1216 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1217 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1219 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1221 if(!BackendList[i].getFactory)
1222 BackendList[i].Deinit();
1223 else
1225 ALCbackendFactory *factory = BackendList[i].getFactory();
1226 V0(factory,deinit)();
1230 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1231 V0(factory,deinit)();
1234 alc_deinit_safe();
1238 /************************************************
1239 * Device enumeration
1240 ************************************************/
1241 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1243 DO_INITCONFIG();
1245 LockLists();
1246 al_string_clear(list);
1248 if(backendinfo->Probe)
1249 backendinfo->Probe(type);
1250 else if(backendinfo->getFactory)
1252 ALCbackendFactory *factory = backendinfo->getFactory();
1253 V(factory,probe)(type);
1256 UnlockLists();
1258 static void ProbeAllDevicesList(void)
1259 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1260 static void ProbeCaptureDeviceList(void)
1261 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1263 static void AppendDevice(const ALCchar *name, al_string *devnames)
1265 size_t len = strlen(name);
1266 if(len > 0)
1267 al_string_append_range(devnames, name, name+len+1);
1269 void AppendAllDevicesList(const ALCchar *name)
1270 { AppendDevice(name, &alcAllDevicesList); }
1271 void AppendCaptureDeviceList(const ALCchar *name)
1272 { AppendDevice(name, &alcCaptureDeviceList); }
1275 /************************************************
1276 * Device format information
1277 ************************************************/
1278 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1280 switch(type)
1282 case DevFmtByte: return "Signed Byte";
1283 case DevFmtUByte: return "Unsigned Byte";
1284 case DevFmtShort: return "Signed Short";
1285 case DevFmtUShort: return "Unsigned Short";
1286 case DevFmtInt: return "Signed Int";
1287 case DevFmtUInt: return "Unsigned Int";
1288 case DevFmtFloat: return "Float";
1290 return "(unknown type)";
1292 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1294 switch(chans)
1296 case DevFmtMono: return "Mono";
1297 case DevFmtStereo: return "Stereo";
1298 case DevFmtQuad: return "Quadraphonic";
1299 case DevFmtX51: return "5.1 Surround";
1300 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1301 case DevFmtX61: return "6.1 Surround";
1302 case DevFmtX71: return "7.1 Surround";
1303 case DevFmtBFormat3D: return "B-Format 3D";
1305 return "(unknown channels)";
1308 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1309 ALuint BytesFromDevFmt(enum DevFmtType type)
1311 switch(type)
1313 case DevFmtByte: return sizeof(ALbyte);
1314 case DevFmtUByte: return sizeof(ALubyte);
1315 case DevFmtShort: return sizeof(ALshort);
1316 case DevFmtUShort: return sizeof(ALushort);
1317 case DevFmtInt: return sizeof(ALint);
1318 case DevFmtUInt: return sizeof(ALuint);
1319 case DevFmtFloat: return sizeof(ALfloat);
1321 return 0;
1323 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1325 switch(chans)
1327 case DevFmtMono: return 1;
1328 case DevFmtStereo: return 2;
1329 case DevFmtQuad: return 4;
1330 case DevFmtX51: return 6;
1331 case DevFmtX51Rear: return 6;
1332 case DevFmtX61: return 7;
1333 case DevFmtX71: return 8;
1334 case DevFmtBFormat3D: return 4;
1336 return 0;
1339 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1340 enum DevFmtChannels *chans, enum DevFmtType *type)
1342 static const struct {
1343 ALenum format;
1344 enum DevFmtChannels channels;
1345 enum DevFmtType type;
1346 } list[] = {
1347 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1348 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1349 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1351 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1352 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1353 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1355 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1356 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1357 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1359 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1360 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1361 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1363 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1364 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1365 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1367 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1368 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1369 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1371 ALuint i;
1373 for(i = 0;i < COUNTOF(list);i++)
1375 if(list[i].format == format)
1377 *chans = list[i].channels;
1378 *type = list[i].type;
1379 return AL_TRUE;
1383 return AL_FALSE;
1386 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1388 switch(type)
1390 case ALC_BYTE_SOFT:
1391 case ALC_UNSIGNED_BYTE_SOFT:
1392 case ALC_SHORT_SOFT:
1393 case ALC_UNSIGNED_SHORT_SOFT:
1394 case ALC_INT_SOFT:
1395 case ALC_UNSIGNED_INT_SOFT:
1396 case ALC_FLOAT_SOFT:
1397 return ALC_TRUE;
1399 return ALC_FALSE;
1402 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1404 switch(channels)
1406 case ALC_MONO_SOFT:
1407 case ALC_STEREO_SOFT:
1408 case ALC_QUAD_SOFT:
1409 case ALC_5POINT1_SOFT:
1410 case ALC_6POINT1_SOFT:
1411 case ALC_7POINT1_SOFT:
1412 return ALC_TRUE;
1414 return ALC_FALSE;
1418 /************************************************
1419 * Miscellaneous ALC helpers
1420 ************************************************/
1422 extern inline void LockContext(ALCcontext *context);
1423 extern inline void UnlockContext(ALCcontext *context);
1425 void ALCdevice_Lock(ALCdevice *device)
1427 V0(device->Backend,lock)();
1430 void ALCdevice_Unlock(ALCdevice *device)
1432 V0(device->Backend,unlock)();
1436 /* SetDefaultWFXChannelOrder
1438 * Sets the default channel order used by WaveFormatEx.
1440 void SetDefaultWFXChannelOrder(ALCdevice *device)
1442 ALuint i;
1444 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1445 device->RealOut.ChannelName[i] = InvalidChannel;
1447 switch(device->FmtChans)
1449 case DevFmtMono:
1450 device->RealOut.ChannelName[0] = FrontCenter;
1451 break;
1452 case DevFmtStereo:
1453 device->RealOut.ChannelName[0] = FrontLeft;
1454 device->RealOut.ChannelName[1] = FrontRight;
1455 break;
1456 case DevFmtQuad:
1457 device->RealOut.ChannelName[0] = FrontLeft;
1458 device->RealOut.ChannelName[1] = FrontRight;
1459 device->RealOut.ChannelName[2] = BackLeft;
1460 device->RealOut.ChannelName[3] = BackRight;
1461 break;
1462 case DevFmtX51:
1463 device->RealOut.ChannelName[0] = FrontLeft;
1464 device->RealOut.ChannelName[1] = FrontRight;
1465 device->RealOut.ChannelName[2] = FrontCenter;
1466 device->RealOut.ChannelName[3] = LFE;
1467 device->RealOut.ChannelName[4] = SideLeft;
1468 device->RealOut.ChannelName[5] = SideRight;
1469 break;
1470 case DevFmtX51Rear:
1471 device->RealOut.ChannelName[0] = FrontLeft;
1472 device->RealOut.ChannelName[1] = FrontRight;
1473 device->RealOut.ChannelName[2] = FrontCenter;
1474 device->RealOut.ChannelName[3] = LFE;
1475 device->RealOut.ChannelName[4] = BackLeft;
1476 device->RealOut.ChannelName[5] = BackRight;
1477 break;
1478 case DevFmtX61:
1479 device->RealOut.ChannelName[0] = FrontLeft;
1480 device->RealOut.ChannelName[1] = FrontRight;
1481 device->RealOut.ChannelName[2] = FrontCenter;
1482 device->RealOut.ChannelName[3] = LFE;
1483 device->RealOut.ChannelName[4] = BackCenter;
1484 device->RealOut.ChannelName[5] = SideLeft;
1485 device->RealOut.ChannelName[6] = SideRight;
1486 break;
1487 case DevFmtX71:
1488 device->RealOut.ChannelName[0] = FrontLeft;
1489 device->RealOut.ChannelName[1] = FrontRight;
1490 device->RealOut.ChannelName[2] = FrontCenter;
1491 device->RealOut.ChannelName[3] = LFE;
1492 device->RealOut.ChannelName[4] = BackLeft;
1493 device->RealOut.ChannelName[5] = BackRight;
1494 device->RealOut.ChannelName[6] = SideLeft;
1495 device->RealOut.ChannelName[7] = SideRight;
1496 break;
1497 case DevFmtBFormat3D:
1498 device->RealOut.ChannelName[0] = Aux0;
1499 device->RealOut.ChannelName[1] = Aux1;
1500 device->RealOut.ChannelName[2] = Aux2;
1501 device->RealOut.ChannelName[3] = Aux3;
1502 break;
1506 /* SetDefaultChannelOrder
1508 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1510 void SetDefaultChannelOrder(ALCdevice *device)
1512 ALuint i;
1514 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1515 device->RealOut.ChannelName[i] = InvalidChannel;
1517 switch(device->FmtChans)
1519 case DevFmtX51Rear:
1520 device->RealOut.ChannelName[0] = FrontLeft;
1521 device->RealOut.ChannelName[1] = FrontRight;
1522 device->RealOut.ChannelName[2] = BackLeft;
1523 device->RealOut.ChannelName[3] = BackRight;
1524 device->RealOut.ChannelName[4] = FrontCenter;
1525 device->RealOut.ChannelName[5] = LFE;
1526 return;
1527 case DevFmtX71:
1528 device->RealOut.ChannelName[0] = FrontLeft;
1529 device->RealOut.ChannelName[1] = FrontRight;
1530 device->RealOut.ChannelName[2] = BackLeft;
1531 device->RealOut.ChannelName[3] = BackRight;
1532 device->RealOut.ChannelName[4] = FrontCenter;
1533 device->RealOut.ChannelName[5] = LFE;
1534 device->RealOut.ChannelName[6] = SideLeft;
1535 device->RealOut.ChannelName[7] = SideRight;
1536 return;
1538 /* Same as WFX order */
1539 case DevFmtMono:
1540 case DevFmtStereo:
1541 case DevFmtQuad:
1542 case DevFmtX51:
1543 case DevFmtX61:
1544 case DevFmtBFormat3D:
1545 SetDefaultWFXChannelOrder(device);
1546 break;
1550 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1553 /* ALCcontext_DeferUpdates
1555 * Defers/suspends updates for the given context's listener and sources. This
1556 * does *NOT* stop mixing, but rather prevents certain property changes from
1557 * taking effect.
1559 void ALCcontext_DeferUpdates(ALCcontext *context)
1561 ALCdevice *device = context->Device;
1562 FPUCtl oldMode;
1564 SetMixerFPUMode(&oldMode);
1566 V0(device->Backend,lock)();
1567 if(!context->DeferUpdates)
1569 context->DeferUpdates = AL_TRUE;
1571 /* Make sure all pending updates are performed */
1572 UpdateContextSources(context);
1574 V0(device->Backend,unlock)();
1576 RestoreFPUMode(&oldMode);
1579 /* ALCcontext_ProcessUpdates
1581 * Resumes update processing after being deferred.
1583 void ALCcontext_ProcessUpdates(ALCcontext *context)
1585 ALCdevice *device = context->Device;
1587 V0(device->Backend,lock)();
1588 if(context->DeferUpdates)
1590 ALsizei pos;
1592 context->DeferUpdates = AL_FALSE;
1594 LockUIntMapRead(&context->SourceMap);
1595 for(pos = 0;pos < context->SourceMap.size;pos++)
1597 ALsource *Source = context->SourceMap.array[pos].value;
1598 ALenum new_state;
1600 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1601 Source->OffsetType != AL_NONE)
1603 WriteLock(&Source->queue_lock);
1604 ApplyOffset(Source);
1605 WriteUnlock(&Source->queue_lock);
1608 new_state = Source->new_state;
1609 Source->new_state = AL_NONE;
1610 if(new_state)
1611 SetSourceState(Source, context, new_state);
1613 UnlockUIntMapRead(&context->SourceMap);
1615 V0(device->Backend,unlock)();
1619 /* alcSetError
1621 * Stores the latest ALC device error
1623 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1625 if(TrapALCError)
1627 #ifdef _WIN32
1628 /* DebugBreak() will cause an exception if there is no debugger */
1629 if(IsDebuggerPresent())
1630 DebugBreak();
1631 #elif defined(SIGTRAP)
1632 raise(SIGTRAP);
1633 #endif
1636 if(device)
1637 ATOMIC_STORE(&device->LastError, errorCode);
1638 else
1639 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1643 /* UpdateClockBase
1645 * Updates the device's base clock time with however many samples have been
1646 * done. This is used so frequency changes on the device don't cause the time
1647 * to jump forward or back.
1649 static inline void UpdateClockBase(ALCdevice *device)
1651 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1652 device->SamplesDone = 0;
1655 /* UpdateDeviceParams
1657 * Updates device parameters according to the attribute list (caller is
1658 * responsible for holding the list lock).
1660 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1662 ALCcontext *context;
1663 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1664 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1665 enum DevFmtChannels oldChans;
1666 enum DevFmtType oldType;
1667 ALCuint oldFreq;
1668 FPUCtl oldMode;
1669 ALCsizei hrtf_id = -1;
1670 size_t size;
1672 // Check for attributes
1673 if(device->Type == Loopback)
1675 enum {
1676 GotFreq = 1<<0,
1677 GotChans = 1<<1,
1678 GotType = 1<<2,
1679 GotAll = GotFreq|GotChans|GotType
1681 ALCuint freq, numMono, numStereo, numSends;
1682 enum DevFmtChannels schans;
1683 enum DevFmtType stype;
1684 ALCuint attrIdx = 0;
1685 ALCint gotFmt = 0;
1687 if(!attrList)
1689 WARN("Missing attributes for loopback device\n");
1690 return ALC_INVALID_VALUE;
1693 numMono = device->NumMonoSources;
1694 numStereo = device->NumStereoSources;
1695 numSends = device->NumAuxSends;
1696 schans = device->FmtChans;
1697 stype = device->FmtType;
1698 freq = device->Frequency;
1700 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1701 while(attrList[attrIdx])
1703 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1705 ALCint val = attrList[attrIdx + 1];
1706 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, val);
1707 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1708 return ALC_INVALID_VALUE;
1709 schans = val;
1710 gotFmt |= GotChans;
1713 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1715 ALCint val = attrList[attrIdx + 1];
1716 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, val);
1717 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1718 return ALC_INVALID_VALUE;
1719 stype = val;
1720 gotFmt |= GotType;
1723 if(attrList[attrIdx] == ALC_FREQUENCY)
1725 freq = attrList[attrIdx + 1];
1726 TRACE_ATTR(ALC_FREQUENCY, freq);
1727 if(freq < MIN_OUTPUT_RATE)
1728 return ALC_INVALID_VALUE;
1729 gotFmt |= GotFreq;
1732 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1734 numStereo = attrList[attrIdx + 1];
1735 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1736 if(numStereo > device->MaxNoOfSources)
1737 numStereo = device->MaxNoOfSources;
1739 numMono = device->MaxNoOfSources - numStereo;
1742 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1744 numSends = attrList[attrIdx + 1];
1745 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1748 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1750 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1751 if(attrList[attrIdx + 1] == ALC_FALSE)
1752 hrtf_appreq = Hrtf_Disable;
1753 else if(attrList[attrIdx + 1] == ALC_TRUE)
1754 hrtf_appreq = Hrtf_Enable;
1755 else
1756 hrtf_appreq = Hrtf_Default;
1759 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1761 hrtf_id = attrList[attrIdx + 1];
1762 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1765 attrIdx += 2;
1767 #undef TRACE_ATTR
1769 if(gotFmt != GotAll)
1771 WARN("Missing format for loopback device\n");
1772 return ALC_INVALID_VALUE;
1775 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1776 numSends = minu(MAX_SENDS, numSends);
1778 if((device->Flags&DEVICE_RUNNING))
1779 V0(device->Backend,stop)();
1780 device->Flags &= ~DEVICE_RUNNING;
1782 UpdateClockBase(device);
1784 device->Frequency = freq;
1785 device->FmtChans = schans;
1786 device->FmtType = stype;
1787 device->NumMonoSources = numMono;
1788 device->NumStereoSources = numStereo;
1789 device->NumAuxSends = numSends;
1791 else if(attrList && attrList[0])
1793 ALCuint freq, numMono, numStereo, numSends;
1794 ALCuint attrIdx = 0;
1796 /* If a context is already running on the device, stop playback so the
1797 * device attributes can be updated. */
1798 if((device->Flags&DEVICE_RUNNING))
1799 V0(device->Backend,stop)();
1800 device->Flags &= ~DEVICE_RUNNING;
1802 freq = device->Frequency;
1803 numMono = device->NumMonoSources;
1804 numStereo = device->NumStereoSources;
1805 numSends = device->NumAuxSends;
1807 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1808 while(attrList[attrIdx])
1810 if(attrList[attrIdx] == ALC_FREQUENCY)
1812 freq = attrList[attrIdx + 1];
1813 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1814 TRACE_ATTR(ALC_FREQUENCY, freq);
1817 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1819 numStereo = attrList[attrIdx + 1];
1820 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1821 if(numStereo > device->MaxNoOfSources)
1822 numStereo = device->MaxNoOfSources;
1824 numMono = device->MaxNoOfSources - numStereo;
1827 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1829 numSends = attrList[attrIdx + 1];
1830 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1833 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1835 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1836 if(attrList[attrIdx + 1] == ALC_FALSE)
1837 hrtf_appreq = Hrtf_Disable;
1838 else if(attrList[attrIdx + 1] == ALC_TRUE)
1839 hrtf_appreq = Hrtf_Enable;
1840 else
1841 hrtf_appreq = Hrtf_Default;
1844 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1846 hrtf_id = attrList[attrIdx + 1];
1847 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1850 attrIdx += 2;
1852 #undef TRACE_ATTR
1854 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1855 freq = maxu(freq, MIN_OUTPUT_RATE);
1857 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1858 numSends = minu(MAX_SENDS, numSends);
1860 UpdateClockBase(device);
1862 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1863 device->Frequency;
1864 /* SSE and Neon do best with the update size being a multiple of 4 */
1865 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1866 device->UpdateSize = (device->UpdateSize+3)&~3;
1868 device->Frequency = freq;
1869 device->NumMonoSources = numMono;
1870 device->NumStereoSources = numStereo;
1871 device->NumAuxSends = numSends;
1874 if((device->Flags&DEVICE_RUNNING))
1875 return ALC_NO_ERROR;
1877 al_free(device->Uhj_Encoder);
1878 device->Uhj_Encoder = NULL;
1880 al_free(device->Bs2b);
1881 device->Bs2b = NULL;
1883 al_free(device->Dry.Buffer);
1884 device->Dry.Buffer = NULL;
1885 device->Dry.NumChannels = 0;
1886 device->VirtOut.Buffer = NULL;
1887 device->VirtOut.NumChannels = 0;
1888 device->RealOut.Buffer = NULL;
1889 device->RealOut.NumChannels = 0;
1891 UpdateClockBase(device);
1893 /*************************************************************************
1894 * Update device format request if HRTF is requested
1896 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1897 if(device->Type != Loopback)
1899 const char *hrtf;
1900 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1902 if(strcasecmp(hrtf, "true") == 0)
1903 hrtf_userreq = Hrtf_Enable;
1904 else if(strcasecmp(hrtf, "false") == 0)
1905 hrtf_userreq = Hrtf_Disable;
1906 else if(strcasecmp(hrtf, "auto") != 0)
1907 ERR("Unexpected hrtf value: %s\n", hrtf);
1910 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1912 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1914 VECTOR_DEINIT(device->Hrtf_List);
1915 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1917 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1919 device->FmtChans = DevFmtStereo;
1920 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1921 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1922 else
1923 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1924 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1926 else
1928 hrtf_userreq = Hrtf_Default;
1929 hrtf_appreq = Hrtf_Disable;
1930 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1934 else if(hrtf_appreq == Hrtf_Enable)
1936 size_t i = VECTOR_SIZE(device->Hrtf_List);
1937 /* Loopback device. We don't need to match to a specific HRTF entry
1938 * here. If the requested ID matches, we'll pick that later, if not,
1939 * we'll try to auto-select one anyway. Just make sure one exists
1940 * that'll work.
1942 if(device->FmtChans == DevFmtStereo)
1944 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1946 VECTOR_DEINIT(device->Hrtf_List);
1947 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1949 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1951 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1952 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1953 break;
1956 if(i == VECTOR_SIZE(device->Hrtf_List))
1958 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1959 DevFmtChannelsString(device->FmtChans), device->Frequency);
1960 hrtf_appreq = Hrtf_Disable;
1961 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1965 oldFreq = device->Frequency;
1966 oldChans = device->FmtChans;
1967 oldType = device->FmtType;
1969 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1970 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1971 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1972 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1973 device->UpdateSize, device->NumUpdates
1976 if(V0(device->Backend,reset)() == ALC_FALSE)
1977 return ALC_INVALID_DEVICE;
1979 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1981 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1982 DevFmtChannelsString(device->FmtChans));
1983 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1985 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1987 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1988 DevFmtTypeString(device->FmtType));
1989 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1991 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1993 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1994 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1997 if((device->UpdateSize&3) != 0)
1999 if((CPUCapFlags&CPU_CAP_SSE))
2000 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2001 if((CPUCapFlags&CPU_CAP_NEON))
2002 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2005 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2006 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2007 device->Frequency, device->UpdateSize, device->NumUpdates
2010 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2012 /* Allocate extra channels for any post-filter output. */
2013 size = device->Dry.NumChannels * sizeof(device->Dry.Buffer[0]);
2014 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2015 size += (ChannelsFromDevFmt(device->FmtChans)+4) * sizeof(device->Dry.Buffer[0]);
2016 else if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2017 size += ChannelsFromDevFmt(device->FmtChans) * sizeof(device->Dry.Buffer[0]);
2018 device->Dry.Buffer = al_calloc(16, size);
2019 if(!device->Dry.Buffer)
2021 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2022 return ALC_INVALID_DEVICE;
2025 if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2027 device->VirtOut.Buffer = device->Dry.Buffer;
2028 device->VirtOut.NumChannels = device->Dry.NumChannels;
2029 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2030 device->RealOut.NumChannels = ChannelsFromDevFmt(device->FmtChans);
2032 else
2034 device->VirtOut.Buffer = NULL;
2035 device->VirtOut.NumChannels = 0;
2036 device->RealOut.Buffer = device->Dry.Buffer;
2037 device->RealOut.NumChannels = device->Dry.NumChannels;
2040 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2042 /* Higher-order high quality decoding requires upsampling first-order
2043 * content, so make sure to mix it separately.
2045 device->FOAOut.Buffer = device->RealOut.Buffer + device->RealOut.NumChannels;
2046 device->FOAOut.NumChannels = 4;
2048 else
2050 device->FOAOut.Buffer = device->Dry.Buffer;
2051 device->FOAOut.NumChannels = device->Dry.NumChannels;
2054 SetMixerFPUMode(&oldMode);
2055 V0(device->Backend,lock)();
2056 if(device->DefaultSlot)
2058 ALeffectslot *slot = device->DefaultSlot;
2059 ALeffectState *state = slot->Params.EffectState;
2061 state->OutBuffer = device->Dry.Buffer;
2062 state->OutChannels = device->Dry.NumChannels;
2063 if(V(state,deviceUpdate)(device) == AL_FALSE)
2065 V0(device->Backend,unlock)();
2066 RestoreFPUMode(&oldMode);
2067 return ALC_INVALID_DEVICE;
2069 UpdateEffectSlotProps(slot);
2072 context = ATOMIC_LOAD(&device->ContextList);
2073 while(context)
2075 ALsizei pos;
2077 LockUIntMapRead(&context->EffectSlotMap);
2078 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2080 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2082 slot->Params.EffectState->OutBuffer = device->Dry.Buffer;
2083 slot->Params.EffectState->OutChannels = device->Dry.NumChannels;
2084 if(V(slot->Params.EffectState,deviceUpdate)(device) == AL_FALSE)
2086 UnlockUIntMapRead(&context->EffectSlotMap);
2087 V0(device->Backend,unlock)();
2088 RestoreFPUMode(&oldMode);
2089 return ALC_INVALID_DEVICE;
2091 UpdateEffectSlotProps(slot);
2093 UnlockUIntMapRead(&context->EffectSlotMap);
2095 LockUIntMapRead(&context->SourceMap);
2096 for(pos = 0;pos < context->SourceMap.size;pos++)
2098 ALsource *source = context->SourceMap.array[pos].value;
2099 ALuint s = device->NumAuxSends;
2100 while(s < MAX_SENDS)
2102 if(source->Send[s].Slot)
2103 DecrementRef(&source->Send[s].Slot->ref);
2104 source->Send[s].Slot = NULL;
2105 source->Send[s].Gain = 1.0f;
2106 source->Send[s].GainHF = 1.0f;
2107 s++;
2109 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2111 UnlockUIntMapRead(&context->SourceMap);
2113 for(pos = 0;pos < context->VoiceCount;pos++)
2115 ALvoice *voice = &context->Voices[pos];
2116 ALsource *source = voice->Source;
2117 ALbufferlistitem *BufferListItem;
2119 if(!source)
2120 continue;
2122 BufferListItem = ATOMIC_LOAD(&source->queue);
2123 while(BufferListItem != NULL)
2125 ALbuffer *buffer;
2126 if((buffer=BufferListItem->buffer) != NULL)
2128 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2129 voice->Update(voice, source, buffer, context);
2130 break;
2132 BufferListItem = BufferListItem->next;
2136 context = context->next;
2138 V0(device->Backend,unlock)();
2139 RestoreFPUMode(&oldMode);
2141 if(!(device->Flags&DEVICE_PAUSED))
2143 if(V0(device->Backend,start)() == ALC_FALSE)
2144 return ALC_INVALID_DEVICE;
2145 device->Flags |= DEVICE_RUNNING;
2148 return ALC_NO_ERROR;
2151 /* FreeDevice
2153 * Frees the device structure, and destroys any objects the app failed to
2154 * delete. Called once there's no more references on the device.
2156 static ALCvoid FreeDevice(ALCdevice *device)
2158 TRACE("%p\n", device);
2160 V0(device->Backend,close)();
2161 DELETE_OBJ(device->Backend);
2162 device->Backend = NULL;
2164 if(device->DefaultSlot)
2166 DeinitEffectSlot(device->DefaultSlot);
2167 device->DefaultSlot = NULL;
2170 if(device->BufferMap.size > 0)
2172 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2173 ReleaseALBuffers(device);
2175 ResetUIntMap(&device->BufferMap);
2177 if(device->EffectMap.size > 0)
2179 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2180 ReleaseALEffects(device);
2182 ResetUIntMap(&device->EffectMap);
2184 if(device->FilterMap.size > 0)
2186 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2187 ReleaseALFilters(device);
2189 ResetUIntMap(&device->FilterMap);
2191 AL_STRING_DEINIT(device->Hrtf_Name);
2192 FreeHrtfList(&device->Hrtf_List);
2194 al_free(device->Bs2b);
2195 device->Bs2b = NULL;
2197 al_free(device->Uhj_Encoder);
2198 device->Uhj_Encoder = NULL;
2200 bformatdec_free(device->AmbiDecoder);
2201 device->AmbiDecoder = NULL;
2203 AL_STRING_DEINIT(device->DeviceName);
2205 al_free(device->Dry.Buffer);
2206 device->Dry.Buffer = NULL;
2207 device->Dry.NumChannels = 0;
2208 device->VirtOut.Buffer = NULL;
2209 device->VirtOut.NumChannels = 0;
2210 device->RealOut.Buffer = NULL;
2211 device->RealOut.NumChannels = 0;
2213 al_free(device);
2217 void ALCdevice_IncRef(ALCdevice *device)
2219 uint ref;
2220 ref = IncrementRef(&device->ref);
2221 TRACEREF("%p increasing refcount to %u\n", device, ref);
2224 void ALCdevice_DecRef(ALCdevice *device)
2226 uint ref;
2227 ref = DecrementRef(&device->ref);
2228 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2229 if(ref == 0) FreeDevice(device);
2232 /* VerifyDevice
2234 * Checks if the device handle is valid, and increments its ref count if so.
2236 static ALCboolean VerifyDevice(ALCdevice **device)
2238 ALCdevice *tmpDevice;
2240 LockLists();
2241 tmpDevice = ATOMIC_LOAD(&DeviceList);
2242 while(tmpDevice)
2244 if(tmpDevice == *device)
2246 ALCdevice_IncRef(tmpDevice);
2247 UnlockLists();
2248 return ALC_TRUE;
2250 tmpDevice = tmpDevice->next;
2252 UnlockLists();
2254 *device = NULL;
2255 return ALC_FALSE;
2259 /* InitContext
2261 * Initializes context fields
2263 static ALvoid InitContext(ALCcontext *Context)
2265 ALlistener *listener = Context->Listener;
2267 //Initialise listener
2268 listener->Gain = 1.0f;
2269 listener->MetersPerUnit = 1.0f;
2270 listener->Position[0] = 0.0f;
2271 listener->Position[1] = 0.0f;
2272 listener->Position[2] = 0.0f;
2273 listener->Velocity[0] = 0.0f;
2274 listener->Velocity[1] = 0.0f;
2275 listener->Velocity[2] = 0.0f;
2276 listener->Forward[0] = 0.0f;
2277 listener->Forward[1] = 0.0f;
2278 listener->Forward[2] = -1.0f;
2279 listener->Up[0] = 0.0f;
2280 listener->Up[1] = 1.0f;
2281 listener->Up[2] = 0.0f;
2283 aluMatrixdSet(&listener->Params.Matrix,
2284 1.0, 0.0, 0.0, 0.0,
2285 0.0, 1.0, 0.0, 0.0,
2286 0.0, 0.0, 1.0, 0.0,
2287 0.0, 0.0, 0.0, 1.0
2289 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2290 listener->Params.Gain = 1.0f;
2291 listener->Params.MetersPerUnit = 1.0f;
2292 listener->Params.DopplerFactor = 1.0f;
2293 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2295 ATOMIC_INIT(&listener->Update, NULL);
2296 ATOMIC_INIT(&listener->FreeList, NULL);
2298 //Validate Context
2299 RWLockInit(&Context->PropLock);
2300 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2301 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2302 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2304 //Set globals
2305 Context->DistanceModel = DefaultDistanceModel;
2306 Context->SourceDistanceModel = AL_FALSE;
2307 Context->DopplerFactor = 1.0f;
2308 Context->DopplerVelocity = 1.0f;
2309 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2310 Context->DeferUpdates = AL_FALSE;
2312 Context->ExtensionList = alExtList;
2316 /* FreeContext
2318 * Cleans up the context, and destroys any remaining objects the app failed to
2319 * delete. Called once there's no more references on the context.
2321 static void FreeContext(ALCcontext *context)
2323 ALlistener *listener = context->Listener;
2324 struct ALlistenerProps *lprops;
2325 size_t count;
2327 TRACE("%p\n", context);
2329 if(context->SourceMap.size > 0)
2331 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2332 ReleaseALSources(context);
2334 ResetUIntMap(&context->SourceMap);
2336 if(context->EffectSlotMap.size > 0)
2338 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2339 ReleaseALAuxiliaryEffectSlots(context);
2341 ResetUIntMap(&context->EffectSlotMap);
2343 al_free(context->Voices);
2344 context->Voices = NULL;
2345 context->VoiceCount = 0;
2346 context->MaxVoices = 0;
2348 VECTOR_DEINIT(context->ActiveAuxSlots);
2350 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2352 TRACE("Freed unapplied listener update %p\n", lprops);
2353 al_free(lprops);
2355 count = 0;
2356 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_consume);
2357 while(lprops)
2359 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_consume);
2360 al_free(lprops);
2361 lprops = next;
2362 ++count;
2364 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2366 ALCdevice_DecRef(context->Device);
2367 context->Device = NULL;
2369 //Invalidate context
2370 memset(context, 0, sizeof(ALCcontext));
2371 al_free(context);
2374 /* ReleaseContext
2376 * Removes the context reference from the given device and removes it from
2377 * being current on the running thread or globally.
2379 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2381 ALCcontext *nextctx;
2382 ALCcontext *origctx;
2384 if(altss_get(LocalContext) == context)
2386 WARN("%p released while current on thread\n", context);
2387 altss_set(LocalContext, NULL);
2388 ALCcontext_DecRef(context);
2391 origctx = context;
2392 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2393 ALCcontext_DecRef(context);
2395 ALCdevice_Lock(device);
2396 origctx = context;
2397 nextctx = context->next;
2398 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2400 ALCcontext *list;
2401 do {
2402 list = origctx;
2403 origctx = context;
2404 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2406 ALCdevice_Unlock(device);
2408 ALCcontext_DecRef(context);
2411 void ALCcontext_IncRef(ALCcontext *context)
2413 uint ref;
2414 ref = IncrementRef(&context->ref);
2415 TRACEREF("%p increasing refcount to %u\n", context, ref);
2418 void ALCcontext_DecRef(ALCcontext *context)
2420 uint ref;
2421 ref = DecrementRef(&context->ref);
2422 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2423 if(ref == 0) FreeContext(context);
2426 static void ReleaseThreadCtx(void *ptr)
2428 WARN("%p current for thread being destroyed\n", ptr);
2429 ALCcontext_DecRef(ptr);
2432 /* VerifyContext
2434 * Checks that the given context is valid, and increments its reference count.
2436 static ALCboolean VerifyContext(ALCcontext **context)
2438 ALCdevice *dev;
2440 LockLists();
2441 dev = ATOMIC_LOAD(&DeviceList);
2442 while(dev)
2444 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2445 while(ctx)
2447 if(ctx == *context)
2449 ALCcontext_IncRef(ctx);
2450 UnlockLists();
2451 return ALC_TRUE;
2453 ctx = ctx->next;
2455 dev = dev->next;
2457 UnlockLists();
2459 *context = NULL;
2460 return ALC_FALSE;
2464 /* GetContextRef
2466 * Returns the currently active context for this thread, and adds a reference
2467 * without locking it.
2469 ALCcontext *GetContextRef(void)
2471 ALCcontext *context;
2473 context = altss_get(LocalContext);
2474 if(context)
2475 ALCcontext_IncRef(context);
2476 else
2478 LockLists();
2479 context = ATOMIC_LOAD(&GlobalContext);
2480 if(context)
2481 ALCcontext_IncRef(context);
2482 UnlockLists();
2485 return context;
2489 /************************************************
2490 * Standard ALC functions
2491 ************************************************/
2493 /* alcGetError
2495 * Return last ALC generated error code for the given device
2497 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2499 ALCenum errorCode;
2501 if(VerifyDevice(&device))
2503 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2504 ALCdevice_DecRef(device);
2506 else
2507 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2509 return errorCode;
2513 /* alcSuspendContext
2515 * Suspends updates for the given context
2517 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2519 if(!SuspendDefers)
2520 return;
2522 if(!VerifyContext(&context))
2523 alcSetError(NULL, ALC_INVALID_CONTEXT);
2524 else
2526 ALCcontext_DeferUpdates(context);
2527 ALCcontext_DecRef(context);
2531 /* alcProcessContext
2533 * Resumes processing updates for the given context
2535 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2537 if(!SuspendDefers)
2538 return;
2540 if(!VerifyContext(&context))
2541 alcSetError(NULL, ALC_INVALID_CONTEXT);
2542 else
2544 ALCcontext_ProcessUpdates(context);
2545 ALCcontext_DecRef(context);
2550 /* alcGetString
2552 * Returns information about the device, and error strings
2554 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2556 const ALCchar *value = NULL;
2558 switch(param)
2560 case ALC_NO_ERROR:
2561 value = alcNoError;
2562 break;
2564 case ALC_INVALID_ENUM:
2565 value = alcErrInvalidEnum;
2566 break;
2568 case ALC_INVALID_VALUE:
2569 value = alcErrInvalidValue;
2570 break;
2572 case ALC_INVALID_DEVICE:
2573 value = alcErrInvalidDevice;
2574 break;
2576 case ALC_INVALID_CONTEXT:
2577 value = alcErrInvalidContext;
2578 break;
2580 case ALC_OUT_OF_MEMORY:
2581 value = alcErrOutOfMemory;
2582 break;
2584 case ALC_DEVICE_SPECIFIER:
2585 value = alcDefaultName;
2586 break;
2588 case ALC_ALL_DEVICES_SPECIFIER:
2589 if(VerifyDevice(&Device))
2591 value = al_string_get_cstr(Device->DeviceName);
2592 ALCdevice_DecRef(Device);
2594 else
2596 ProbeAllDevicesList();
2597 value = al_string_get_cstr(alcAllDevicesList);
2599 break;
2601 case ALC_CAPTURE_DEVICE_SPECIFIER:
2602 if(VerifyDevice(&Device))
2604 value = al_string_get_cstr(Device->DeviceName);
2605 ALCdevice_DecRef(Device);
2607 else
2609 ProbeCaptureDeviceList();
2610 value = al_string_get_cstr(alcCaptureDeviceList);
2612 break;
2614 /* Default devices are always first in the list */
2615 case ALC_DEFAULT_DEVICE_SPECIFIER:
2616 value = alcDefaultName;
2617 break;
2619 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2620 if(al_string_empty(alcAllDevicesList))
2621 ProbeAllDevicesList();
2623 VerifyDevice(&Device);
2625 free(alcDefaultAllDevicesSpecifier);
2626 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2627 if(!alcDefaultAllDevicesSpecifier)
2628 alcSetError(Device, ALC_OUT_OF_MEMORY);
2630 value = alcDefaultAllDevicesSpecifier;
2631 if(Device) ALCdevice_DecRef(Device);
2632 break;
2634 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2635 if(al_string_empty(alcCaptureDeviceList))
2636 ProbeCaptureDeviceList();
2638 VerifyDevice(&Device);
2640 free(alcCaptureDefaultDeviceSpecifier);
2641 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2642 if(!alcCaptureDefaultDeviceSpecifier)
2643 alcSetError(Device, ALC_OUT_OF_MEMORY);
2645 value = alcCaptureDefaultDeviceSpecifier;
2646 if(Device) ALCdevice_DecRef(Device);
2647 break;
2649 case ALC_EXTENSIONS:
2650 if(!VerifyDevice(&Device))
2651 value = alcNoDeviceExtList;
2652 else
2654 value = alcExtensionList;
2655 ALCdevice_DecRef(Device);
2657 break;
2659 case ALC_HRTF_SPECIFIER_SOFT:
2660 if(!VerifyDevice(&Device))
2661 alcSetError(NULL, ALC_INVALID_DEVICE);
2662 else
2664 LockLists();
2665 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2666 UnlockLists();
2667 ALCdevice_DecRef(Device);
2669 break;
2671 default:
2672 VerifyDevice(&Device);
2673 alcSetError(Device, ALC_INVALID_ENUM);
2674 if(Device) ALCdevice_DecRef(Device);
2675 break;
2678 return value;
2682 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2684 ALCsizei i;
2686 if(size <= 0 || values == NULL)
2688 alcSetError(device, ALC_INVALID_VALUE);
2689 return 0;
2692 if(!device)
2694 switch(param)
2696 case ALC_MAJOR_VERSION:
2697 values[0] = alcMajorVersion;
2698 return 1;
2699 case ALC_MINOR_VERSION:
2700 values[0] = alcMinorVersion;
2701 return 1;
2703 case ALC_ATTRIBUTES_SIZE:
2704 case ALC_ALL_ATTRIBUTES:
2705 case ALC_FREQUENCY:
2706 case ALC_REFRESH:
2707 case ALC_SYNC:
2708 case ALC_MONO_SOURCES:
2709 case ALC_STEREO_SOURCES:
2710 case ALC_CAPTURE_SAMPLES:
2711 case ALC_FORMAT_CHANNELS_SOFT:
2712 case ALC_FORMAT_TYPE_SOFT:
2713 alcSetError(NULL, ALC_INVALID_DEVICE);
2714 return 0;
2716 default:
2717 alcSetError(NULL, ALC_INVALID_ENUM);
2718 return 0;
2720 return 0;
2723 if(device->Type == Capture)
2725 switch(param)
2727 case ALC_CAPTURE_SAMPLES:
2728 V0(device->Backend,lock)();
2729 values[0] = V0(device->Backend,availableSamples)();
2730 V0(device->Backend,unlock)();
2731 return 1;
2733 case ALC_CONNECTED:
2734 values[0] = device->Connected;
2735 return 1;
2737 default:
2738 alcSetError(device, ALC_INVALID_ENUM);
2739 return 0;
2741 return 0;
2744 /* render device */
2745 switch(param)
2747 case ALC_MAJOR_VERSION:
2748 values[0] = alcMajorVersion;
2749 return 1;
2751 case ALC_MINOR_VERSION:
2752 values[0] = alcMinorVersion;
2753 return 1;
2755 case ALC_EFX_MAJOR_VERSION:
2756 values[0] = alcEFXMajorVersion;
2757 return 1;
2759 case ALC_EFX_MINOR_VERSION:
2760 values[0] = alcEFXMinorVersion;
2761 return 1;
2763 case ALC_ATTRIBUTES_SIZE:
2764 values[0] = 17;
2765 return 1;
2767 case ALC_ALL_ATTRIBUTES:
2768 if(size < 17)
2770 alcSetError(device, ALC_INVALID_VALUE);
2771 return 0;
2774 i = 0;
2775 values[i++] = ALC_FREQUENCY;
2776 values[i++] = device->Frequency;
2778 if(device->Type != Loopback)
2780 values[i++] = ALC_REFRESH;
2781 values[i++] = device->Frequency / device->UpdateSize;
2783 values[i++] = ALC_SYNC;
2784 values[i++] = ALC_FALSE;
2786 else
2788 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2789 values[i++] = device->FmtChans;
2791 values[i++] = ALC_FORMAT_TYPE_SOFT;
2792 values[i++] = device->FmtType;
2795 values[i++] = ALC_MONO_SOURCES;
2796 values[i++] = device->NumMonoSources;
2798 values[i++] = ALC_STEREO_SOURCES;
2799 values[i++] = device->NumStereoSources;
2801 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2802 values[i++] = device->NumAuxSends;
2804 values[i++] = ALC_HRTF_SOFT;
2805 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2807 values[i++] = ALC_HRTF_STATUS_SOFT;
2808 values[i++] = device->Hrtf_Status;
2810 values[i++] = 0;
2811 return i;
2813 case ALC_FREQUENCY:
2814 values[0] = device->Frequency;
2815 return 1;
2817 case ALC_REFRESH:
2818 if(device->Type == Loopback)
2820 alcSetError(device, ALC_INVALID_DEVICE);
2821 return 0;
2823 values[0] = device->Frequency / device->UpdateSize;
2824 return 1;
2826 case ALC_SYNC:
2827 if(device->Type == Loopback)
2829 alcSetError(device, ALC_INVALID_DEVICE);
2830 return 0;
2832 values[0] = ALC_FALSE;
2833 return 1;
2835 case ALC_FORMAT_CHANNELS_SOFT:
2836 if(device->Type != Loopback)
2838 alcSetError(device, ALC_INVALID_DEVICE);
2839 return 0;
2841 values[0] = device->FmtChans;
2842 return 1;
2844 case ALC_FORMAT_TYPE_SOFT:
2845 if(device->Type != Loopback)
2847 alcSetError(device, ALC_INVALID_DEVICE);
2848 return 0;
2850 values[0] = device->FmtType;
2851 return 1;
2853 case ALC_MONO_SOURCES:
2854 values[0] = device->NumMonoSources;
2855 return 1;
2857 case ALC_STEREO_SOURCES:
2858 values[0] = device->NumStereoSources;
2859 return 1;
2861 case ALC_MAX_AUXILIARY_SENDS:
2862 values[0] = device->NumAuxSends;
2863 return 1;
2865 case ALC_CONNECTED:
2866 values[0] = device->Connected;
2867 return 1;
2869 case ALC_HRTF_SOFT:
2870 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2871 return 1;
2873 case ALC_HRTF_STATUS_SOFT:
2874 values[0] = device->Hrtf_Status;
2875 return 1;
2877 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2878 FreeHrtfList(&device->Hrtf_List);
2879 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2880 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2881 return 1;
2883 default:
2884 alcSetError(device, ALC_INVALID_ENUM);
2885 return 0;
2887 return 0;
2890 /* alcGetIntegerv
2892 * Returns information about the device and the version of OpenAL
2894 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2896 VerifyDevice(&device);
2897 if(size <= 0 || values == NULL)
2898 alcSetError(device, ALC_INVALID_VALUE);
2899 else
2900 GetIntegerv(device, param, size, values);
2901 if(device) ALCdevice_DecRef(device);
2904 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2906 ALCint *ivals;
2907 ALsizei i;
2909 VerifyDevice(&device);
2910 if(size <= 0 || values == NULL)
2911 alcSetError(device, ALC_INVALID_VALUE);
2912 else if(!device || device->Type == Capture)
2914 ivals = malloc(size * sizeof(ALCint));
2915 size = GetIntegerv(device, pname, size, ivals);
2916 for(i = 0;i < size;i++)
2917 values[i] = ivals[i];
2918 free(ivals);
2920 else /* render device */
2922 switch(pname)
2924 case ALC_ATTRIBUTES_SIZE:
2925 *values = 19;
2926 break;
2928 case ALC_ALL_ATTRIBUTES:
2929 if(size < 19)
2930 alcSetError(device, ALC_INVALID_VALUE);
2931 else
2933 int i = 0;
2935 V0(device->Backend,lock)();
2936 values[i++] = ALC_FREQUENCY;
2937 values[i++] = device->Frequency;
2939 if(device->Type != Loopback)
2941 values[i++] = ALC_REFRESH;
2942 values[i++] = device->Frequency / device->UpdateSize;
2944 values[i++] = ALC_SYNC;
2945 values[i++] = ALC_FALSE;
2947 else
2949 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2950 values[i++] = device->FmtChans;
2952 values[i++] = ALC_FORMAT_TYPE_SOFT;
2953 values[i++] = device->FmtType;
2956 values[i++] = ALC_MONO_SOURCES;
2957 values[i++] = device->NumMonoSources;
2959 values[i++] = ALC_STEREO_SOURCES;
2960 values[i++] = device->NumStereoSources;
2962 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2963 values[i++] = device->NumAuxSends;
2965 values[i++] = ALC_HRTF_SOFT;
2966 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2968 values[i++] = ALC_HRTF_STATUS_SOFT;
2969 values[i++] = device->Hrtf_Status;
2971 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2972 values[i++] = device->ClockBase +
2973 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2975 values[i++] = 0;
2976 V0(device->Backend,unlock)();
2978 break;
2980 case ALC_DEVICE_CLOCK_SOFT:
2981 V0(device->Backend,lock)();
2982 *values = device->ClockBase +
2983 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2984 V0(device->Backend,unlock)();
2985 break;
2987 default:
2988 ivals = malloc(size * sizeof(ALCint));
2989 size = GetIntegerv(device, pname, size, ivals);
2990 for(i = 0;i < size;i++)
2991 values[i] = ivals[i];
2992 free(ivals);
2993 break;
2996 if(device)
2997 ALCdevice_DecRef(device);
3001 /* alcIsExtensionPresent
3003 * Determines if there is support for a particular extension
3005 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3007 ALCboolean bResult = ALC_FALSE;
3009 VerifyDevice(&device);
3011 if(!extName)
3012 alcSetError(device, ALC_INVALID_VALUE);
3013 else
3015 size_t len = strlen(extName);
3016 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3017 while(ptr && *ptr)
3019 if(strncasecmp(ptr, extName, len) == 0 &&
3020 (ptr[len] == '\0' || isspace(ptr[len])))
3022 bResult = ALC_TRUE;
3023 break;
3025 if((ptr=strchr(ptr, ' ')) != NULL)
3027 do {
3028 ++ptr;
3029 } while(isspace(*ptr));
3033 if(device)
3034 ALCdevice_DecRef(device);
3035 return bResult;
3039 /* alcGetProcAddress
3041 * Retrieves the function address for a particular extension function
3043 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3045 ALCvoid *ptr = NULL;
3047 if(!funcName)
3049 VerifyDevice(&device);
3050 alcSetError(device, ALC_INVALID_VALUE);
3051 if(device) ALCdevice_DecRef(device);
3053 else
3055 ALsizei i = 0;
3056 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3057 i++;
3058 ptr = alcFunctions[i].address;
3061 return ptr;
3065 /* alcGetEnumValue
3067 * Get the value for a particular ALC enumeration name
3069 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3071 ALCenum val = 0;
3073 if(!enumName)
3075 VerifyDevice(&device);
3076 alcSetError(device, ALC_INVALID_VALUE);
3077 if(device) ALCdevice_DecRef(device);
3079 else
3081 ALsizei i = 0;
3082 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3083 i++;
3084 val = enumeration[i].value;
3087 return val;
3091 /* alcCreateContext
3093 * Create and attach a context to the given device.
3095 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3097 ALCcontext *ALContext;
3098 ALCenum err;
3100 LockLists();
3101 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3103 UnlockLists();
3104 alcSetError(device, ALC_INVALID_DEVICE);
3105 if(device) ALCdevice_DecRef(device);
3106 return NULL;
3109 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3111 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3113 UnlockLists();
3114 alcSetError(device, err);
3115 if(err == ALC_INVALID_DEVICE)
3117 V0(device->Backend,lock)();
3118 aluHandleDisconnect(device);
3119 V0(device->Backend,unlock)();
3121 ALCdevice_DecRef(device);
3122 return NULL;
3125 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3126 if(ALContext)
3128 InitRef(&ALContext->ref, 1);
3129 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3131 VECTOR_INIT(ALContext->ActiveAuxSlots);
3133 ALContext->VoiceCount = 0;
3134 ALContext->MaxVoices = 256;
3135 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3137 if(!ALContext || !ALContext->Voices)
3139 if(!ATOMIC_LOAD(&device->ContextList))
3141 V0(device->Backend,stop)();
3142 device->Flags &= ~DEVICE_RUNNING;
3144 UnlockLists();
3146 if(ALContext)
3148 al_free(ALContext->Voices);
3149 ALContext->Voices = NULL;
3151 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3153 al_free(ALContext);
3154 ALContext = NULL;
3157 alcSetError(device, ALC_OUT_OF_MEMORY);
3158 ALCdevice_DecRef(device);
3159 return NULL;
3162 ALContext->Device = device;
3163 ALCdevice_IncRef(device);
3164 InitContext(ALContext);
3167 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3168 do {
3169 ALContext->next = head;
3170 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3172 UnlockLists();
3174 ALCdevice_DecRef(device);
3176 TRACE("Created context %p\n", ALContext);
3177 return ALContext;
3180 /* alcDestroyContext
3182 * Remove a context from its device
3184 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3186 ALCdevice *Device;
3188 LockLists();
3189 /* alcGetContextsDevice sets an error for invalid contexts */
3190 Device = alcGetContextsDevice(context);
3191 if(Device)
3193 ReleaseContext(context, Device);
3194 if(!ATOMIC_LOAD(&Device->ContextList))
3196 V0(Device->Backend,stop)();
3197 Device->Flags &= ~DEVICE_RUNNING;
3200 UnlockLists();
3204 /* alcGetCurrentContext
3206 * Returns the currently active context on the calling thread
3208 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3210 ALCcontext *Context = altss_get(LocalContext);
3211 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3212 return Context;
3215 /* alcGetThreadContext
3217 * Returns the currently active thread-local context
3219 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3221 return altss_get(LocalContext);
3225 /* alcMakeContextCurrent
3227 * Makes the given context the active process-wide context, and removes the
3228 * thread-local context for the calling thread.
3230 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3232 /* context must be valid or NULL */
3233 if(context && !VerifyContext(&context))
3235 alcSetError(NULL, ALC_INVALID_CONTEXT);
3236 return ALC_FALSE;
3238 /* context's reference count is already incremented */
3239 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3240 if(context) ALCcontext_DecRef(context);
3242 if((context=altss_get(LocalContext)) != NULL)
3244 altss_set(LocalContext, NULL);
3245 ALCcontext_DecRef(context);
3248 return ALC_TRUE;
3251 /* alcSetThreadContext
3253 * Makes the given context the active context for the current thread
3255 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3257 ALCcontext *old;
3259 /* context must be valid or NULL */
3260 if(context && !VerifyContext(&context))
3262 alcSetError(NULL, ALC_INVALID_CONTEXT);
3263 return ALC_FALSE;
3265 /* context's reference count is already incremented */
3266 old = altss_get(LocalContext);
3267 altss_set(LocalContext, context);
3268 if(old) ALCcontext_DecRef(old);
3270 return ALC_TRUE;
3274 /* alcGetContextsDevice
3276 * Returns the device that a particular context is attached to
3278 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3280 ALCdevice *Device;
3282 if(!VerifyContext(&Context))
3284 alcSetError(NULL, ALC_INVALID_CONTEXT);
3285 return NULL;
3287 Device = Context->Device;
3288 ALCcontext_DecRef(Context);
3290 return Device;
3294 /* alcOpenDevice
3296 * Opens the named device.
3298 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3300 const ALCchar *fmt;
3301 ALCdevice *device;
3302 ALCenum err;
3304 DO_INITCONFIG();
3306 if(!PlaybackBackend.name)
3308 alcSetError(NULL, ALC_INVALID_VALUE);
3309 return NULL;
3312 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3313 #ifdef _WIN32
3314 /* Some old Windows apps hardcode these expecting OpenAL to use a
3315 * specific audio API, even when they're not enumerated. Creative's
3316 * router effectively ignores them too.
3318 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3319 || strcasecmp(deviceName, "MMSYSTEM") == 0
3320 #endif
3322 deviceName = NULL;
3324 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3325 if(!device)
3327 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3328 return NULL;
3331 //Validate device
3332 InitRef(&device->ref, 1);
3333 device->Connected = ALC_TRUE;
3334 device->Type = Playback;
3335 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3337 device->Flags = 0;
3338 device->Bs2b = NULL;
3339 device->Uhj_Encoder = NULL;
3340 VECTOR_INIT(device->Hrtf_List);
3341 AL_STRING_INIT(device->Hrtf_Name);
3342 device->Render_Mode = NormalRender;
3343 AL_STRING_INIT(device->DeviceName);
3344 device->Dry.Buffer = NULL;
3345 device->Dry.NumChannels = 0;
3346 device->VirtOut.Buffer = NULL;
3347 device->VirtOut.NumChannels = 0;
3348 device->RealOut.Buffer = NULL;
3349 device->RealOut.NumChannels = 0;
3351 ATOMIC_INIT(&device->ContextList, NULL);
3353 device->ClockBase = 0;
3354 device->SamplesDone = 0;
3356 device->MaxNoOfSources = 256;
3357 device->AuxiliaryEffectSlotMax = 4;
3358 device->NumAuxSends = MAX_SENDS;
3360 InitUIntMap(&device->BufferMap, ~0);
3361 InitUIntMap(&device->EffectMap, ~0);
3362 InitUIntMap(&device->FilterMap, ~0);
3364 //Set output format
3365 device->FmtChans = DevFmtChannelsDefault;
3366 device->FmtType = DevFmtTypeDefault;
3367 device->Frequency = DEFAULT_OUTPUT_RATE;
3368 device->IsHeadphones = AL_FALSE;
3369 device->NumUpdates = 4;
3370 device->UpdateSize = 1024;
3372 if(!PlaybackBackend.getFactory)
3373 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3374 ALCbackend_Playback);
3375 else
3377 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3378 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3380 if(!device->Backend)
3382 al_free(device);
3383 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3384 return NULL;
3388 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3390 static const struct {
3391 const char name[16];
3392 enum DevFmtChannels chans;
3393 } chanlist[] = {
3394 { "mono", DevFmtMono },
3395 { "stereo", DevFmtStereo },
3396 { "quad", DevFmtQuad },
3397 { "surround51", DevFmtX51 },
3398 { "surround61", DevFmtX61 },
3399 { "surround71", DevFmtX71 },
3400 { "surround51rear", DevFmtX51Rear },
3402 size_t i;
3404 for(i = 0;i < COUNTOF(chanlist);i++)
3406 if(strcasecmp(chanlist[i].name, fmt) == 0)
3408 device->FmtChans = chanlist[i].chans;
3409 device->Flags |= DEVICE_CHANNELS_REQUEST;
3410 break;
3413 if(i == COUNTOF(chanlist))
3414 ERR("Unsupported channels: %s\n", fmt);
3416 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3418 static const struct {
3419 const char name[16];
3420 enum DevFmtType type;
3421 } typelist[] = {
3422 { "int8", DevFmtByte },
3423 { "uint8", DevFmtUByte },
3424 { "int16", DevFmtShort },
3425 { "uint16", DevFmtUShort },
3426 { "int32", DevFmtInt },
3427 { "uint32", DevFmtUInt },
3428 { "float32", DevFmtFloat },
3430 size_t i;
3432 for(i = 0;i < COUNTOF(typelist);i++)
3434 if(strcasecmp(typelist[i].name, fmt) == 0)
3436 device->FmtType = typelist[i].type;
3437 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3438 break;
3441 if(i == COUNTOF(typelist))
3442 ERR("Unsupported sample-type: %s\n", fmt);
3445 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3447 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3448 if(device->Frequency < MIN_OUTPUT_RATE)
3449 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3450 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3453 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3454 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3456 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3457 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3458 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3459 device->UpdateSize = (device->UpdateSize+3)&~3;
3461 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3462 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3464 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3465 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3467 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3468 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3470 device->NumStereoSources = 1;
3471 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3473 // Find a playback device to open
3474 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3476 DELETE_OBJ(device->Backend);
3477 al_free(device);
3478 alcSetError(NULL, err);
3479 return NULL;
3482 if(DefaultEffect.type != AL_EFFECT_NULL)
3484 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3485 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3487 device->DefaultSlot = NULL;
3488 ERR("Failed to initialize the default effect slot\n");
3490 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3492 DeinitEffectSlot(device->DefaultSlot);
3493 device->DefaultSlot = NULL;
3494 ERR("Failed to initialize the default effect\n");
3496 else
3498 aluInitEffectPanning(device->DefaultSlot);
3499 UpdateEffectSlotProps(device->DefaultSlot);
3504 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3505 do {
3506 device->next = head;
3507 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3510 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3511 return device;
3514 /* alcCloseDevice
3516 * Closes the given device.
3518 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3520 ALCdevice *list, *origdev, *nextdev;
3521 ALCcontext *ctx;
3523 LockLists();
3524 list = ATOMIC_LOAD(&DeviceList);
3525 do {
3526 if(list == device)
3527 break;
3528 } while((list=list->next) != NULL);
3529 if(!list || list->Type == Capture)
3531 alcSetError(list, ALC_INVALID_DEVICE);
3532 UnlockLists();
3533 return ALC_FALSE;
3536 origdev = device;
3537 nextdev = device->next;
3538 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3540 do {
3541 list = origdev;
3542 origdev = device;
3543 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3545 UnlockLists();
3547 ctx = ATOMIC_LOAD(&device->ContextList);
3548 while(ctx != NULL)
3550 ALCcontext *next = ctx->next;
3551 WARN("Releasing context %p\n", ctx);
3552 ReleaseContext(ctx, device);
3553 ctx = next;
3555 if((device->Flags&DEVICE_RUNNING))
3556 V0(device->Backend,stop)();
3557 device->Flags &= ~DEVICE_RUNNING;
3559 ALCdevice_DecRef(device);
3561 return ALC_TRUE;
3565 /************************************************
3566 * ALC capture functions
3567 ************************************************/
3568 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3570 ALCdevice *device = NULL;
3571 ALCenum err;
3573 DO_INITCONFIG();
3575 if(!CaptureBackend.name)
3577 alcSetError(NULL, ALC_INVALID_VALUE);
3578 return NULL;
3581 if(samples <= 0)
3583 alcSetError(NULL, ALC_INVALID_VALUE);
3584 return NULL;
3587 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3588 deviceName = NULL;
3590 device = al_calloc(16, sizeof(ALCdevice));
3591 if(!device)
3593 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3594 return NULL;
3597 //Validate device
3598 InitRef(&device->ref, 1);
3599 device->Connected = ALC_TRUE;
3600 device->Type = Capture;
3602 VECTOR_INIT(device->Hrtf_List);
3603 AL_STRING_INIT(device->Hrtf_Name);
3605 AL_STRING_INIT(device->DeviceName);
3606 device->Dry.Buffer = NULL;
3607 device->Dry.NumChannels = 0;
3608 device->VirtOut.Buffer = NULL;
3609 device->VirtOut.NumChannels = 0;
3610 device->RealOut.Buffer = NULL;
3611 device->RealOut.NumChannels = 0;
3613 InitUIntMap(&device->BufferMap, ~0);
3614 InitUIntMap(&device->EffectMap, ~0);
3615 InitUIntMap(&device->FilterMap, ~0);
3617 if(!CaptureBackend.getFactory)
3618 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3619 ALCbackend_Capture);
3620 else
3622 ALCbackendFactory *factory = CaptureBackend.getFactory();
3623 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3625 if(!device->Backend)
3627 al_free(device);
3628 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3629 return NULL;
3632 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3633 device->Frequency = frequency;
3635 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3636 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3638 al_free(device);
3639 alcSetError(NULL, ALC_INVALID_ENUM);
3640 return NULL;
3642 device->IsHeadphones = AL_FALSE;
3644 device->UpdateSize = samples;
3645 device->NumUpdates = 1;
3647 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3649 al_free(device);
3650 alcSetError(NULL, err);
3651 return NULL;
3655 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3656 do {
3657 device->next = head;
3658 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3661 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3662 return device;
3665 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3667 ALCdevice *list, *next, *nextdev;
3669 LockLists();
3670 list = ATOMIC_LOAD(&DeviceList);
3671 do {
3672 if(list == device)
3673 break;
3674 } while((list=list->next) != NULL);
3675 if(!list || list->Type != Capture)
3677 alcSetError(list, ALC_INVALID_DEVICE);
3678 UnlockLists();
3679 return ALC_FALSE;
3682 next = device;
3683 nextdev = device->next;
3684 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3686 do {
3687 list = next;
3688 next = device;
3689 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3691 UnlockLists();
3693 ALCdevice_DecRef(device);
3695 return ALC_TRUE;
3698 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3700 if(!VerifyDevice(&device) || device->Type != Capture)
3701 alcSetError(device, ALC_INVALID_DEVICE);
3702 else
3704 V0(device->Backend,lock)();
3705 if(!device->Connected)
3706 alcSetError(device, ALC_INVALID_DEVICE);
3707 else if(!(device->Flags&DEVICE_RUNNING))
3709 if(V0(device->Backend,start)())
3710 device->Flags |= DEVICE_RUNNING;
3711 else
3713 aluHandleDisconnect(device);
3714 alcSetError(device, ALC_INVALID_DEVICE);
3717 V0(device->Backend,unlock)();
3720 if(device) ALCdevice_DecRef(device);
3723 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3725 if(!VerifyDevice(&device) || device->Type != Capture)
3726 alcSetError(device, ALC_INVALID_DEVICE);
3727 else
3729 V0(device->Backend,lock)();
3730 if((device->Flags&DEVICE_RUNNING))
3731 V0(device->Backend,stop)();
3732 device->Flags &= ~DEVICE_RUNNING;
3733 V0(device->Backend,unlock)();
3736 if(device) ALCdevice_DecRef(device);
3739 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3741 if(!VerifyDevice(&device) || device->Type != Capture)
3742 alcSetError(device, ALC_INVALID_DEVICE);
3743 else
3745 ALCenum err = ALC_INVALID_VALUE;
3747 V0(device->Backend,lock)();
3748 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3749 err = V(device->Backend,captureSamples)(buffer, samples);
3750 V0(device->Backend,unlock)();
3752 if(err != ALC_NO_ERROR)
3753 alcSetError(device, err);
3755 if(device) ALCdevice_DecRef(device);
3759 /************************************************
3760 * ALC loopback functions
3761 ************************************************/
3763 /* alcLoopbackOpenDeviceSOFT
3765 * Open a loopback device, for manual rendering.
3767 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3769 ALCbackendFactory *factory;
3770 ALCdevice *device;
3772 DO_INITCONFIG();
3774 /* Make sure the device name, if specified, is us. */
3775 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3777 alcSetError(NULL, ALC_INVALID_VALUE);
3778 return NULL;
3781 device = al_calloc(16, sizeof(ALCdevice));
3782 if(!device)
3784 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3785 return NULL;
3788 //Validate device
3789 InitRef(&device->ref, 1);
3790 device->Connected = ALC_TRUE;
3791 device->Type = Loopback;
3792 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3794 device->Flags = 0;
3795 VECTOR_INIT(device->Hrtf_List);
3796 AL_STRING_INIT(device->Hrtf_Name);
3797 device->Bs2b = NULL;
3798 device->Uhj_Encoder = NULL;
3799 device->Render_Mode = NormalRender;
3800 AL_STRING_INIT(device->DeviceName);
3801 device->Dry.Buffer = NULL;
3802 device->Dry.NumChannels = 0;
3803 device->VirtOut.Buffer = NULL;
3804 device->VirtOut.NumChannels = 0;
3805 device->RealOut.Buffer = NULL;
3806 device->RealOut.NumChannels = 0;
3808 ATOMIC_INIT(&device->ContextList, NULL);
3810 device->ClockBase = 0;
3811 device->SamplesDone = 0;
3813 device->MaxNoOfSources = 256;
3814 device->AuxiliaryEffectSlotMax = 4;
3815 device->NumAuxSends = MAX_SENDS;
3817 InitUIntMap(&device->BufferMap, ~0);
3818 InitUIntMap(&device->EffectMap, ~0);
3819 InitUIntMap(&device->FilterMap, ~0);
3821 factory = ALCloopbackFactory_getFactory();
3822 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3823 if(!device->Backend)
3825 al_free(device);
3826 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3827 return NULL;
3830 //Set output format
3831 device->NumUpdates = 0;
3832 device->UpdateSize = 0;
3834 device->Frequency = DEFAULT_OUTPUT_RATE;
3835 device->FmtChans = DevFmtChannelsDefault;
3836 device->FmtType = DevFmtTypeDefault;
3837 device->IsHeadphones = AL_FALSE;
3839 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3840 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3842 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3843 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3845 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3846 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3848 device->NumStereoSources = 1;
3849 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3851 // Open the "backend"
3852 V(device->Backend,open)("Loopback");
3855 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3856 do {
3857 device->next = head;
3858 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3861 TRACE("Created device %p\n", device);
3862 return device;
3865 /* alcIsRenderFormatSupportedSOFT
3867 * Determines if the loopback device supports the given format for rendering.
3869 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3871 ALCboolean ret = ALC_FALSE;
3873 if(!VerifyDevice(&device) || device->Type != Loopback)
3874 alcSetError(device, ALC_INVALID_DEVICE);
3875 else if(freq <= 0)
3876 alcSetError(device, ALC_INVALID_VALUE);
3877 else
3879 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3880 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3881 freq >= MIN_OUTPUT_RATE)
3882 ret = ALC_TRUE;
3884 if(device) ALCdevice_DecRef(device);
3886 return ret;
3889 /* alcRenderSamplesSOFT
3891 * Renders some samples into a buffer, using the format last set by the
3892 * attributes given to alcCreateContext.
3894 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3896 if(!VerifyDevice(&device) || device->Type != Loopback)
3897 alcSetError(device, ALC_INVALID_DEVICE);
3898 else if(samples < 0 || (samples > 0 && buffer == NULL))
3899 alcSetError(device, ALC_INVALID_VALUE);
3900 else
3901 aluMixData(device, buffer, samples);
3902 if(device) ALCdevice_DecRef(device);
3906 /************************************************
3907 * ALC DSP pause/resume functions
3908 ************************************************/
3910 /* alcDevicePauseSOFT
3912 * Pause the DSP to stop audio processing.
3914 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3916 if(!VerifyDevice(&device) || device->Type != Playback)
3917 alcSetError(device, ALC_INVALID_DEVICE);
3918 else
3920 LockLists();
3921 if((device->Flags&DEVICE_RUNNING))
3922 V0(device->Backend,stop)();
3923 device->Flags &= ~DEVICE_RUNNING;
3924 device->Flags |= DEVICE_PAUSED;
3925 UnlockLists();
3927 if(device) ALCdevice_DecRef(device);
3930 /* alcDeviceResumeSOFT
3932 * Resume the DSP to restart audio processing.
3934 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3936 if(!VerifyDevice(&device) || device->Type != Playback)
3937 alcSetError(device, ALC_INVALID_DEVICE);
3938 else
3940 LockLists();
3941 if((device->Flags&DEVICE_PAUSED))
3943 device->Flags &= ~DEVICE_PAUSED;
3944 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3946 if(V0(device->Backend,start)() != ALC_FALSE)
3947 device->Flags |= DEVICE_RUNNING;
3948 else
3950 alcSetError(device, ALC_INVALID_DEVICE);
3951 V0(device->Backend,lock)();
3952 aluHandleDisconnect(device);
3953 V0(device->Backend,unlock)();
3957 UnlockLists();
3959 if(device) ALCdevice_DecRef(device);
3963 /************************************************
3964 * ALC HRTF functions
3965 ************************************************/
3967 /* alcGetStringiSOFT
3969 * Gets a string parameter at the given index.
3971 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3973 const ALCchar *str = NULL;
3975 if(!VerifyDevice(&device) || device->Type == Capture)
3976 alcSetError(device, ALC_INVALID_DEVICE);
3977 else switch(paramName)
3979 case ALC_HRTF_SPECIFIER_SOFT:
3980 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
3981 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
3982 else
3983 alcSetError(device, ALC_INVALID_VALUE);
3984 break;
3986 default:
3987 alcSetError(device, ALC_INVALID_ENUM);
3988 break;
3990 if(device) ALCdevice_DecRef(device);
3992 return str;
3995 /* alcResetDeviceSOFT
3997 * Resets the given device output, using the specified attribute list.
3999 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4001 ALCenum err;
4003 LockLists();
4004 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4006 UnlockLists();
4007 alcSetError(device, ALC_INVALID_DEVICE);
4008 if(device) ALCdevice_DecRef(device);
4009 return ALC_FALSE;
4012 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
4014 UnlockLists();
4015 alcSetError(device, err);
4016 if(err == ALC_INVALID_DEVICE)
4018 V0(device->Backend,lock)();
4019 aluHandleDisconnect(device);
4020 V0(device->Backend,unlock)();
4022 ALCdevice_DecRef(device);
4023 return ALC_FALSE;
4025 UnlockLists();
4026 ALCdevice_DecRef(device);
4028 return ALC_TRUE;