Find a valid source buffer before updating the voice
[openal-soft.git] / Alc / ALc.c
blobf8eda9a5702d4ac31d36bc7700b154f6202e3d91
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);
1573 #define UPDATE_SLOT(iter) do { \
1574 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1575 V((*iter)->EffectState,update)(device, *iter); \
1576 } while(0)
1577 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1578 #undef UPDATE_SLOT
1580 V0(device->Backend,unlock)();
1582 RestoreFPUMode(&oldMode);
1585 /* ALCcontext_ProcessUpdates
1587 * Resumes update processing after being deferred.
1589 void ALCcontext_ProcessUpdates(ALCcontext *context)
1591 ALCdevice *device = context->Device;
1593 V0(device->Backend,lock)();
1594 if(context->DeferUpdates)
1596 ALsizei pos;
1598 context->DeferUpdates = AL_FALSE;
1600 LockUIntMapRead(&context->SourceMap);
1601 for(pos = 0;pos < context->SourceMap.size;pos++)
1603 ALsource *Source = context->SourceMap.array[pos].value;
1604 ALenum new_state;
1606 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1607 Source->Offset >= 0.0)
1609 WriteLock(&Source->queue_lock);
1610 ApplyOffset(Source);
1611 WriteUnlock(&Source->queue_lock);
1614 new_state = Source->new_state;
1615 Source->new_state = AL_NONE;
1616 if(new_state)
1617 SetSourceState(Source, context, new_state);
1619 UnlockUIntMapRead(&context->SourceMap);
1621 V0(device->Backend,unlock)();
1625 /* alcSetError
1627 * Stores the latest ALC device error
1629 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1631 if(TrapALCError)
1633 #ifdef _WIN32
1634 /* DebugBreak() will cause an exception if there is no debugger */
1635 if(IsDebuggerPresent())
1636 DebugBreak();
1637 #elif defined(SIGTRAP)
1638 raise(SIGTRAP);
1639 #endif
1642 if(device)
1643 ATOMIC_STORE(&device->LastError, errorCode);
1644 else
1645 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1649 /* UpdateClockBase
1651 * Updates the device's base clock time with however many samples have been
1652 * done. This is used so frequency changes on the device don't cause the time
1653 * to jump forward or back.
1655 static inline void UpdateClockBase(ALCdevice *device)
1657 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1658 device->SamplesDone = 0;
1661 /* UpdateDeviceParams
1663 * Updates device parameters according to the attribute list (caller is
1664 * responsible for holding the list lock).
1666 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1668 ALCcontext *context;
1669 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1670 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1671 enum DevFmtChannels oldChans;
1672 enum DevFmtType oldType;
1673 ALCuint oldFreq;
1674 FPUCtl oldMode;
1675 ALCsizei hrtf_id = -1;
1676 size_t size;
1678 // Check for attributes
1679 if(device->Type == Loopback)
1681 enum {
1682 GotFreq = 1<<0,
1683 GotChans = 1<<1,
1684 GotType = 1<<2,
1685 GotAll = GotFreq|GotChans|GotType
1687 ALCuint freq, numMono, numStereo, numSends;
1688 enum DevFmtChannels schans;
1689 enum DevFmtType stype;
1690 ALCuint attrIdx = 0;
1691 ALCint gotFmt = 0;
1693 if(!attrList)
1695 WARN("Missing attributes for loopback device\n");
1696 return ALC_INVALID_VALUE;
1699 numMono = device->NumMonoSources;
1700 numStereo = device->NumStereoSources;
1701 numSends = device->NumAuxSends;
1702 schans = device->FmtChans;
1703 stype = device->FmtType;
1704 freq = device->Frequency;
1706 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1707 while(attrList[attrIdx])
1709 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1711 ALCint val = attrList[attrIdx + 1];
1712 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, val);
1713 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1714 return ALC_INVALID_VALUE;
1715 schans = val;
1716 gotFmt |= GotChans;
1719 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1721 ALCint val = attrList[attrIdx + 1];
1722 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, val);
1723 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1724 return ALC_INVALID_VALUE;
1725 stype = val;
1726 gotFmt |= GotType;
1729 if(attrList[attrIdx] == ALC_FREQUENCY)
1731 freq = attrList[attrIdx + 1];
1732 TRACE_ATTR(ALC_FREQUENCY, freq);
1733 if(freq < MIN_OUTPUT_RATE)
1734 return ALC_INVALID_VALUE;
1735 gotFmt |= GotFreq;
1738 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1740 numStereo = attrList[attrIdx + 1];
1741 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1742 if(numStereo > device->MaxNoOfSources)
1743 numStereo = device->MaxNoOfSources;
1745 numMono = device->MaxNoOfSources - numStereo;
1748 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1750 numSends = attrList[attrIdx + 1];
1751 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1754 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1756 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1757 if(attrList[attrIdx + 1] == ALC_FALSE)
1758 hrtf_appreq = Hrtf_Disable;
1759 else if(attrList[attrIdx + 1] == ALC_TRUE)
1760 hrtf_appreq = Hrtf_Enable;
1761 else
1762 hrtf_appreq = Hrtf_Default;
1765 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1767 hrtf_id = attrList[attrIdx + 1];
1768 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1771 attrIdx += 2;
1773 #undef TRACE_ATTR
1775 if(gotFmt != GotAll)
1777 WARN("Missing format for loopback device\n");
1778 return ALC_INVALID_VALUE;
1781 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1782 numSends = minu(MAX_SENDS, numSends);
1784 if((device->Flags&DEVICE_RUNNING))
1785 V0(device->Backend,stop)();
1786 device->Flags &= ~DEVICE_RUNNING;
1788 UpdateClockBase(device);
1790 device->Frequency = freq;
1791 device->FmtChans = schans;
1792 device->FmtType = stype;
1793 device->NumMonoSources = numMono;
1794 device->NumStereoSources = numStereo;
1795 device->NumAuxSends = numSends;
1797 else if(attrList && attrList[0])
1799 ALCuint freq, numMono, numStereo, numSends;
1800 ALCuint attrIdx = 0;
1802 /* If a context is already running on the device, stop playback so the
1803 * device attributes can be updated. */
1804 if((device->Flags&DEVICE_RUNNING))
1805 V0(device->Backend,stop)();
1806 device->Flags &= ~DEVICE_RUNNING;
1808 freq = device->Frequency;
1809 numMono = device->NumMonoSources;
1810 numStereo = device->NumStereoSources;
1811 numSends = device->NumAuxSends;
1813 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1814 while(attrList[attrIdx])
1816 if(attrList[attrIdx] == ALC_FREQUENCY)
1818 freq = attrList[attrIdx + 1];
1819 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1820 TRACE_ATTR(ALC_FREQUENCY, freq);
1823 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1825 numStereo = attrList[attrIdx + 1];
1826 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1827 if(numStereo > device->MaxNoOfSources)
1828 numStereo = device->MaxNoOfSources;
1830 numMono = device->MaxNoOfSources - numStereo;
1833 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1835 numSends = attrList[attrIdx + 1];
1836 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1839 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1841 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1842 if(attrList[attrIdx + 1] == ALC_FALSE)
1843 hrtf_appreq = Hrtf_Disable;
1844 else if(attrList[attrIdx + 1] == ALC_TRUE)
1845 hrtf_appreq = Hrtf_Enable;
1846 else
1847 hrtf_appreq = Hrtf_Default;
1850 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1852 hrtf_id = attrList[attrIdx + 1];
1853 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1856 attrIdx += 2;
1858 #undef TRACE_ATTR
1860 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1861 freq = maxu(freq, MIN_OUTPUT_RATE);
1863 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1864 numSends = minu(MAX_SENDS, numSends);
1866 UpdateClockBase(device);
1868 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1869 device->Frequency;
1870 /* SSE and Neon do best with the update size being a multiple of 4 */
1871 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1872 device->UpdateSize = (device->UpdateSize+3)&~3;
1874 device->Frequency = freq;
1875 device->NumMonoSources = numMono;
1876 device->NumStereoSources = numStereo;
1877 device->NumAuxSends = numSends;
1880 if((device->Flags&DEVICE_RUNNING))
1881 return ALC_NO_ERROR;
1883 al_free(device->Uhj_Encoder);
1884 device->Uhj_Encoder = NULL;
1886 al_free(device->Bs2b);
1887 device->Bs2b = NULL;
1889 al_free(device->Dry.Buffer);
1890 device->Dry.Buffer = NULL;
1891 device->Dry.NumChannels = 0;
1892 device->VirtOut.Buffer = NULL;
1893 device->VirtOut.NumChannels = 0;
1894 device->RealOut.Buffer = NULL;
1895 device->RealOut.NumChannels = 0;
1897 UpdateClockBase(device);
1899 /*************************************************************************
1900 * Update device format request if HRTF is requested
1902 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1903 if(device->Type != Loopback)
1905 const char *hrtf;
1906 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1908 if(strcasecmp(hrtf, "true") == 0)
1909 hrtf_userreq = Hrtf_Enable;
1910 else if(strcasecmp(hrtf, "false") == 0)
1911 hrtf_userreq = Hrtf_Disable;
1912 else if(strcasecmp(hrtf, "auto") != 0)
1913 ERR("Unexpected hrtf value: %s\n", hrtf);
1916 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1918 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1920 VECTOR_DEINIT(device->Hrtf_List);
1921 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1923 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1925 device->FmtChans = DevFmtStereo;
1926 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1927 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1928 else
1929 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1930 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1932 else
1934 hrtf_userreq = Hrtf_Default;
1935 hrtf_appreq = Hrtf_Disable;
1936 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1940 else if(hrtf_appreq == Hrtf_Enable)
1942 size_t i = VECTOR_SIZE(device->Hrtf_List);
1943 /* Loopback device. We don't need to match to a specific HRTF entry
1944 * here. If the requested ID matches, we'll pick that later, if not,
1945 * we'll try to auto-select one anyway. Just make sure one exists
1946 * that'll work.
1948 if(device->FmtChans == DevFmtStereo)
1950 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1952 VECTOR_DEINIT(device->Hrtf_List);
1953 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1955 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1957 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1958 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1959 break;
1962 if(i == VECTOR_SIZE(device->Hrtf_List))
1964 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1965 DevFmtChannelsString(device->FmtChans), device->Frequency);
1966 hrtf_appreq = Hrtf_Disable;
1967 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1971 oldFreq = device->Frequency;
1972 oldChans = device->FmtChans;
1973 oldType = device->FmtType;
1975 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1976 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1977 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1978 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1979 device->UpdateSize, device->NumUpdates
1982 if(V0(device->Backend,reset)() == ALC_FALSE)
1983 return ALC_INVALID_DEVICE;
1985 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1987 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1988 DevFmtChannelsString(device->FmtChans));
1989 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1991 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1993 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1994 DevFmtTypeString(device->FmtType));
1995 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1997 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1999 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2000 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2003 if((device->UpdateSize&3) != 0)
2005 if((CPUCapFlags&CPU_CAP_SSE))
2006 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2007 if((CPUCapFlags&CPU_CAP_NEON))
2008 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2011 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2012 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2013 device->Frequency, device->UpdateSize, device->NumUpdates
2016 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2018 /* Allocate extra channels for any post-filter output. */
2019 size = device->Dry.NumChannels * sizeof(device->Dry.Buffer[0]);
2020 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2021 size += (ChannelsFromDevFmt(device->FmtChans)+4) * sizeof(device->Dry.Buffer[0]);
2022 else if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2023 size += ChannelsFromDevFmt(device->FmtChans) * sizeof(device->Dry.Buffer[0]);
2024 device->Dry.Buffer = al_calloc(16, size);
2025 if(!device->Dry.Buffer)
2027 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2028 return ALC_INVALID_DEVICE;
2031 if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2033 device->VirtOut.Buffer = device->Dry.Buffer;
2034 device->VirtOut.NumChannels = device->Dry.NumChannels;
2035 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2036 device->RealOut.NumChannels = ChannelsFromDevFmt(device->FmtChans);
2038 else
2040 device->VirtOut.Buffer = NULL;
2041 device->VirtOut.NumChannels = 0;
2042 device->RealOut.Buffer = device->Dry.Buffer;
2043 device->RealOut.NumChannels = device->Dry.NumChannels;
2046 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2048 /* Higher-order high quality decoding requires upsampling first-order
2049 * content, so make sure to mix it separately.
2051 device->FOAOut.Buffer = device->RealOut.Buffer + device->RealOut.NumChannels;
2052 device->FOAOut.NumChannels = 4;
2054 else
2056 device->FOAOut.Buffer = device->Dry.Buffer;
2057 device->FOAOut.NumChannels = device->Dry.NumChannels;
2060 SetMixerFPUMode(&oldMode);
2061 V0(device->Backend,lock)();
2062 context = ATOMIC_LOAD(&device->ContextList);
2063 while(context)
2065 ALsizei pos;
2067 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2068 LockUIntMapRead(&context->EffectSlotMap);
2069 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2071 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2073 slot->EffectState->OutBuffer = device->Dry.Buffer;
2074 slot->EffectState->OutChannels = device->Dry.NumChannels;
2075 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2077 UnlockUIntMapRead(&context->EffectSlotMap);
2078 V0(device->Backend,unlock)();
2079 RestoreFPUMode(&oldMode);
2080 return ALC_INVALID_DEVICE;
2082 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2083 V(slot->EffectState,update)(device, slot);
2085 UnlockUIntMapRead(&context->EffectSlotMap);
2087 LockUIntMapRead(&context->SourceMap);
2088 for(pos = 0;pos < context->SourceMap.size;pos++)
2090 ALsource *source = context->SourceMap.array[pos].value;
2091 ALuint s = device->NumAuxSends;
2092 while(s < MAX_SENDS)
2094 if(source->Send[s].Slot)
2095 DecrementRef(&source->Send[s].Slot->ref);
2096 source->Send[s].Slot = NULL;
2097 source->Send[s].Gain = 1.0f;
2098 source->Send[s].GainHF = 1.0f;
2099 s++;
2101 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2103 UnlockUIntMapRead(&context->SourceMap);
2105 for(pos = 0;pos < context->VoiceCount;pos++)
2107 ALvoice *voice = &context->Voices[pos];
2108 ALsource *source = voice->Source;
2109 ALbufferlistitem *BufferListItem;
2111 if(!source)
2112 continue;
2114 BufferListItem = ATOMIC_LOAD(&source->queue);
2115 while(BufferListItem != NULL)
2117 ALbuffer *buffer;
2118 if((buffer=BufferListItem->buffer) != NULL)
2120 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2121 voice->Update(voice, source, buffer, context);
2122 break;
2124 BufferListItem = BufferListItem->next;
2128 context = context->next;
2130 if(device->DefaultSlot)
2132 ALeffectslot *slot = device->DefaultSlot;
2133 ALeffectState *state = slot->EffectState;
2135 state->OutBuffer = device->Dry.Buffer;
2136 state->OutChannels = device->Dry.NumChannels;
2137 if(V(state,deviceUpdate)(device) == AL_FALSE)
2139 V0(device->Backend,unlock)();
2140 RestoreFPUMode(&oldMode);
2141 return ALC_INVALID_DEVICE;
2143 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2144 V(slot->EffectState,update)(device, slot);
2146 V0(device->Backend,unlock)();
2147 RestoreFPUMode(&oldMode);
2149 if(!(device->Flags&DEVICE_PAUSED))
2151 if(V0(device->Backend,start)() == ALC_FALSE)
2152 return ALC_INVALID_DEVICE;
2153 device->Flags |= DEVICE_RUNNING;
2156 return ALC_NO_ERROR;
2159 /* FreeDevice
2161 * Frees the device structure, and destroys any objects the app failed to
2162 * delete. Called once there's no more references on the device.
2164 static ALCvoid FreeDevice(ALCdevice *device)
2166 TRACE("%p\n", device);
2168 V0(device->Backend,close)();
2169 DELETE_OBJ(device->Backend);
2170 device->Backend = NULL;
2172 if(device->DefaultSlot)
2174 ALeffectState *state = device->DefaultSlot->EffectState;
2175 device->DefaultSlot = NULL;
2176 DELETE_OBJ(state);
2179 if(device->BufferMap.size > 0)
2181 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2182 ReleaseALBuffers(device);
2184 ResetUIntMap(&device->BufferMap);
2186 if(device->EffectMap.size > 0)
2188 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2189 ReleaseALEffects(device);
2191 ResetUIntMap(&device->EffectMap);
2193 if(device->FilterMap.size > 0)
2195 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2196 ReleaseALFilters(device);
2198 ResetUIntMap(&device->FilterMap);
2200 AL_STRING_DEINIT(device->Hrtf_Name);
2201 FreeHrtfList(&device->Hrtf_List);
2203 al_free(device->Bs2b);
2204 device->Bs2b = NULL;
2206 al_free(device->Uhj_Encoder);
2207 device->Uhj_Encoder = NULL;
2209 bformatdec_free(device->AmbiDecoder);
2210 device->AmbiDecoder = NULL;
2212 AL_STRING_DEINIT(device->DeviceName);
2214 al_free(device->Dry.Buffer);
2215 device->Dry.Buffer = NULL;
2216 device->Dry.NumChannels = 0;
2217 device->VirtOut.Buffer = NULL;
2218 device->VirtOut.NumChannels = 0;
2219 device->RealOut.Buffer = NULL;
2220 device->RealOut.NumChannels = 0;
2222 al_free(device);
2226 void ALCdevice_IncRef(ALCdevice *device)
2228 uint ref;
2229 ref = IncrementRef(&device->ref);
2230 TRACEREF("%p increasing refcount to %u\n", device, ref);
2233 void ALCdevice_DecRef(ALCdevice *device)
2235 uint ref;
2236 ref = DecrementRef(&device->ref);
2237 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2238 if(ref == 0) FreeDevice(device);
2241 /* VerifyDevice
2243 * Checks if the device handle is valid, and increments its ref count if so.
2245 static ALCboolean VerifyDevice(ALCdevice **device)
2247 ALCdevice *tmpDevice;
2249 LockLists();
2250 tmpDevice = ATOMIC_LOAD(&DeviceList);
2251 while(tmpDevice)
2253 if(tmpDevice == *device)
2255 ALCdevice_IncRef(tmpDevice);
2256 UnlockLists();
2257 return ALC_TRUE;
2259 tmpDevice = tmpDevice->next;
2261 UnlockLists();
2263 *device = NULL;
2264 return ALC_FALSE;
2268 /* InitContext
2270 * Initializes context fields
2272 static ALvoid InitContext(ALCcontext *Context)
2274 ALlistener *listener = Context->Listener;
2275 //Initialise listener
2276 listener->Gain = 1.0f;
2277 listener->MetersPerUnit = 1.0f;
2278 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2279 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2280 listener->Forward[0] = 0.0f;
2281 listener->Forward[1] = 0.0f;
2282 listener->Forward[2] = -1.0f;
2283 listener->Up[0] = 0.0f;
2284 listener->Up[1] = 1.0f;
2285 listener->Up[2] = 0.0f;
2287 aluMatrixdSet(&listener->Params.Matrix,
2288 1.0, 0.0, 0.0, 0.0,
2289 0.0, 1.0, 0.0, 0.0,
2290 0.0, 0.0, 1.0, 0.0,
2291 0.0, 0.0, 0.0, 1.0
2293 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2294 listener->Params.Gain = 1.0f;
2295 listener->Params.MetersPerUnit = 1.0f;
2296 listener->Params.DopplerFactor = 1.0f;
2297 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2299 //Validate Context
2300 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2301 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2302 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2303 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2305 //Set globals
2306 Context->DistanceModel = DefaultDistanceModel;
2307 Context->SourceDistanceModel = AL_FALSE;
2308 Context->DopplerFactor = 1.0f;
2309 Context->DopplerVelocity = 1.0f;
2310 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2311 Context->DeferUpdates = AL_FALSE;
2313 Context->ExtensionList = alExtList;
2317 /* FreeContext
2319 * Cleans up the context, and destroys any remaining objects the app failed to
2320 * delete. Called once there's no more references on the context.
2322 static void FreeContext(ALCcontext *context)
2324 TRACE("%p\n", context);
2326 if(context->SourceMap.size > 0)
2328 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2329 ReleaseALSources(context);
2331 ResetUIntMap(&context->SourceMap);
2333 if(context->EffectSlotMap.size > 0)
2335 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2336 ReleaseALAuxiliaryEffectSlots(context);
2338 ResetUIntMap(&context->EffectSlotMap);
2340 al_free(context->Voices);
2341 context->Voices = NULL;
2342 context->VoiceCount = 0;
2343 context->MaxVoices = 0;
2345 VECTOR_DEINIT(context->ActiveAuxSlots);
2347 ALCdevice_DecRef(context->Device);
2348 context->Device = NULL;
2350 //Invalidate context
2351 memset(context, 0, sizeof(ALCcontext));
2352 al_free(context);
2355 /* ReleaseContext
2357 * Removes the context reference from the given device and removes it from
2358 * being current on the running thread or globally.
2360 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2362 ALCcontext *nextctx;
2363 ALCcontext *origctx;
2365 if(altss_get(LocalContext) == context)
2367 WARN("%p released while current on thread\n", context);
2368 altss_set(LocalContext, NULL);
2369 ALCcontext_DecRef(context);
2372 origctx = context;
2373 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2374 ALCcontext_DecRef(context);
2376 ALCdevice_Lock(device);
2377 origctx = context;
2378 nextctx = context->next;
2379 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2381 ALCcontext *list;
2382 do {
2383 list = origctx;
2384 origctx = context;
2385 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2387 ALCdevice_Unlock(device);
2389 ALCcontext_DecRef(context);
2392 void ALCcontext_IncRef(ALCcontext *context)
2394 uint ref;
2395 ref = IncrementRef(&context->ref);
2396 TRACEREF("%p increasing refcount to %u\n", context, ref);
2399 void ALCcontext_DecRef(ALCcontext *context)
2401 uint ref;
2402 ref = DecrementRef(&context->ref);
2403 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2404 if(ref == 0) FreeContext(context);
2407 static void ReleaseThreadCtx(void *ptr)
2409 WARN("%p current for thread being destroyed\n", ptr);
2410 ALCcontext_DecRef(ptr);
2413 /* VerifyContext
2415 * Checks that the given context is valid, and increments its reference count.
2417 static ALCboolean VerifyContext(ALCcontext **context)
2419 ALCdevice *dev;
2421 LockLists();
2422 dev = ATOMIC_LOAD(&DeviceList);
2423 while(dev)
2425 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2426 while(ctx)
2428 if(ctx == *context)
2430 ALCcontext_IncRef(ctx);
2431 UnlockLists();
2432 return ALC_TRUE;
2434 ctx = ctx->next;
2436 dev = dev->next;
2438 UnlockLists();
2440 *context = NULL;
2441 return ALC_FALSE;
2445 /* GetContextRef
2447 * Returns the currently active context for this thread, and adds a reference
2448 * without locking it.
2450 ALCcontext *GetContextRef(void)
2452 ALCcontext *context;
2454 context = altss_get(LocalContext);
2455 if(context)
2456 ALCcontext_IncRef(context);
2457 else
2459 LockLists();
2460 context = ATOMIC_LOAD(&GlobalContext);
2461 if(context)
2462 ALCcontext_IncRef(context);
2463 UnlockLists();
2466 return context;
2470 /************************************************
2471 * Standard ALC functions
2472 ************************************************/
2474 /* alcGetError
2476 * Return last ALC generated error code for the given device
2478 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2480 ALCenum errorCode;
2482 if(VerifyDevice(&device))
2484 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2485 ALCdevice_DecRef(device);
2487 else
2488 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2490 return errorCode;
2494 /* alcSuspendContext
2496 * Suspends updates for the given context
2498 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2500 if(!SuspendDefers)
2501 return;
2503 if(!VerifyContext(&context))
2504 alcSetError(NULL, ALC_INVALID_CONTEXT);
2505 else
2507 ALCcontext_DeferUpdates(context);
2508 ALCcontext_DecRef(context);
2512 /* alcProcessContext
2514 * Resumes processing updates for the given context
2516 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2518 if(!SuspendDefers)
2519 return;
2521 if(!VerifyContext(&context))
2522 alcSetError(NULL, ALC_INVALID_CONTEXT);
2523 else
2525 ALCcontext_ProcessUpdates(context);
2526 ALCcontext_DecRef(context);
2531 /* alcGetString
2533 * Returns information about the device, and error strings
2535 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2537 const ALCchar *value = NULL;
2539 switch(param)
2541 case ALC_NO_ERROR:
2542 value = alcNoError;
2543 break;
2545 case ALC_INVALID_ENUM:
2546 value = alcErrInvalidEnum;
2547 break;
2549 case ALC_INVALID_VALUE:
2550 value = alcErrInvalidValue;
2551 break;
2553 case ALC_INVALID_DEVICE:
2554 value = alcErrInvalidDevice;
2555 break;
2557 case ALC_INVALID_CONTEXT:
2558 value = alcErrInvalidContext;
2559 break;
2561 case ALC_OUT_OF_MEMORY:
2562 value = alcErrOutOfMemory;
2563 break;
2565 case ALC_DEVICE_SPECIFIER:
2566 value = alcDefaultName;
2567 break;
2569 case ALC_ALL_DEVICES_SPECIFIER:
2570 if(VerifyDevice(&Device))
2572 value = al_string_get_cstr(Device->DeviceName);
2573 ALCdevice_DecRef(Device);
2575 else
2577 ProbeAllDevicesList();
2578 value = al_string_get_cstr(alcAllDevicesList);
2580 break;
2582 case ALC_CAPTURE_DEVICE_SPECIFIER:
2583 if(VerifyDevice(&Device))
2585 value = al_string_get_cstr(Device->DeviceName);
2586 ALCdevice_DecRef(Device);
2588 else
2590 ProbeCaptureDeviceList();
2591 value = al_string_get_cstr(alcCaptureDeviceList);
2593 break;
2595 /* Default devices are always first in the list */
2596 case ALC_DEFAULT_DEVICE_SPECIFIER:
2597 value = alcDefaultName;
2598 break;
2600 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2601 if(al_string_empty(alcAllDevicesList))
2602 ProbeAllDevicesList();
2604 VerifyDevice(&Device);
2606 free(alcDefaultAllDevicesSpecifier);
2607 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2608 if(!alcDefaultAllDevicesSpecifier)
2609 alcSetError(Device, ALC_OUT_OF_MEMORY);
2611 value = alcDefaultAllDevicesSpecifier;
2612 if(Device) ALCdevice_DecRef(Device);
2613 break;
2615 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2616 if(al_string_empty(alcCaptureDeviceList))
2617 ProbeCaptureDeviceList();
2619 VerifyDevice(&Device);
2621 free(alcCaptureDefaultDeviceSpecifier);
2622 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2623 if(!alcCaptureDefaultDeviceSpecifier)
2624 alcSetError(Device, ALC_OUT_OF_MEMORY);
2626 value = alcCaptureDefaultDeviceSpecifier;
2627 if(Device) ALCdevice_DecRef(Device);
2628 break;
2630 case ALC_EXTENSIONS:
2631 if(!VerifyDevice(&Device))
2632 value = alcNoDeviceExtList;
2633 else
2635 value = alcExtensionList;
2636 ALCdevice_DecRef(Device);
2638 break;
2640 case ALC_HRTF_SPECIFIER_SOFT:
2641 if(!VerifyDevice(&Device))
2642 alcSetError(NULL, ALC_INVALID_DEVICE);
2643 else
2645 LockLists();
2646 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2647 UnlockLists();
2648 ALCdevice_DecRef(Device);
2650 break;
2652 default:
2653 VerifyDevice(&Device);
2654 alcSetError(Device, ALC_INVALID_ENUM);
2655 if(Device) ALCdevice_DecRef(Device);
2656 break;
2659 return value;
2663 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2665 ALCsizei i;
2667 if(size <= 0 || values == NULL)
2669 alcSetError(device, ALC_INVALID_VALUE);
2670 return 0;
2673 if(!device)
2675 switch(param)
2677 case ALC_MAJOR_VERSION:
2678 values[0] = alcMajorVersion;
2679 return 1;
2680 case ALC_MINOR_VERSION:
2681 values[0] = alcMinorVersion;
2682 return 1;
2684 case ALC_ATTRIBUTES_SIZE:
2685 case ALC_ALL_ATTRIBUTES:
2686 case ALC_FREQUENCY:
2687 case ALC_REFRESH:
2688 case ALC_SYNC:
2689 case ALC_MONO_SOURCES:
2690 case ALC_STEREO_SOURCES:
2691 case ALC_CAPTURE_SAMPLES:
2692 case ALC_FORMAT_CHANNELS_SOFT:
2693 case ALC_FORMAT_TYPE_SOFT:
2694 alcSetError(NULL, ALC_INVALID_DEVICE);
2695 return 0;
2697 default:
2698 alcSetError(NULL, ALC_INVALID_ENUM);
2699 return 0;
2701 return 0;
2704 if(device->Type == Capture)
2706 switch(param)
2708 case ALC_CAPTURE_SAMPLES:
2709 V0(device->Backend,lock)();
2710 values[0] = V0(device->Backend,availableSamples)();
2711 V0(device->Backend,unlock)();
2712 return 1;
2714 case ALC_CONNECTED:
2715 values[0] = device->Connected;
2716 return 1;
2718 default:
2719 alcSetError(device, ALC_INVALID_ENUM);
2720 return 0;
2722 return 0;
2725 /* render device */
2726 switch(param)
2728 case ALC_MAJOR_VERSION:
2729 values[0] = alcMajorVersion;
2730 return 1;
2732 case ALC_MINOR_VERSION:
2733 values[0] = alcMinorVersion;
2734 return 1;
2736 case ALC_EFX_MAJOR_VERSION:
2737 values[0] = alcEFXMajorVersion;
2738 return 1;
2740 case ALC_EFX_MINOR_VERSION:
2741 values[0] = alcEFXMinorVersion;
2742 return 1;
2744 case ALC_ATTRIBUTES_SIZE:
2745 values[0] = 17;
2746 return 1;
2748 case ALC_ALL_ATTRIBUTES:
2749 if(size < 17)
2751 alcSetError(device, ALC_INVALID_VALUE);
2752 return 0;
2755 i = 0;
2756 values[i++] = ALC_FREQUENCY;
2757 values[i++] = device->Frequency;
2759 if(device->Type != Loopback)
2761 values[i++] = ALC_REFRESH;
2762 values[i++] = device->Frequency / device->UpdateSize;
2764 values[i++] = ALC_SYNC;
2765 values[i++] = ALC_FALSE;
2767 else
2769 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2770 values[i++] = device->FmtChans;
2772 values[i++] = ALC_FORMAT_TYPE_SOFT;
2773 values[i++] = device->FmtType;
2776 values[i++] = ALC_MONO_SOURCES;
2777 values[i++] = device->NumMonoSources;
2779 values[i++] = ALC_STEREO_SOURCES;
2780 values[i++] = device->NumStereoSources;
2782 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2783 values[i++] = device->NumAuxSends;
2785 values[i++] = ALC_HRTF_SOFT;
2786 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2788 values[i++] = ALC_HRTF_STATUS_SOFT;
2789 values[i++] = device->Hrtf_Status;
2791 values[i++] = 0;
2792 return i;
2794 case ALC_FREQUENCY:
2795 values[0] = device->Frequency;
2796 return 1;
2798 case ALC_REFRESH:
2799 if(device->Type == Loopback)
2801 alcSetError(device, ALC_INVALID_DEVICE);
2802 return 0;
2804 values[0] = device->Frequency / device->UpdateSize;
2805 return 1;
2807 case ALC_SYNC:
2808 if(device->Type == Loopback)
2810 alcSetError(device, ALC_INVALID_DEVICE);
2811 return 0;
2813 values[0] = ALC_FALSE;
2814 return 1;
2816 case ALC_FORMAT_CHANNELS_SOFT:
2817 if(device->Type != Loopback)
2819 alcSetError(device, ALC_INVALID_DEVICE);
2820 return 0;
2822 values[0] = device->FmtChans;
2823 return 1;
2825 case ALC_FORMAT_TYPE_SOFT:
2826 if(device->Type != Loopback)
2828 alcSetError(device, ALC_INVALID_DEVICE);
2829 return 0;
2831 values[0] = device->FmtType;
2832 return 1;
2834 case ALC_MONO_SOURCES:
2835 values[0] = device->NumMonoSources;
2836 return 1;
2838 case ALC_STEREO_SOURCES:
2839 values[0] = device->NumStereoSources;
2840 return 1;
2842 case ALC_MAX_AUXILIARY_SENDS:
2843 values[0] = device->NumAuxSends;
2844 return 1;
2846 case ALC_CONNECTED:
2847 values[0] = device->Connected;
2848 return 1;
2850 case ALC_HRTF_SOFT:
2851 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2852 return 1;
2854 case ALC_HRTF_STATUS_SOFT:
2855 values[0] = device->Hrtf_Status;
2856 return 1;
2858 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2859 FreeHrtfList(&device->Hrtf_List);
2860 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2861 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2862 return 1;
2864 default:
2865 alcSetError(device, ALC_INVALID_ENUM);
2866 return 0;
2868 return 0;
2871 /* alcGetIntegerv
2873 * Returns information about the device and the version of OpenAL
2875 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2877 VerifyDevice(&device);
2878 if(size <= 0 || values == NULL)
2879 alcSetError(device, ALC_INVALID_VALUE);
2880 else
2881 GetIntegerv(device, param, size, values);
2882 if(device) ALCdevice_DecRef(device);
2885 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2887 ALCint *ivals;
2888 ALsizei i;
2890 VerifyDevice(&device);
2891 if(size <= 0 || values == NULL)
2892 alcSetError(device, ALC_INVALID_VALUE);
2893 else if(!device || device->Type == Capture)
2895 ivals = malloc(size * sizeof(ALCint));
2896 size = GetIntegerv(device, pname, size, ivals);
2897 for(i = 0;i < size;i++)
2898 values[i] = ivals[i];
2899 free(ivals);
2901 else /* render device */
2903 switch(pname)
2905 case ALC_ATTRIBUTES_SIZE:
2906 *values = 19;
2907 break;
2909 case ALC_ALL_ATTRIBUTES:
2910 if(size < 19)
2911 alcSetError(device, ALC_INVALID_VALUE);
2912 else
2914 int i = 0;
2916 V0(device->Backend,lock)();
2917 values[i++] = ALC_FREQUENCY;
2918 values[i++] = device->Frequency;
2920 if(device->Type != Loopback)
2922 values[i++] = ALC_REFRESH;
2923 values[i++] = device->Frequency / device->UpdateSize;
2925 values[i++] = ALC_SYNC;
2926 values[i++] = ALC_FALSE;
2928 else
2930 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2931 values[i++] = device->FmtChans;
2933 values[i++] = ALC_FORMAT_TYPE_SOFT;
2934 values[i++] = device->FmtType;
2937 values[i++] = ALC_MONO_SOURCES;
2938 values[i++] = device->NumMonoSources;
2940 values[i++] = ALC_STEREO_SOURCES;
2941 values[i++] = device->NumStereoSources;
2943 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2944 values[i++] = device->NumAuxSends;
2946 values[i++] = ALC_HRTF_SOFT;
2947 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2949 values[i++] = ALC_HRTF_STATUS_SOFT;
2950 values[i++] = device->Hrtf_Status;
2952 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2953 values[i++] = device->ClockBase +
2954 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2956 values[i++] = 0;
2957 V0(device->Backend,unlock)();
2959 break;
2961 case ALC_DEVICE_CLOCK_SOFT:
2962 V0(device->Backend,lock)();
2963 *values = device->ClockBase +
2964 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2965 V0(device->Backend,unlock)();
2966 break;
2968 default:
2969 ivals = malloc(size * sizeof(ALCint));
2970 size = GetIntegerv(device, pname, size, ivals);
2971 for(i = 0;i < size;i++)
2972 values[i] = ivals[i];
2973 free(ivals);
2974 break;
2977 if(device)
2978 ALCdevice_DecRef(device);
2982 /* alcIsExtensionPresent
2984 * Determines if there is support for a particular extension
2986 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2988 ALCboolean bResult = ALC_FALSE;
2990 VerifyDevice(&device);
2992 if(!extName)
2993 alcSetError(device, ALC_INVALID_VALUE);
2994 else
2996 size_t len = strlen(extName);
2997 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2998 while(ptr && *ptr)
3000 if(strncasecmp(ptr, extName, len) == 0 &&
3001 (ptr[len] == '\0' || isspace(ptr[len])))
3003 bResult = ALC_TRUE;
3004 break;
3006 if((ptr=strchr(ptr, ' ')) != NULL)
3008 do {
3009 ++ptr;
3010 } while(isspace(*ptr));
3014 if(device)
3015 ALCdevice_DecRef(device);
3016 return bResult;
3020 /* alcGetProcAddress
3022 * Retrieves the function address for a particular extension function
3024 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3026 ALCvoid *ptr = NULL;
3028 if(!funcName)
3030 VerifyDevice(&device);
3031 alcSetError(device, ALC_INVALID_VALUE);
3032 if(device) ALCdevice_DecRef(device);
3034 else
3036 ALsizei i = 0;
3037 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3038 i++;
3039 ptr = alcFunctions[i].address;
3042 return ptr;
3046 /* alcGetEnumValue
3048 * Get the value for a particular ALC enumeration name
3050 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3052 ALCenum val = 0;
3054 if(!enumName)
3056 VerifyDevice(&device);
3057 alcSetError(device, ALC_INVALID_VALUE);
3058 if(device) ALCdevice_DecRef(device);
3060 else
3062 ALsizei i = 0;
3063 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3064 i++;
3065 val = enumeration[i].value;
3068 return val;
3072 /* alcCreateContext
3074 * Create and attach a context to the given device.
3076 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3078 ALCcontext *ALContext;
3079 ALCenum err;
3081 LockLists();
3082 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3084 UnlockLists();
3085 alcSetError(device, ALC_INVALID_DEVICE);
3086 if(device) ALCdevice_DecRef(device);
3087 return NULL;
3090 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3092 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3094 UnlockLists();
3095 alcSetError(device, err);
3096 if(err == ALC_INVALID_DEVICE)
3098 V0(device->Backend,lock)();
3099 aluHandleDisconnect(device);
3100 V0(device->Backend,unlock)();
3102 ALCdevice_DecRef(device);
3103 return NULL;
3106 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3107 if(ALContext)
3109 InitRef(&ALContext->ref, 1);
3110 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3112 VECTOR_INIT(ALContext->ActiveAuxSlots);
3114 ALContext->VoiceCount = 0;
3115 ALContext->MaxVoices = 256;
3116 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3118 if(!ALContext || !ALContext->Voices)
3120 if(!ATOMIC_LOAD(&device->ContextList))
3122 V0(device->Backend,stop)();
3123 device->Flags &= ~DEVICE_RUNNING;
3125 UnlockLists();
3127 if(ALContext)
3129 al_free(ALContext->Voices);
3130 ALContext->Voices = NULL;
3132 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3134 al_free(ALContext);
3135 ALContext = NULL;
3138 alcSetError(device, ALC_OUT_OF_MEMORY);
3139 ALCdevice_DecRef(device);
3140 return NULL;
3143 ALContext->Device = device;
3144 ALCdevice_IncRef(device);
3145 InitContext(ALContext);
3148 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3149 do {
3150 ALContext->next = head;
3151 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3153 UnlockLists();
3155 ALCdevice_DecRef(device);
3157 TRACE("Created context %p\n", ALContext);
3158 return ALContext;
3161 /* alcDestroyContext
3163 * Remove a context from its device
3165 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3167 ALCdevice *Device;
3169 LockLists();
3170 /* alcGetContextsDevice sets an error for invalid contexts */
3171 Device = alcGetContextsDevice(context);
3172 if(Device)
3174 ReleaseContext(context, Device);
3175 if(!ATOMIC_LOAD(&Device->ContextList))
3177 V0(Device->Backend,stop)();
3178 Device->Flags &= ~DEVICE_RUNNING;
3181 UnlockLists();
3185 /* alcGetCurrentContext
3187 * Returns the currently active context on the calling thread
3189 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3191 ALCcontext *Context = altss_get(LocalContext);
3192 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3193 return Context;
3196 /* alcGetThreadContext
3198 * Returns the currently active thread-local context
3200 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3202 return altss_get(LocalContext);
3206 /* alcMakeContextCurrent
3208 * Makes the given context the active process-wide context, and removes the
3209 * thread-local context for the calling thread.
3211 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3213 /* context must be valid or NULL */
3214 if(context && !VerifyContext(&context))
3216 alcSetError(NULL, ALC_INVALID_CONTEXT);
3217 return ALC_FALSE;
3219 /* context's reference count is already incremented */
3220 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3221 if(context) ALCcontext_DecRef(context);
3223 if((context=altss_get(LocalContext)) != NULL)
3225 altss_set(LocalContext, NULL);
3226 ALCcontext_DecRef(context);
3229 return ALC_TRUE;
3232 /* alcSetThreadContext
3234 * Makes the given context the active context for the current thread
3236 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3238 ALCcontext *old;
3240 /* context must be valid or NULL */
3241 if(context && !VerifyContext(&context))
3243 alcSetError(NULL, ALC_INVALID_CONTEXT);
3244 return ALC_FALSE;
3246 /* context's reference count is already incremented */
3247 old = altss_get(LocalContext);
3248 altss_set(LocalContext, context);
3249 if(old) ALCcontext_DecRef(old);
3251 return ALC_TRUE;
3255 /* alcGetContextsDevice
3257 * Returns the device that a particular context is attached to
3259 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3261 ALCdevice *Device;
3263 if(!VerifyContext(&Context))
3265 alcSetError(NULL, ALC_INVALID_CONTEXT);
3266 return NULL;
3268 Device = Context->Device;
3269 ALCcontext_DecRef(Context);
3271 return Device;
3275 /* alcOpenDevice
3277 * Opens the named device.
3279 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3281 const ALCchar *fmt;
3282 ALCdevice *device;
3283 ALCenum err;
3285 DO_INITCONFIG();
3287 if(!PlaybackBackend.name)
3289 alcSetError(NULL, ALC_INVALID_VALUE);
3290 return NULL;
3293 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3294 #ifdef _WIN32
3295 /* Some old Windows apps hardcode these expecting OpenAL to use a
3296 * specific audio API, even when they're not enumerated. Creative's
3297 * router effectively ignores them too.
3299 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3300 || strcasecmp(deviceName, "MMSYSTEM") == 0
3301 #endif
3303 deviceName = NULL;
3305 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3306 if(!device)
3308 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3309 return NULL;
3312 //Validate device
3313 InitRef(&device->ref, 1);
3314 device->Connected = ALC_TRUE;
3315 device->Type = Playback;
3316 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3318 device->Flags = 0;
3319 device->Bs2b = NULL;
3320 device->Uhj_Encoder = NULL;
3321 VECTOR_INIT(device->Hrtf_List);
3322 AL_STRING_INIT(device->Hrtf_Name);
3323 device->Render_Mode = NormalRender;
3324 AL_STRING_INIT(device->DeviceName);
3325 device->Dry.Buffer = NULL;
3326 device->Dry.NumChannels = 0;
3327 device->VirtOut.Buffer = NULL;
3328 device->VirtOut.NumChannels = 0;
3329 device->RealOut.Buffer = NULL;
3330 device->RealOut.NumChannels = 0;
3332 ATOMIC_INIT(&device->ContextList, NULL);
3334 device->ClockBase = 0;
3335 device->SamplesDone = 0;
3337 device->MaxNoOfSources = 256;
3338 device->AuxiliaryEffectSlotMax = 4;
3339 device->NumAuxSends = MAX_SENDS;
3341 InitUIntMap(&device->BufferMap, ~0);
3342 InitUIntMap(&device->EffectMap, ~0);
3343 InitUIntMap(&device->FilterMap, ~0);
3345 //Set output format
3346 device->FmtChans = DevFmtChannelsDefault;
3347 device->FmtType = DevFmtTypeDefault;
3348 device->Frequency = DEFAULT_OUTPUT_RATE;
3349 device->IsHeadphones = AL_FALSE;
3350 device->NumUpdates = 4;
3351 device->UpdateSize = 1024;
3353 if(!PlaybackBackend.getFactory)
3354 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3355 ALCbackend_Playback);
3356 else
3358 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3359 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3361 if(!device->Backend)
3363 al_free(device);
3364 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3365 return NULL;
3369 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3371 static const struct {
3372 const char name[16];
3373 enum DevFmtChannels chans;
3374 } chanlist[] = {
3375 { "mono", DevFmtMono },
3376 { "stereo", DevFmtStereo },
3377 { "quad", DevFmtQuad },
3378 { "surround51", DevFmtX51 },
3379 { "surround61", DevFmtX61 },
3380 { "surround71", DevFmtX71 },
3381 { "surround51rear", DevFmtX51Rear },
3383 size_t i;
3385 for(i = 0;i < COUNTOF(chanlist);i++)
3387 if(strcasecmp(chanlist[i].name, fmt) == 0)
3389 device->FmtChans = chanlist[i].chans;
3390 device->Flags |= DEVICE_CHANNELS_REQUEST;
3391 break;
3394 if(i == COUNTOF(chanlist))
3395 ERR("Unsupported channels: %s\n", fmt);
3397 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3399 static const struct {
3400 const char name[16];
3401 enum DevFmtType type;
3402 } typelist[] = {
3403 { "int8", DevFmtByte },
3404 { "uint8", DevFmtUByte },
3405 { "int16", DevFmtShort },
3406 { "uint16", DevFmtUShort },
3407 { "int32", DevFmtInt },
3408 { "uint32", DevFmtUInt },
3409 { "float32", DevFmtFloat },
3411 size_t i;
3413 for(i = 0;i < COUNTOF(typelist);i++)
3415 if(strcasecmp(typelist[i].name, fmt) == 0)
3417 device->FmtType = typelist[i].type;
3418 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3419 break;
3422 if(i == COUNTOF(typelist))
3423 ERR("Unsupported sample-type: %s\n", fmt);
3426 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3428 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3429 if(device->Frequency < MIN_OUTPUT_RATE)
3430 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3431 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3434 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3435 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3437 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3438 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3439 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3440 device->UpdateSize = (device->UpdateSize+3)&~3;
3442 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3443 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3445 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3446 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3448 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3449 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3451 device->NumStereoSources = 1;
3452 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3454 // Find a playback device to open
3455 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3457 DELETE_OBJ(device->Backend);
3458 al_free(device);
3459 alcSetError(NULL, err);
3460 return NULL;
3463 if(DefaultEffect.type != AL_EFFECT_NULL)
3465 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3466 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3468 device->DefaultSlot = NULL;
3469 ERR("Failed to initialize the default effect slot\n");
3471 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3473 ALeffectState *state = device->DefaultSlot->EffectState;
3474 device->DefaultSlot = NULL;
3475 DELETE_OBJ(state);
3476 ERR("Failed to initialize the default effect\n");
3478 else
3479 aluInitEffectPanning(device->DefaultSlot);
3483 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3484 do {
3485 device->next = head;
3486 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3489 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3490 return device;
3493 /* alcCloseDevice
3495 * Closes the given device.
3497 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3499 ALCdevice *list, *origdev, *nextdev;
3500 ALCcontext *ctx;
3502 LockLists();
3503 list = ATOMIC_LOAD(&DeviceList);
3504 do {
3505 if(list == device)
3506 break;
3507 } while((list=list->next) != NULL);
3508 if(!list || list->Type == Capture)
3510 alcSetError(list, ALC_INVALID_DEVICE);
3511 UnlockLists();
3512 return ALC_FALSE;
3515 origdev = device;
3516 nextdev = device->next;
3517 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3519 do {
3520 list = origdev;
3521 origdev = device;
3522 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3524 UnlockLists();
3526 ctx = ATOMIC_LOAD(&device->ContextList);
3527 while(ctx != NULL)
3529 ALCcontext *next = ctx->next;
3530 WARN("Releasing context %p\n", ctx);
3531 ReleaseContext(ctx, device);
3532 ctx = next;
3534 if((device->Flags&DEVICE_RUNNING))
3535 V0(device->Backend,stop)();
3536 device->Flags &= ~DEVICE_RUNNING;
3538 ALCdevice_DecRef(device);
3540 return ALC_TRUE;
3544 /************************************************
3545 * ALC capture functions
3546 ************************************************/
3547 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3549 ALCdevice *device = NULL;
3550 ALCenum err;
3552 DO_INITCONFIG();
3554 if(!CaptureBackend.name)
3556 alcSetError(NULL, ALC_INVALID_VALUE);
3557 return NULL;
3560 if(samples <= 0)
3562 alcSetError(NULL, ALC_INVALID_VALUE);
3563 return NULL;
3566 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3567 deviceName = NULL;
3569 device = al_calloc(16, sizeof(ALCdevice));
3570 if(!device)
3572 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3573 return NULL;
3576 //Validate device
3577 InitRef(&device->ref, 1);
3578 device->Connected = ALC_TRUE;
3579 device->Type = Capture;
3581 VECTOR_INIT(device->Hrtf_List);
3582 AL_STRING_INIT(device->Hrtf_Name);
3584 AL_STRING_INIT(device->DeviceName);
3585 device->Dry.Buffer = NULL;
3586 device->Dry.NumChannels = 0;
3587 device->VirtOut.Buffer = NULL;
3588 device->VirtOut.NumChannels = 0;
3589 device->RealOut.Buffer = NULL;
3590 device->RealOut.NumChannels = 0;
3592 InitUIntMap(&device->BufferMap, ~0);
3593 InitUIntMap(&device->EffectMap, ~0);
3594 InitUIntMap(&device->FilterMap, ~0);
3596 if(!CaptureBackend.getFactory)
3597 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3598 ALCbackend_Capture);
3599 else
3601 ALCbackendFactory *factory = CaptureBackend.getFactory();
3602 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3604 if(!device->Backend)
3606 al_free(device);
3607 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3608 return NULL;
3611 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3612 device->Frequency = frequency;
3614 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3615 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3617 al_free(device);
3618 alcSetError(NULL, ALC_INVALID_ENUM);
3619 return NULL;
3621 device->IsHeadphones = AL_FALSE;
3623 device->UpdateSize = samples;
3624 device->NumUpdates = 1;
3626 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3628 al_free(device);
3629 alcSetError(NULL, err);
3630 return NULL;
3634 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3635 do {
3636 device->next = head;
3637 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3640 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3641 return device;
3644 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3646 ALCdevice *list, *next, *nextdev;
3648 LockLists();
3649 list = ATOMIC_LOAD(&DeviceList);
3650 do {
3651 if(list == device)
3652 break;
3653 } while((list=list->next) != NULL);
3654 if(!list || list->Type != Capture)
3656 alcSetError(list, ALC_INVALID_DEVICE);
3657 UnlockLists();
3658 return ALC_FALSE;
3661 next = device;
3662 nextdev = device->next;
3663 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3665 do {
3666 list = next;
3667 next = device;
3668 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3670 UnlockLists();
3672 ALCdevice_DecRef(device);
3674 return ALC_TRUE;
3677 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3679 if(!VerifyDevice(&device) || device->Type != Capture)
3680 alcSetError(device, ALC_INVALID_DEVICE);
3681 else
3683 V0(device->Backend,lock)();
3684 if(!device->Connected)
3685 alcSetError(device, ALC_INVALID_DEVICE);
3686 else if(!(device->Flags&DEVICE_RUNNING))
3688 if(V0(device->Backend,start)())
3689 device->Flags |= DEVICE_RUNNING;
3690 else
3692 aluHandleDisconnect(device);
3693 alcSetError(device, ALC_INVALID_DEVICE);
3696 V0(device->Backend,unlock)();
3699 if(device) ALCdevice_DecRef(device);
3702 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3704 if(!VerifyDevice(&device) || device->Type != Capture)
3705 alcSetError(device, ALC_INVALID_DEVICE);
3706 else
3708 V0(device->Backend,lock)();
3709 if((device->Flags&DEVICE_RUNNING))
3710 V0(device->Backend,stop)();
3711 device->Flags &= ~DEVICE_RUNNING;
3712 V0(device->Backend,unlock)();
3715 if(device) ALCdevice_DecRef(device);
3718 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3720 if(!VerifyDevice(&device) || device->Type != Capture)
3721 alcSetError(device, ALC_INVALID_DEVICE);
3722 else
3724 ALCenum err = ALC_INVALID_VALUE;
3726 V0(device->Backend,lock)();
3727 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3728 err = V(device->Backend,captureSamples)(buffer, samples);
3729 V0(device->Backend,unlock)();
3731 if(err != ALC_NO_ERROR)
3732 alcSetError(device, err);
3734 if(device) ALCdevice_DecRef(device);
3738 /************************************************
3739 * ALC loopback functions
3740 ************************************************/
3742 /* alcLoopbackOpenDeviceSOFT
3744 * Open a loopback device, for manual rendering.
3746 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3748 ALCbackendFactory *factory;
3749 ALCdevice *device;
3751 DO_INITCONFIG();
3753 /* Make sure the device name, if specified, is us. */
3754 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3756 alcSetError(NULL, ALC_INVALID_VALUE);
3757 return NULL;
3760 device = al_calloc(16, sizeof(ALCdevice));
3761 if(!device)
3763 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3764 return NULL;
3767 //Validate device
3768 InitRef(&device->ref, 1);
3769 device->Connected = ALC_TRUE;
3770 device->Type = Loopback;
3771 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3773 device->Flags = 0;
3774 VECTOR_INIT(device->Hrtf_List);
3775 AL_STRING_INIT(device->Hrtf_Name);
3776 device->Bs2b = NULL;
3777 device->Uhj_Encoder = NULL;
3778 device->Render_Mode = NormalRender;
3779 AL_STRING_INIT(device->DeviceName);
3780 device->Dry.Buffer = NULL;
3781 device->Dry.NumChannels = 0;
3782 device->VirtOut.Buffer = NULL;
3783 device->VirtOut.NumChannels = 0;
3784 device->RealOut.Buffer = NULL;
3785 device->RealOut.NumChannels = 0;
3787 ATOMIC_INIT(&device->ContextList, NULL);
3789 device->ClockBase = 0;
3790 device->SamplesDone = 0;
3792 device->MaxNoOfSources = 256;
3793 device->AuxiliaryEffectSlotMax = 4;
3794 device->NumAuxSends = MAX_SENDS;
3796 InitUIntMap(&device->BufferMap, ~0);
3797 InitUIntMap(&device->EffectMap, ~0);
3798 InitUIntMap(&device->FilterMap, ~0);
3800 factory = ALCloopbackFactory_getFactory();
3801 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3802 if(!device->Backend)
3804 al_free(device);
3805 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3806 return NULL;
3809 //Set output format
3810 device->NumUpdates = 0;
3811 device->UpdateSize = 0;
3813 device->Frequency = DEFAULT_OUTPUT_RATE;
3814 device->FmtChans = DevFmtChannelsDefault;
3815 device->FmtType = DevFmtTypeDefault;
3816 device->IsHeadphones = AL_FALSE;
3818 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3819 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3821 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3822 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3824 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3825 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3827 device->NumStereoSources = 1;
3828 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3830 // Open the "backend"
3831 V(device->Backend,open)("Loopback");
3834 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3835 do {
3836 device->next = head;
3837 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3840 TRACE("Created device %p\n", device);
3841 return device;
3844 /* alcIsRenderFormatSupportedSOFT
3846 * Determines if the loopback device supports the given format for rendering.
3848 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3850 ALCboolean ret = ALC_FALSE;
3852 if(!VerifyDevice(&device) || device->Type != Loopback)
3853 alcSetError(device, ALC_INVALID_DEVICE);
3854 else if(freq <= 0)
3855 alcSetError(device, ALC_INVALID_VALUE);
3856 else
3858 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3859 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3860 freq >= MIN_OUTPUT_RATE)
3861 ret = ALC_TRUE;
3863 if(device) ALCdevice_DecRef(device);
3865 return ret;
3868 /* alcRenderSamplesSOFT
3870 * Renders some samples into a buffer, using the format last set by the
3871 * attributes given to alcCreateContext.
3873 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3875 if(!VerifyDevice(&device) || device->Type != Loopback)
3876 alcSetError(device, ALC_INVALID_DEVICE);
3877 else if(samples < 0 || (samples > 0 && buffer == NULL))
3878 alcSetError(device, ALC_INVALID_VALUE);
3879 else
3880 aluMixData(device, buffer, samples);
3881 if(device) ALCdevice_DecRef(device);
3885 /************************************************
3886 * ALC DSP pause/resume functions
3887 ************************************************/
3889 /* alcDevicePauseSOFT
3891 * Pause the DSP to stop audio processing.
3893 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3895 if(!VerifyDevice(&device) || device->Type != Playback)
3896 alcSetError(device, ALC_INVALID_DEVICE);
3897 else
3899 LockLists();
3900 if((device->Flags&DEVICE_RUNNING))
3901 V0(device->Backend,stop)();
3902 device->Flags &= ~DEVICE_RUNNING;
3903 device->Flags |= DEVICE_PAUSED;
3904 UnlockLists();
3906 if(device) ALCdevice_DecRef(device);
3909 /* alcDeviceResumeSOFT
3911 * Resume the DSP to restart audio processing.
3913 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3915 if(!VerifyDevice(&device) || device->Type != Playback)
3916 alcSetError(device, ALC_INVALID_DEVICE);
3917 else
3919 LockLists();
3920 if((device->Flags&DEVICE_PAUSED))
3922 device->Flags &= ~DEVICE_PAUSED;
3923 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3925 if(V0(device->Backend,start)() != ALC_FALSE)
3926 device->Flags |= DEVICE_RUNNING;
3927 else
3929 alcSetError(device, ALC_INVALID_DEVICE);
3930 V0(device->Backend,lock)();
3931 aluHandleDisconnect(device);
3932 V0(device->Backend,unlock)();
3936 UnlockLists();
3938 if(device) ALCdevice_DecRef(device);
3942 /************************************************
3943 * ALC HRTF functions
3944 ************************************************/
3946 /* alcGetStringiSOFT
3948 * Gets a string parameter at the given index.
3950 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3952 const ALCchar *str = NULL;
3954 if(!VerifyDevice(&device) || device->Type == Capture)
3955 alcSetError(device, ALC_INVALID_DEVICE);
3956 else switch(paramName)
3958 case ALC_HRTF_SPECIFIER_SOFT:
3959 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
3960 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
3961 else
3962 alcSetError(device, ALC_INVALID_VALUE);
3963 break;
3965 default:
3966 alcSetError(device, ALC_INVALID_ENUM);
3967 break;
3969 if(device) ALCdevice_DecRef(device);
3971 return str;
3974 /* alcResetDeviceSOFT
3976 * Resets the given device output, using the specified attribute list.
3978 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
3980 ALCenum err;
3982 LockLists();
3983 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3985 UnlockLists();
3986 alcSetError(device, ALC_INVALID_DEVICE);
3987 if(device) ALCdevice_DecRef(device);
3988 return ALC_FALSE;
3991 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
3993 UnlockLists();
3994 alcSetError(device, err);
3995 if(err == ALC_INVALID_DEVICE)
3997 V0(device->Backend,lock)();
3998 aluHandleDisconnect(device);
3999 V0(device->Backend,unlock)();
4001 ALCdevice_DecRef(device);
4002 return ALC_FALSE;
4004 UnlockLists();
4005 ALCdevice_DecRef(device);
4007 return ALC_TRUE;