Correct conversion from polar to cartesian coords for HRTF
[openal-soft.git] / Alc / ALc.c
blobbaf7f01b4fd05568ac1d8a05d49e141f84dee6c2
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 "alMidi.h"
39 #include "bs2b.h"
40 #include "alu.h"
42 #include "compat.h"
43 #include "threads.h"
44 #include "alstring.h"
46 #include "backends/base.h"
47 #include "midi/base.h"
50 /************************************************
51 * Backends
52 ************************************************/
53 struct BackendInfo {
54 const char *name;
55 ALCbackendFactory* (*getFactory)(void);
56 ALCboolean (*Init)(BackendFuncs*);
57 void (*Deinit)(void);
58 void (*Probe)(enum DevProbe);
59 BackendFuncs Funcs;
62 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
63 static struct BackendInfo BackendList[] = {
64 #ifdef HAVE_JACK
65 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
66 #endif
67 #ifdef HAVE_PULSEAUDIO
68 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
69 #endif
70 #ifdef HAVE_ALSA
71 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
72 #endif
73 #ifdef HAVE_COREAUDIO
74 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
75 #endif
76 #ifdef HAVE_OSS
77 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
78 #endif
79 #ifdef HAVE_SOLARIS
80 { "solaris", NULL, alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs },
81 #endif
82 #ifdef HAVE_SNDIO
83 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
84 #endif
85 #ifdef HAVE_QSA
86 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
87 #endif
88 #ifdef HAVE_MMDEVAPI
89 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
90 #endif
91 #ifdef HAVE_DSOUND
92 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
93 #endif
94 #ifdef HAVE_WINMM
95 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
96 #endif
97 #ifdef HAVE_PORTAUDIO
98 { "port", NULL, alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs },
99 #endif
100 #ifdef HAVE_OPENSL
101 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
102 #endif
104 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
105 #ifdef HAVE_WAVE
106 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
107 #endif
109 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
111 #undef EmptyFuncs
113 static struct BackendInfo PlaybackBackend;
114 static struct BackendInfo CaptureBackend;
117 /************************************************
118 * Functions, enums, and errors
119 ************************************************/
120 typedef struct ALCfunction {
121 const ALCchar *funcName;
122 ALCvoid *address;
123 } ALCfunction;
125 typedef struct ALCenums {
126 const ALCchar *enumName;
127 ALCenum value;
128 } ALCenums;
130 #define DECL(x) { #x, (ALCvoid*)(x) }
131 static const ALCfunction alcFunctions[] = {
132 DECL(alcCreateContext),
133 DECL(alcMakeContextCurrent),
134 DECL(alcProcessContext),
135 DECL(alcSuspendContext),
136 DECL(alcDestroyContext),
137 DECL(alcGetCurrentContext),
138 DECL(alcGetContextsDevice),
139 DECL(alcOpenDevice),
140 DECL(alcCloseDevice),
141 DECL(alcGetError),
142 DECL(alcIsExtensionPresent),
143 DECL(alcGetProcAddress),
144 DECL(alcGetEnumValue),
145 DECL(alcGetString),
146 DECL(alcGetIntegerv),
147 DECL(alcCaptureOpenDevice),
148 DECL(alcCaptureCloseDevice),
149 DECL(alcCaptureStart),
150 DECL(alcCaptureStop),
151 DECL(alcCaptureSamples),
153 DECL(alcSetThreadContext),
154 DECL(alcGetThreadContext),
156 DECL(alcLoopbackOpenDeviceSOFT),
157 DECL(alcIsRenderFormatSupportedSOFT),
158 DECL(alcRenderSamplesSOFT),
160 DECL(alcDevicePauseSOFT),
161 DECL(alcDeviceResumeSOFT),
163 DECL(alcGetInteger64vSOFT),
165 DECL(alEnable),
166 DECL(alDisable),
167 DECL(alIsEnabled),
168 DECL(alGetString),
169 DECL(alGetBooleanv),
170 DECL(alGetIntegerv),
171 DECL(alGetFloatv),
172 DECL(alGetDoublev),
173 DECL(alGetBoolean),
174 DECL(alGetInteger),
175 DECL(alGetFloat),
176 DECL(alGetDouble),
177 DECL(alGetError),
178 DECL(alIsExtensionPresent),
179 DECL(alGetProcAddress),
180 DECL(alGetEnumValue),
181 DECL(alListenerf),
182 DECL(alListener3f),
183 DECL(alListenerfv),
184 DECL(alListeneri),
185 DECL(alListener3i),
186 DECL(alListeneriv),
187 DECL(alGetListenerf),
188 DECL(alGetListener3f),
189 DECL(alGetListenerfv),
190 DECL(alGetListeneri),
191 DECL(alGetListener3i),
192 DECL(alGetListeneriv),
193 DECL(alGenSources),
194 DECL(alDeleteSources),
195 DECL(alIsSource),
196 DECL(alSourcef),
197 DECL(alSource3f),
198 DECL(alSourcefv),
199 DECL(alSourcei),
200 DECL(alSource3i),
201 DECL(alSourceiv),
202 DECL(alGetSourcef),
203 DECL(alGetSource3f),
204 DECL(alGetSourcefv),
205 DECL(alGetSourcei),
206 DECL(alGetSource3i),
207 DECL(alGetSourceiv),
208 DECL(alSourcePlayv),
209 DECL(alSourceStopv),
210 DECL(alSourceRewindv),
211 DECL(alSourcePausev),
212 DECL(alSourcePlay),
213 DECL(alSourceStop),
214 DECL(alSourceRewind),
215 DECL(alSourcePause),
216 DECL(alSourceQueueBuffers),
217 DECL(alSourceUnqueueBuffers),
218 DECL(alGenBuffers),
219 DECL(alDeleteBuffers),
220 DECL(alIsBuffer),
221 DECL(alBufferData),
222 DECL(alBufferf),
223 DECL(alBuffer3f),
224 DECL(alBufferfv),
225 DECL(alBufferi),
226 DECL(alBuffer3i),
227 DECL(alBufferiv),
228 DECL(alGetBufferf),
229 DECL(alGetBuffer3f),
230 DECL(alGetBufferfv),
231 DECL(alGetBufferi),
232 DECL(alGetBuffer3i),
233 DECL(alGetBufferiv),
234 DECL(alDopplerFactor),
235 DECL(alDopplerVelocity),
236 DECL(alSpeedOfSound),
237 DECL(alDistanceModel),
239 DECL(alGenFilters),
240 DECL(alDeleteFilters),
241 DECL(alIsFilter),
242 DECL(alFilteri),
243 DECL(alFilteriv),
244 DECL(alFilterf),
245 DECL(alFilterfv),
246 DECL(alGetFilteri),
247 DECL(alGetFilteriv),
248 DECL(alGetFilterf),
249 DECL(alGetFilterfv),
250 DECL(alGenEffects),
251 DECL(alDeleteEffects),
252 DECL(alIsEffect),
253 DECL(alEffecti),
254 DECL(alEffectiv),
255 DECL(alEffectf),
256 DECL(alEffectfv),
257 DECL(alGetEffecti),
258 DECL(alGetEffectiv),
259 DECL(alGetEffectf),
260 DECL(alGetEffectfv),
261 DECL(alGenAuxiliaryEffectSlots),
262 DECL(alDeleteAuxiliaryEffectSlots),
263 DECL(alIsAuxiliaryEffectSlot),
264 DECL(alAuxiliaryEffectSloti),
265 DECL(alAuxiliaryEffectSlotiv),
266 DECL(alAuxiliaryEffectSlotf),
267 DECL(alAuxiliaryEffectSlotfv),
268 DECL(alGetAuxiliaryEffectSloti),
269 DECL(alGetAuxiliaryEffectSlotiv),
270 DECL(alGetAuxiliaryEffectSlotf),
271 DECL(alGetAuxiliaryEffectSlotfv),
273 DECL(alBufferSubDataSOFT),
275 DECL(alBufferSamplesSOFT),
276 DECL(alBufferSubSamplesSOFT),
277 DECL(alGetBufferSamplesSOFT),
278 DECL(alIsBufferFormatSupportedSOFT),
280 DECL(alDeferUpdatesSOFT),
281 DECL(alProcessUpdatesSOFT),
283 DECL(alSourcedSOFT),
284 DECL(alSource3dSOFT),
285 DECL(alSourcedvSOFT),
286 DECL(alGetSourcedSOFT),
287 DECL(alGetSource3dSOFT),
288 DECL(alGetSourcedvSOFT),
289 DECL(alSourcei64SOFT),
290 DECL(alSource3i64SOFT),
291 DECL(alSourcei64vSOFT),
292 DECL(alGetSourcei64SOFT),
293 DECL(alGetSource3i64SOFT),
294 DECL(alGetSourcei64vSOFT),
296 DECL(alGenSoundfontsSOFT),
297 DECL(alDeleteSoundfontsSOFT),
298 DECL(alIsSoundfontSOFT),
299 DECL(alGetSoundfontivSOFT),
300 DECL(alSoundfontPresetsSOFT),
301 DECL(alGenPresetsSOFT),
302 DECL(alDeletePresetsSOFT),
303 DECL(alIsPresetSOFT),
304 DECL(alPresetiSOFT),
305 DECL(alPresetivSOFT),
306 DECL(alGetPresetivSOFT),
307 DECL(alPresetFontsoundsSOFT),
308 DECL(alGenFontsoundsSOFT),
309 DECL(alDeleteFontsoundsSOFT),
310 DECL(alIsFontsoundSOFT),
311 DECL(alFontsoundiSOFT),
312 DECL(alFontsound2iSOFT),
313 DECL(alFontsoundivSOFT),
314 DECL(alGetFontsoundivSOFT),
315 DECL(alFontsoundModulatoriSOFT),
316 DECL(alGetFontsoundModulatorivSOFT),
317 DECL(alMidiSoundfontSOFT),
318 DECL(alMidiSoundfontvSOFT),
319 DECL(alMidiEventSOFT),
320 DECL(alMidiSysExSOFT),
321 DECL(alMidiPlaySOFT),
322 DECL(alMidiPauseSOFT),
323 DECL(alMidiStopSOFT),
324 DECL(alMidiResetSOFT),
325 DECL(alMidiGainSOFT),
326 DECL(alGetInteger64SOFT),
327 DECL(alGetInteger64vSOFT),
328 DECL(alLoadSoundfontSOFT),
330 { NULL, NULL }
332 #undef DECL
334 #define DECL(x) { #x, (x) }
335 static const ALCenums enumeration[] = {
336 DECL(ALC_INVALID),
337 DECL(ALC_FALSE),
338 DECL(ALC_TRUE),
340 DECL(ALC_MAJOR_VERSION),
341 DECL(ALC_MINOR_VERSION),
342 DECL(ALC_ATTRIBUTES_SIZE),
343 DECL(ALC_ALL_ATTRIBUTES),
344 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
345 DECL(ALC_DEVICE_SPECIFIER),
346 DECL(ALC_ALL_DEVICES_SPECIFIER),
347 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
348 DECL(ALC_EXTENSIONS),
349 DECL(ALC_FREQUENCY),
350 DECL(ALC_REFRESH),
351 DECL(ALC_SYNC),
352 DECL(ALC_MONO_SOURCES),
353 DECL(ALC_STEREO_SOURCES),
354 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
355 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
356 DECL(ALC_CAPTURE_SAMPLES),
357 DECL(ALC_CONNECTED),
359 DECL(ALC_EFX_MAJOR_VERSION),
360 DECL(ALC_EFX_MINOR_VERSION),
361 DECL(ALC_MAX_AUXILIARY_SENDS),
363 DECL(ALC_FORMAT_CHANNELS_SOFT),
364 DECL(ALC_FORMAT_TYPE_SOFT),
366 DECL(ALC_MONO_SOFT),
367 DECL(ALC_STEREO_SOFT),
368 DECL(ALC_QUAD_SOFT),
369 DECL(ALC_5POINT1_SOFT),
370 DECL(ALC_6POINT1_SOFT),
371 DECL(ALC_7POINT1_SOFT),
373 DECL(ALC_BYTE_SOFT),
374 DECL(ALC_UNSIGNED_BYTE_SOFT),
375 DECL(ALC_SHORT_SOFT),
376 DECL(ALC_UNSIGNED_SHORT_SOFT),
377 DECL(ALC_INT_SOFT),
378 DECL(ALC_UNSIGNED_INT_SOFT),
379 DECL(ALC_FLOAT_SOFT),
381 DECL(ALC_NO_ERROR),
382 DECL(ALC_INVALID_DEVICE),
383 DECL(ALC_INVALID_CONTEXT),
384 DECL(ALC_INVALID_ENUM),
385 DECL(ALC_INVALID_VALUE),
386 DECL(ALC_OUT_OF_MEMORY),
389 DECL(AL_INVALID),
390 DECL(AL_NONE),
391 DECL(AL_FALSE),
392 DECL(AL_TRUE),
394 DECL(AL_SOURCE_RELATIVE),
395 DECL(AL_CONE_INNER_ANGLE),
396 DECL(AL_CONE_OUTER_ANGLE),
397 DECL(AL_PITCH),
398 DECL(AL_POSITION),
399 DECL(AL_DIRECTION),
400 DECL(AL_VELOCITY),
401 DECL(AL_LOOPING),
402 DECL(AL_BUFFER),
403 DECL(AL_GAIN),
404 DECL(AL_MIN_GAIN),
405 DECL(AL_MAX_GAIN),
406 DECL(AL_ORIENTATION),
407 DECL(AL_REFERENCE_DISTANCE),
408 DECL(AL_ROLLOFF_FACTOR),
409 DECL(AL_CONE_OUTER_GAIN),
410 DECL(AL_MAX_DISTANCE),
411 DECL(AL_SEC_OFFSET),
412 DECL(AL_SAMPLE_OFFSET),
413 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
414 DECL(AL_BYTE_OFFSET),
415 DECL(AL_BYTE_RW_OFFSETS_SOFT),
416 DECL(AL_SOURCE_TYPE),
417 DECL(AL_STATIC),
418 DECL(AL_STREAMING),
419 DECL(AL_UNDETERMINED),
420 DECL(AL_METERS_PER_UNIT),
421 DECL(AL_DIRECT_CHANNELS_SOFT),
423 DECL(AL_DIRECT_FILTER),
424 DECL(AL_AUXILIARY_SEND_FILTER),
425 DECL(AL_AIR_ABSORPTION_FACTOR),
426 DECL(AL_ROOM_ROLLOFF_FACTOR),
427 DECL(AL_CONE_OUTER_GAINHF),
428 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
429 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
430 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
432 DECL(AL_SOURCE_STATE),
433 DECL(AL_INITIAL),
434 DECL(AL_PLAYING),
435 DECL(AL_PAUSED),
436 DECL(AL_STOPPED),
438 DECL(AL_BUFFERS_QUEUED),
439 DECL(AL_BUFFERS_PROCESSED),
441 DECL(AL_FORMAT_MONO8),
442 DECL(AL_FORMAT_MONO16),
443 DECL(AL_FORMAT_MONO_FLOAT32),
444 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
445 DECL(AL_FORMAT_STEREO8),
446 DECL(AL_FORMAT_STEREO16),
447 DECL(AL_FORMAT_STEREO_FLOAT32),
448 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
449 DECL(AL_FORMAT_MONO_IMA4),
450 DECL(AL_FORMAT_STEREO_IMA4),
451 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
452 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
453 DECL(AL_FORMAT_QUAD8_LOKI),
454 DECL(AL_FORMAT_QUAD16_LOKI),
455 DECL(AL_FORMAT_QUAD8),
456 DECL(AL_FORMAT_QUAD16),
457 DECL(AL_FORMAT_QUAD32),
458 DECL(AL_FORMAT_51CHN8),
459 DECL(AL_FORMAT_51CHN16),
460 DECL(AL_FORMAT_51CHN32),
461 DECL(AL_FORMAT_61CHN8),
462 DECL(AL_FORMAT_61CHN16),
463 DECL(AL_FORMAT_61CHN32),
464 DECL(AL_FORMAT_71CHN8),
465 DECL(AL_FORMAT_71CHN16),
466 DECL(AL_FORMAT_71CHN32),
467 DECL(AL_FORMAT_REAR8),
468 DECL(AL_FORMAT_REAR16),
469 DECL(AL_FORMAT_REAR32),
470 DECL(AL_FORMAT_MONO_MULAW),
471 DECL(AL_FORMAT_MONO_MULAW_EXT),
472 DECL(AL_FORMAT_STEREO_MULAW),
473 DECL(AL_FORMAT_STEREO_MULAW_EXT),
474 DECL(AL_FORMAT_QUAD_MULAW),
475 DECL(AL_FORMAT_51CHN_MULAW),
476 DECL(AL_FORMAT_61CHN_MULAW),
477 DECL(AL_FORMAT_71CHN_MULAW),
478 DECL(AL_FORMAT_REAR_MULAW),
479 DECL(AL_FORMAT_MONO_ALAW_EXT),
480 DECL(AL_FORMAT_STEREO_ALAW_EXT),
482 DECL(AL_MONO8_SOFT),
483 DECL(AL_MONO16_SOFT),
484 DECL(AL_MONO32F_SOFT),
485 DECL(AL_STEREO8_SOFT),
486 DECL(AL_STEREO16_SOFT),
487 DECL(AL_STEREO32F_SOFT),
488 DECL(AL_QUAD8_SOFT),
489 DECL(AL_QUAD16_SOFT),
490 DECL(AL_QUAD32F_SOFT),
491 DECL(AL_REAR8_SOFT),
492 DECL(AL_REAR16_SOFT),
493 DECL(AL_REAR32F_SOFT),
494 DECL(AL_5POINT1_8_SOFT),
495 DECL(AL_5POINT1_16_SOFT),
496 DECL(AL_5POINT1_32F_SOFT),
497 DECL(AL_6POINT1_8_SOFT),
498 DECL(AL_6POINT1_16_SOFT),
499 DECL(AL_6POINT1_32F_SOFT),
500 DECL(AL_7POINT1_8_SOFT),
501 DECL(AL_7POINT1_16_SOFT),
502 DECL(AL_7POINT1_32F_SOFT),
503 DECL(AL_FORMAT_BFORMAT2D_8),
504 DECL(AL_FORMAT_BFORMAT2D_16),
505 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
506 DECL(AL_FORMAT_BFORMAT2D_MULAW),
507 DECL(AL_FORMAT_BFORMAT3D_8),
508 DECL(AL_FORMAT_BFORMAT3D_16),
509 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
510 DECL(AL_FORMAT_BFORMAT3D_MULAW),
512 DECL(AL_MONO_SOFT),
513 DECL(AL_STEREO_SOFT),
514 DECL(AL_QUAD_SOFT),
515 DECL(AL_REAR_SOFT),
516 DECL(AL_5POINT1_SOFT),
517 DECL(AL_6POINT1_SOFT),
518 DECL(AL_7POINT1_SOFT),
520 DECL(AL_BYTE_SOFT),
521 DECL(AL_UNSIGNED_BYTE_SOFT),
522 DECL(AL_SHORT_SOFT),
523 DECL(AL_UNSIGNED_SHORT_SOFT),
524 DECL(AL_INT_SOFT),
525 DECL(AL_UNSIGNED_INT_SOFT),
526 DECL(AL_FLOAT_SOFT),
527 DECL(AL_DOUBLE_SOFT),
528 DECL(AL_BYTE3_SOFT),
529 DECL(AL_UNSIGNED_BYTE3_SOFT),
531 DECL(AL_FREQUENCY),
532 DECL(AL_BITS),
533 DECL(AL_CHANNELS),
534 DECL(AL_SIZE),
535 DECL(AL_INTERNAL_FORMAT_SOFT),
536 DECL(AL_BYTE_LENGTH_SOFT),
537 DECL(AL_SAMPLE_LENGTH_SOFT),
538 DECL(AL_SEC_LENGTH_SOFT),
539 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
540 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
542 DECL(AL_UNUSED),
543 DECL(AL_PENDING),
544 DECL(AL_PROCESSED),
546 DECL(AL_NO_ERROR),
547 DECL(AL_INVALID_NAME),
548 DECL(AL_INVALID_ENUM),
549 DECL(AL_INVALID_VALUE),
550 DECL(AL_INVALID_OPERATION),
551 DECL(AL_OUT_OF_MEMORY),
553 DECL(AL_VENDOR),
554 DECL(AL_VERSION),
555 DECL(AL_RENDERER),
556 DECL(AL_EXTENSIONS),
558 DECL(AL_DOPPLER_FACTOR),
559 DECL(AL_DOPPLER_VELOCITY),
560 DECL(AL_DISTANCE_MODEL),
561 DECL(AL_SPEED_OF_SOUND),
562 DECL(AL_SOURCE_DISTANCE_MODEL),
563 DECL(AL_DEFERRED_UPDATES_SOFT),
565 DECL(AL_INVERSE_DISTANCE),
566 DECL(AL_INVERSE_DISTANCE_CLAMPED),
567 DECL(AL_LINEAR_DISTANCE),
568 DECL(AL_LINEAR_DISTANCE_CLAMPED),
569 DECL(AL_EXPONENT_DISTANCE),
570 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
572 DECL(AL_FILTER_TYPE),
573 DECL(AL_FILTER_NULL),
574 DECL(AL_FILTER_LOWPASS),
575 DECL(AL_FILTER_HIGHPASS),
576 DECL(AL_FILTER_BANDPASS),
578 DECL(AL_LOWPASS_GAIN),
579 DECL(AL_LOWPASS_GAINHF),
581 DECL(AL_HIGHPASS_GAIN),
582 DECL(AL_HIGHPASS_GAINLF),
584 DECL(AL_BANDPASS_GAIN),
585 DECL(AL_BANDPASS_GAINHF),
586 DECL(AL_BANDPASS_GAINLF),
588 DECL(AL_EFFECT_TYPE),
589 DECL(AL_EFFECT_NULL),
590 DECL(AL_EFFECT_REVERB),
591 DECL(AL_EFFECT_EAXREVERB),
592 DECL(AL_EFFECT_CHORUS),
593 DECL(AL_EFFECT_DISTORTION),
594 DECL(AL_EFFECT_ECHO),
595 DECL(AL_EFFECT_FLANGER),
596 #if 0
597 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
598 DECL(AL_EFFECT_VOCAL_MORPHER),
599 DECL(AL_EFFECT_PITCH_SHIFTER),
600 #endif
601 DECL(AL_EFFECT_RING_MODULATOR),
602 #if 0
603 DECL(AL_EFFECT_AUTOWAH),
604 #endif
605 DECL(AL_EFFECT_COMPRESSOR),
606 DECL(AL_EFFECT_EQUALIZER),
607 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
608 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
610 DECL(AL_EAXREVERB_DENSITY),
611 DECL(AL_EAXREVERB_DIFFUSION),
612 DECL(AL_EAXREVERB_GAIN),
613 DECL(AL_EAXREVERB_GAINHF),
614 DECL(AL_EAXREVERB_GAINLF),
615 DECL(AL_EAXREVERB_DECAY_TIME),
616 DECL(AL_EAXREVERB_DECAY_HFRATIO),
617 DECL(AL_EAXREVERB_DECAY_LFRATIO),
618 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
619 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
620 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
621 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
622 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
623 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
624 DECL(AL_EAXREVERB_ECHO_TIME),
625 DECL(AL_EAXREVERB_ECHO_DEPTH),
626 DECL(AL_EAXREVERB_MODULATION_TIME),
627 DECL(AL_EAXREVERB_MODULATION_DEPTH),
628 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
629 DECL(AL_EAXREVERB_HFREFERENCE),
630 DECL(AL_EAXREVERB_LFREFERENCE),
631 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
632 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
634 DECL(AL_REVERB_DENSITY),
635 DECL(AL_REVERB_DIFFUSION),
636 DECL(AL_REVERB_GAIN),
637 DECL(AL_REVERB_GAINHF),
638 DECL(AL_REVERB_DECAY_TIME),
639 DECL(AL_REVERB_DECAY_HFRATIO),
640 DECL(AL_REVERB_REFLECTIONS_GAIN),
641 DECL(AL_REVERB_REFLECTIONS_DELAY),
642 DECL(AL_REVERB_LATE_REVERB_GAIN),
643 DECL(AL_REVERB_LATE_REVERB_DELAY),
644 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
645 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
646 DECL(AL_REVERB_DECAY_HFLIMIT),
648 DECL(AL_CHORUS_WAVEFORM),
649 DECL(AL_CHORUS_PHASE),
650 DECL(AL_CHORUS_RATE),
651 DECL(AL_CHORUS_DEPTH),
652 DECL(AL_CHORUS_FEEDBACK),
653 DECL(AL_CHORUS_DELAY),
655 DECL(AL_DISTORTION_EDGE),
656 DECL(AL_DISTORTION_GAIN),
657 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
658 DECL(AL_DISTORTION_EQCENTER),
659 DECL(AL_DISTORTION_EQBANDWIDTH),
661 DECL(AL_ECHO_DELAY),
662 DECL(AL_ECHO_LRDELAY),
663 DECL(AL_ECHO_DAMPING),
664 DECL(AL_ECHO_FEEDBACK),
665 DECL(AL_ECHO_SPREAD),
667 DECL(AL_FLANGER_WAVEFORM),
668 DECL(AL_FLANGER_PHASE),
669 DECL(AL_FLANGER_RATE),
670 DECL(AL_FLANGER_DEPTH),
671 DECL(AL_FLANGER_FEEDBACK),
672 DECL(AL_FLANGER_DELAY),
674 DECL(AL_RING_MODULATOR_FREQUENCY),
675 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
676 DECL(AL_RING_MODULATOR_WAVEFORM),
678 #if 0
679 DECL(AL_AUTOWAH_ATTACK_TIME),
680 DECL(AL_AUTOWAH_PEAK_GAIN),
681 DECL(AL_AUTOWAH_RELEASE_TIME),
682 DECL(AL_AUTOWAH_RESONANCE),
683 #endif
685 DECL(AL_COMPRESSOR_ONOFF),
687 DECL(AL_EQUALIZER_LOW_GAIN),
688 DECL(AL_EQUALIZER_LOW_CUTOFF),
689 DECL(AL_EQUALIZER_MID1_GAIN),
690 DECL(AL_EQUALIZER_MID1_CENTER),
691 DECL(AL_EQUALIZER_MID1_WIDTH),
692 DECL(AL_EQUALIZER_MID2_GAIN),
693 DECL(AL_EQUALIZER_MID2_CENTER),
694 DECL(AL_EQUALIZER_MID2_WIDTH),
695 DECL(AL_EQUALIZER_HIGH_GAIN),
696 DECL(AL_EQUALIZER_HIGH_CUTOFF),
698 DECL(AL_DEDICATED_GAIN),
700 { NULL, (ALCenum)0 }
702 #undef DECL
704 static const ALCchar alcNoError[] = "No Error";
705 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
706 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
707 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
708 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
709 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
712 /************************************************
713 * Global variables
714 ************************************************/
716 /* Enumerated device names */
717 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
719 static al_string alcAllDevicesList;
720 static al_string alcCaptureDeviceList;
722 /* Default is always the first in the list */
723 static ALCchar *alcDefaultAllDevicesSpecifier;
724 static ALCchar *alcCaptureDefaultDeviceSpecifier;
726 /* Default context extensions */
727 static const ALchar alExtList[] =
728 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
729 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
730 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
731 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
732 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
733 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
734 "AL_SOFT_source_latency AL_SOFT_source_length";
736 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
738 /* Thread-local current context */
739 static altss_t LocalContext;
740 /* Process-wide current context */
741 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
743 /* Mixing thread piority level */
744 ALint RTPrioLevel;
746 FILE *LogFile;
747 #ifdef _DEBUG
748 enum LogLevel LogLevel = LogWarning;
749 #else
750 enum LogLevel LogLevel = LogError;
751 #endif
753 /* Flag to trap ALC device errors */
754 static ALCboolean TrapALCError = ALC_FALSE;
756 /* One-time configuration init control */
757 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
759 /* Default effect that applies to sources that don't have an effect on send 0 */
760 static ALeffect DefaultEffect;
762 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
763 * updates.
765 static ALCboolean SuspendDefers = ALC_TRUE;
768 /************************************************
769 * ALC information
770 ************************************************/
771 static const ALCchar alcNoDeviceExtList[] =
772 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
773 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
774 static const ALCchar alcExtensionList[] =
775 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
776 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
777 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
778 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
779 static const ALCint alcMajorVersion = 1;
780 static const ALCint alcMinorVersion = 1;
782 static const ALCint alcEFXMajorVersion = 1;
783 static const ALCint alcEFXMinorVersion = 0;
786 /************************************************
787 * Device lists
788 ************************************************/
789 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
791 static almtx_t ListLock;
792 static inline void LockLists(void)
794 int lockret = almtx_lock(&ListLock);
795 assert(lockret == althrd_success);
797 static inline void UnlockLists(void)
799 int unlockret = almtx_unlock(&ListLock);
800 assert(unlockret == althrd_success);
803 /************************************************
804 * Library initialization
805 ************************************************/
806 #if defined(_WIN32)
807 static void alc_init(void);
808 static void alc_deinit(void);
809 static void alc_deinit_safe(void);
811 #ifndef AL_LIBTYPE_STATIC
812 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
814 switch(reason)
816 case DLL_PROCESS_ATTACH:
817 /* Pin the DLL so we won't get unloaded until the process terminates */
818 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
819 (WCHAR*)hModule, &hModule);
820 alc_init();
821 break;
823 case DLL_THREAD_DETACH:
824 break;
826 case DLL_PROCESS_DETACH:
827 if(!lpReserved)
828 alc_deinit();
829 else
830 alc_deinit_safe();
831 break;
833 return TRUE;
835 #elif defined(_MSC_VER)
836 #pragma section(".CRT$XCU",read)
837 static void alc_constructor(void);
838 static void alc_destructor(void);
839 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
841 static void alc_constructor(void)
843 atexit(alc_destructor);
844 alc_init();
847 static void alc_destructor(void)
849 alc_deinit();
851 #elif defined(HAVE_GCC_DESTRUCTOR)
852 static void alc_init(void) __attribute__((constructor));
853 static void alc_deinit(void) __attribute__((destructor));
854 #else
855 #error "No static initialization available on this platform!"
856 #endif
858 #elif defined(HAVE_GCC_DESTRUCTOR)
860 static void alc_init(void) __attribute__((constructor));
861 static void alc_deinit(void) __attribute__((destructor));
863 #else
864 #error "No global initialization available on this platform!"
865 #endif
867 static void ReleaseThreadCtx(void *ptr);
868 static void alc_init(void)
870 const char *str;
871 int ret;
873 LogFile = stderr;
875 AL_STRING_INIT(alcAllDevicesList);
876 AL_STRING_INIT(alcCaptureDeviceList);
878 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
879 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
880 ConeScale *= 0.5f;
882 str = getenv("__ALSOFT_REVERSE_Z");
883 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
884 ZScale *= -1.0f;
886 ret = altss_create(&LocalContext, ReleaseThreadCtx);
887 assert(ret == althrd_success);
889 ret = almtx_init(&ListLock, almtx_recursive);
890 assert(ret == althrd_success);
892 ThunkInit();
895 static void alc_initconfig(void)
897 const char *devs, *str;
898 ALuint capfilter;
899 float valf;
900 int i, n;
902 str = getenv("ALSOFT_LOGLEVEL");
903 if(str)
905 long lvl = strtol(str, NULL, 0);
906 if(lvl >= NoLog && lvl <= LogRef)
907 LogLevel = lvl;
910 str = getenv("ALSOFT_LOGFILE");
911 if(str && str[0])
913 FILE *logfile = al_fopen(str, "wt");
914 if(logfile) LogFile = logfile;
915 else ERR("Failed to open log file '%s'\n", str);
919 char buf[1024] = "";
920 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
921 for(i = 1;BackendList[i].name;i++)
922 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
923 TRACE("Supported backends: %s\n", buf);
925 ReadALConfig();
927 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
928 if(str && *str)
930 if(strcasecmp(str, "ignore") == 0)
932 SuspendDefers = ALC_FALSE;
933 TRACE("Selected context suspend behavior, \"ignore\"\n");
935 else
936 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
939 capfilter = 0;
940 #if defined(HAVE_SSE4_1)
941 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE4_1;
942 #elif defined(HAVE_SSE2)
943 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
944 #elif defined(HAVE_SSE)
945 capfilter |= CPU_CAP_SSE;
946 #endif
947 #ifdef HAVE_NEON
948 capfilter |= CPU_CAP_NEON;
949 #endif
950 if(ConfigValueStr(NULL, "disable-cpu-exts", &str))
952 if(strcasecmp(str, "all") == 0)
953 capfilter = 0;
954 else
956 size_t len;
957 const char *next = str;
959 do {
960 str = next;
961 while(isspace(str[0]))
962 str++;
963 next = strchr(str, ',');
965 if(!str[0] || str[0] == ',')
966 continue;
968 len = (next ? ((size_t)(next-str)) : strlen(str));
969 while(len > 0 && isspace(str[len-1]))
970 len--;
971 if(len == 3 && strncasecmp(str, "sse", len) == 0)
972 capfilter &= ~CPU_CAP_SSE;
973 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
974 capfilter &= ~CPU_CAP_SSE2;
975 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
976 capfilter &= ~CPU_CAP_SSE4_1;
977 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
978 capfilter &= ~CPU_CAP_NEON;
979 else
980 WARN("Invalid CPU extension \"%s\"\n", str);
981 } while(next++);
984 FillCPUCaps(capfilter);
986 #ifdef _WIN32
987 RTPrioLevel = 1;
988 #else
989 RTPrioLevel = 0;
990 #endif
991 ConfigValueInt(NULL, "rt-prio", &RTPrioLevel);
993 if(ConfigValueStr(NULL, "resampler", &str))
995 if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
996 DefaultResampler = PointResampler;
997 else if(strcasecmp(str, "linear") == 0)
998 DefaultResampler = LinearResampler;
999 else if(strcasecmp(str, "cubic") == 0)
1000 DefaultResampler = CubicResampler;
1001 else
1003 char *end;
1005 n = strtol(str, &end, 0);
1006 if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == CubicResampler))
1007 DefaultResampler = n;
1008 else
1009 WARN("Invalid resampler: %s\n", str);
1012 aluInitResamplers();
1014 str = getenv("ALSOFT_TRAP_ERROR");
1015 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1017 TrapALError = AL_TRUE;
1018 TrapALCError = AL_TRUE;
1020 else
1022 str = getenv("ALSOFT_TRAP_AL_ERROR");
1023 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1024 TrapALError = AL_TRUE;
1025 TrapALError = GetConfigValueBool(NULL, "trap-al-error", TrapALError);
1027 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1028 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1029 TrapALCError = ALC_TRUE;
1030 TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", TrapALCError);
1033 if(ConfigValueFloat("reverb", "boost", &valf))
1034 ReverbBoost *= powf(10.0f, valf / 20.0f);
1036 EmulateEAXReverb = GetConfigValueBool("reverb", "emulate-eax", AL_FALSE);
1038 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1039 ConfigValueStr(NULL, "drivers", &devs))
1041 int n;
1042 size_t len;
1043 const char *next = devs;
1044 int endlist, delitem;
1046 i = 0;
1047 do {
1048 devs = next;
1049 while(isspace(devs[0]))
1050 devs++;
1051 next = strchr(devs, ',');
1053 delitem = (devs[0] == '-');
1054 if(devs[0] == '-') devs++;
1056 if(!devs[0] || devs[0] == ',')
1058 endlist = 0;
1059 continue;
1061 endlist = 1;
1063 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1064 while(len > 0 && isspace(devs[len-1]))
1065 len--;
1066 for(n = i;BackendList[n].name;n++)
1068 if(len == strlen(BackendList[n].name) &&
1069 strncmp(BackendList[n].name, devs, len) == 0)
1071 if(delitem)
1073 do {
1074 BackendList[n] = BackendList[n+1];
1075 ++n;
1076 } while(BackendList[n].name);
1078 else
1080 struct BackendInfo Bkp = BackendList[n];
1081 while(n > i)
1083 BackendList[n] = BackendList[n-1];
1084 --n;
1086 BackendList[n] = Bkp;
1088 i++;
1090 break;
1093 } while(next++);
1095 if(endlist)
1097 BackendList[i].name = NULL;
1098 BackendList[i].getFactory = NULL;
1099 BackendList[i].Init = NULL;
1100 BackendList[i].Deinit = NULL;
1101 BackendList[i].Probe = NULL;
1105 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1107 if(BackendList[i].getFactory)
1109 ALCbackendFactory *factory = BackendList[i].getFactory();
1110 if(!V0(factory,init)())
1112 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1113 continue;
1116 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1117 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1119 PlaybackBackend = BackendList[i];
1120 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1122 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1124 CaptureBackend = BackendList[i];
1125 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1128 continue;
1131 if(!BackendList[i].Init(&BackendList[i].Funcs))
1133 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1134 continue;
1137 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1138 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1140 PlaybackBackend = BackendList[i];
1141 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1143 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1145 CaptureBackend = BackendList[i];
1146 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1150 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1151 V0(factory,init)();
1154 if(ConfigValueStr(NULL, "excludefx", &str))
1156 size_t len;
1157 const char *next = str;
1159 do {
1160 str = next;
1161 next = strchr(str, ',');
1163 if(!str[0] || next == str)
1164 continue;
1166 len = (next ? ((size_t)(next-str)) : strlen(str));
1167 for(n = 0;EffectList[n].name;n++)
1169 if(len == strlen(EffectList[n].name) &&
1170 strncmp(EffectList[n].name, str, len) == 0)
1171 DisabledEffects[EffectList[n].type] = AL_TRUE;
1173 } while(next++);
1176 InitEffectFactoryMap();
1178 InitEffect(&DefaultEffect);
1179 str = getenv("ALSOFT_DEFAULT_REVERB");
1180 if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str))
1181 LoadReverbPreset(str, &DefaultEffect);
1183 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1186 /************************************************
1187 * Library deinitialization
1188 ************************************************/
1189 static void alc_cleanup(void)
1191 ALCdevice *dev;
1193 AL_STRING_DEINIT(alcAllDevicesList);
1194 AL_STRING_DEINIT(alcCaptureDeviceList);
1196 free(alcDefaultAllDevicesSpecifier);
1197 alcDefaultAllDevicesSpecifier = NULL;
1198 free(alcCaptureDefaultDeviceSpecifier);
1199 alcCaptureDefaultDeviceSpecifier = NULL;
1201 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1203 ALCuint num = 0;
1204 do {
1205 num++;
1206 } while((dev=dev->next) != NULL);
1207 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1210 DeinitEffectFactoryMap();
1213 static void alc_deinit_safe(void)
1215 alc_cleanup();
1217 FreeHrtfs();
1218 FreeALConfig();
1220 ThunkExit();
1221 almtx_destroy(&ListLock);
1222 altss_delete(LocalContext);
1224 if(LogFile != stderr)
1225 fclose(LogFile);
1226 LogFile = NULL;
1229 static void alc_deinit(void)
1231 int i;
1233 alc_cleanup();
1235 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1236 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1238 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1240 if(!BackendList[i].getFactory)
1241 BackendList[i].Deinit();
1242 else
1244 ALCbackendFactory *factory = BackendList[i].getFactory();
1245 V0(factory,deinit)();
1249 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1250 V0(factory,deinit)();
1253 alc_deinit_safe();
1257 /************************************************
1258 * Device enumeration
1259 ************************************************/
1260 static void ProbeDevices(al_string *list, enum DevProbe type)
1262 DO_INITCONFIG();
1264 LockLists();
1265 al_string_clear(list);
1267 if(type == ALL_DEVICE_PROBE && (PlaybackBackend.Probe || PlaybackBackend.getFactory))
1269 if(!PlaybackBackend.getFactory)
1270 PlaybackBackend.Probe(type);
1271 else
1273 ALCbackendFactory *factory = PlaybackBackend.getFactory();
1274 V(factory,probe)(type);
1277 else if(type == CAPTURE_DEVICE_PROBE && (CaptureBackend.Probe || CaptureBackend.getFactory))
1279 if(!CaptureBackend.getFactory)
1280 CaptureBackend.Probe(type);
1281 else
1283 ALCbackendFactory *factory = CaptureBackend.getFactory();
1284 V(factory,probe)(type);
1287 UnlockLists();
1289 static void ProbeAllDevicesList(void)
1290 { ProbeDevices(&alcAllDevicesList, ALL_DEVICE_PROBE); }
1291 static void ProbeCaptureDeviceList(void)
1292 { ProbeDevices(&alcCaptureDeviceList, CAPTURE_DEVICE_PROBE); }
1294 static void AppendDevice(const ALCchar *name, al_string *devnames)
1296 size_t len = strlen(name);
1297 if(len > 0)
1298 al_string_append_range(devnames, name, name+len+1);
1300 void AppendAllDevicesList(const ALCchar *name)
1301 { AppendDevice(name, &alcAllDevicesList); }
1302 void AppendCaptureDeviceList(const ALCchar *name)
1303 { AppendDevice(name, &alcCaptureDeviceList); }
1306 /************************************************
1307 * Device format information
1308 ************************************************/
1309 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1311 switch(type)
1313 case DevFmtByte: return "Signed Byte";
1314 case DevFmtUByte: return "Unsigned Byte";
1315 case DevFmtShort: return "Signed Short";
1316 case DevFmtUShort: return "Unsigned Short";
1317 case DevFmtInt: return "Signed Int";
1318 case DevFmtUInt: return "Unsigned Int";
1319 case DevFmtFloat: return "Float";
1321 return "(unknown type)";
1323 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1325 switch(chans)
1327 case DevFmtMono: return "Mono";
1328 case DevFmtStereo: return "Stereo";
1329 case DevFmtQuad: return "Quadraphonic";
1330 case DevFmtX51: return "5.1 Surround";
1331 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1332 case DevFmtX61: return "6.1 Surround";
1333 case DevFmtX71: return "7.1 Surround";
1334 case DevFmtBFormat3D: return "B-Format 3D";
1336 return "(unknown channels)";
1339 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1340 ALuint BytesFromDevFmt(enum DevFmtType type)
1342 switch(type)
1344 case DevFmtByte: return sizeof(ALbyte);
1345 case DevFmtUByte: return sizeof(ALubyte);
1346 case DevFmtShort: return sizeof(ALshort);
1347 case DevFmtUShort: return sizeof(ALushort);
1348 case DevFmtInt: return sizeof(ALint);
1349 case DevFmtUInt: return sizeof(ALuint);
1350 case DevFmtFloat: return sizeof(ALfloat);
1352 return 0;
1354 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1356 switch(chans)
1358 case DevFmtMono: return 1;
1359 case DevFmtStereo: return 2;
1360 case DevFmtQuad: return 4;
1361 case DevFmtX51: return 6;
1362 case DevFmtX51Rear: return 6;
1363 case DevFmtX61: return 7;
1364 case DevFmtX71: return 8;
1365 case DevFmtBFormat3D: return 4;
1367 return 0;
1370 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1371 enum DevFmtChannels *chans, enum DevFmtType *type)
1373 static const struct {
1374 ALenum format;
1375 enum DevFmtChannels channels;
1376 enum DevFmtType type;
1377 } list[] = {
1378 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1379 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1380 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1382 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1383 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1384 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1386 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1387 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1388 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1390 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1391 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1392 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1394 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1395 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1396 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1398 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1399 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1400 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1402 ALuint i;
1404 for(i = 0;i < COUNTOF(list);i++)
1406 if(list[i].format == format)
1408 *chans = list[i].channels;
1409 *type = list[i].type;
1410 return AL_TRUE;
1414 return AL_FALSE;
1417 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1419 switch(type)
1421 case ALC_BYTE_SOFT:
1422 case ALC_UNSIGNED_BYTE_SOFT:
1423 case ALC_SHORT_SOFT:
1424 case ALC_UNSIGNED_SHORT_SOFT:
1425 case ALC_INT_SOFT:
1426 case ALC_UNSIGNED_INT_SOFT:
1427 case ALC_FLOAT_SOFT:
1428 return ALC_TRUE;
1430 return ALC_FALSE;
1433 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1435 switch(channels)
1437 case ALC_MONO_SOFT:
1438 case ALC_STEREO_SOFT:
1439 case ALC_QUAD_SOFT:
1440 case ALC_5POINT1_SOFT:
1441 case ALC_6POINT1_SOFT:
1442 case ALC_7POINT1_SOFT:
1443 return ALC_TRUE;
1445 return ALC_FALSE;
1449 /************************************************
1450 * Miscellaneous ALC helpers
1451 ************************************************/
1452 extern inline void LockContext(ALCcontext *context);
1453 extern inline void UnlockContext(ALCcontext *context);
1455 ALint64 ALCdevice_GetLatency(ALCdevice *device)
1457 return V0(device->Backend,getLatency)();
1460 void ALCdevice_Lock(ALCdevice *device)
1462 V0(device->Backend,lock)();
1465 void ALCdevice_Unlock(ALCdevice *device)
1467 V0(device->Backend,unlock)();
1471 /* SetDefaultWFXChannelOrder
1473 * Sets the default channel order used by WaveFormatEx.
1475 void SetDefaultWFXChannelOrder(ALCdevice *device)
1477 ALuint i;
1479 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1480 device->ChannelName[i] = InvalidChannel;
1482 switch(device->FmtChans)
1484 case DevFmtMono:
1485 device->ChannelName[0] = FrontCenter;
1486 break;
1487 case DevFmtStereo:
1488 device->ChannelName[0] = FrontLeft;
1489 device->ChannelName[1] = FrontRight;
1490 break;
1491 case DevFmtQuad:
1492 device->ChannelName[0] = FrontLeft;
1493 device->ChannelName[1] = FrontRight;
1494 device->ChannelName[2] = BackLeft;
1495 device->ChannelName[3] = BackRight;
1496 break;
1497 case DevFmtX51:
1498 device->ChannelName[0] = FrontLeft;
1499 device->ChannelName[1] = FrontRight;
1500 device->ChannelName[2] = FrontCenter;
1501 device->ChannelName[3] = LFE;
1502 device->ChannelName[4] = SideLeft;
1503 device->ChannelName[5] = SideRight;
1504 break;
1505 case DevFmtX51Rear:
1506 device->ChannelName[0] = FrontLeft;
1507 device->ChannelName[1] = FrontRight;
1508 device->ChannelName[2] = FrontCenter;
1509 device->ChannelName[3] = LFE;
1510 device->ChannelName[4] = BackLeft;
1511 device->ChannelName[5] = BackRight;
1512 break;
1513 case DevFmtX61:
1514 device->ChannelName[0] = FrontLeft;
1515 device->ChannelName[1] = FrontRight;
1516 device->ChannelName[2] = FrontCenter;
1517 device->ChannelName[3] = LFE;
1518 device->ChannelName[4] = BackCenter;
1519 device->ChannelName[5] = SideLeft;
1520 device->ChannelName[6] = SideRight;
1521 break;
1522 case DevFmtX71:
1523 device->ChannelName[0] = FrontLeft;
1524 device->ChannelName[1] = FrontRight;
1525 device->ChannelName[2] = FrontCenter;
1526 device->ChannelName[3] = LFE;
1527 device->ChannelName[4] = BackLeft;
1528 device->ChannelName[5] = BackRight;
1529 device->ChannelName[6] = SideLeft;
1530 device->ChannelName[7] = SideRight;
1531 break;
1532 case DevFmtBFormat3D:
1533 device->ChannelName[0] = Aux0;
1534 device->ChannelName[1] = Aux1;
1535 device->ChannelName[2] = Aux2;
1536 device->ChannelName[3] = Aux3;
1537 break;
1541 /* SetDefaultChannelOrder
1543 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1545 void SetDefaultChannelOrder(ALCdevice *device)
1547 ALuint i;
1549 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1550 device->ChannelName[i] = InvalidChannel;
1552 switch(device->FmtChans)
1554 case DevFmtX51Rear:
1555 device->ChannelName[0] = FrontLeft;
1556 device->ChannelName[1] = FrontRight;
1557 device->ChannelName[2] = BackLeft;
1558 device->ChannelName[3] = BackRight;
1559 device->ChannelName[4] = FrontCenter;
1560 device->ChannelName[5] = LFE;
1561 return;
1562 case DevFmtX71:
1563 device->ChannelName[0] = FrontLeft;
1564 device->ChannelName[1] = FrontRight;
1565 device->ChannelName[2] = BackLeft;
1566 device->ChannelName[3] = BackRight;
1567 device->ChannelName[4] = FrontCenter;
1568 device->ChannelName[5] = LFE;
1569 device->ChannelName[6] = SideLeft;
1570 device->ChannelName[7] = SideRight;
1571 return;
1573 /* Same as WFX order */
1574 case DevFmtMono:
1575 case DevFmtStereo:
1576 case DevFmtQuad:
1577 case DevFmtX51:
1578 case DevFmtX61:
1579 case DevFmtBFormat3D:
1580 SetDefaultWFXChannelOrder(device);
1581 break;
1585 extern inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan);
1588 /* ALCcontext_DeferUpdates
1590 * Defers/suspends updates for the given context's listener and sources. This
1591 * does *NOT* stop mixing, but rather prevents certain property changes from
1592 * taking effect.
1594 void ALCcontext_DeferUpdates(ALCcontext *context)
1596 ALCdevice *device = context->Device;
1597 FPUCtl oldMode;
1599 SetMixerFPUMode(&oldMode);
1601 V0(device->Backend,lock)();
1602 if(!context->DeferUpdates)
1604 ALboolean UpdateSources;
1605 ALvoice *voice, *voice_end;
1606 ALeffectslot **slot, **slot_end;
1608 context->DeferUpdates = AL_TRUE;
1610 /* Make sure all pending updates are performed */
1611 UpdateSources = ATOMIC_EXCHANGE(ALenum, &context->UpdateSources, AL_FALSE);
1613 voice = context->Voices;
1614 voice_end = voice + context->VoiceCount;
1615 while(voice != voice_end)
1617 ALsource *source = voice->Source;
1618 if(!source) goto next;
1620 if(source->state != AL_PLAYING && source->state != AL_PAUSED)
1622 voice->Source = NULL;
1623 goto next;
1626 if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || UpdateSources)
1627 voice->Update(voice, source, context);
1628 next:
1629 voice++;
1632 slot = VECTOR_ITER_BEGIN(context->ActiveAuxSlots);
1633 slot_end = VECTOR_ITER_END(context->ActiveAuxSlots);
1634 while(slot != slot_end)
1636 if(ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE))
1637 V((*slot)->EffectState,update)(context->Device, *slot);
1638 slot++;
1641 V0(device->Backend,unlock)();
1643 RestoreFPUMode(&oldMode);
1646 /* ALCcontext_ProcessUpdates
1648 * Resumes update processing after being deferred.
1650 void ALCcontext_ProcessUpdates(ALCcontext *context)
1652 ALCdevice *device = context->Device;
1654 V0(device->Backend,lock)();
1655 if(context->DeferUpdates)
1657 ALsizei pos;
1659 context->DeferUpdates = AL_FALSE;
1661 LockUIntMapRead(&context->SourceMap);
1662 for(pos = 0;pos < context->SourceMap.size;pos++)
1664 ALsource *Source = context->SourceMap.array[pos].value;
1665 ALenum new_state;
1667 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1668 Source->Offset >= 0.0)
1670 ReadLock(&Source->queue_lock);
1671 ApplyOffset(Source);
1672 ReadUnlock(&Source->queue_lock);
1675 new_state = Source->new_state;
1676 Source->new_state = AL_NONE;
1677 if(new_state)
1678 SetSourceState(Source, context, new_state);
1680 UnlockUIntMapRead(&context->SourceMap);
1682 V0(device->Backend,unlock)();
1686 /* alcSetError
1688 * Stores the latest ALC device error
1690 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1692 if(TrapALCError)
1694 #ifdef _WIN32
1695 /* DebugBreak() will cause an exception if there is no debugger */
1696 if(IsDebuggerPresent())
1697 DebugBreak();
1698 #elif defined(SIGTRAP)
1699 raise(SIGTRAP);
1700 #endif
1703 if(device)
1704 ATOMIC_STORE(&device->LastError, errorCode);
1705 else
1706 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1710 /* UpdateClockBase
1712 * Updates the device's base clock time with however many samples have been
1713 * done. This is used so frequency changes on the device don't cause the time
1714 * to jump forward or back.
1716 static inline void UpdateClockBase(ALCdevice *device)
1718 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1719 device->SamplesDone = 0;
1722 /* UpdateDeviceParams
1724 * Updates device parameters according to the attribute list (caller is
1725 * responsible for holding the list lock).
1727 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1729 ALCcontext *context;
1730 enum DevFmtChannels oldChans;
1731 enum DevFmtType oldType;
1732 ALCuint oldFreq;
1733 FPUCtl oldMode;
1734 size_t size;
1736 // Check for attributes
1737 if(device->Type == Loopback)
1739 enum {
1740 GotFreq = 1<<0,
1741 GotChans = 1<<1,
1742 GotType = 1<<2,
1743 GotAll = GotFreq|GotChans|GotType
1745 ALCuint freq, numMono, numStereo, numSends, flags;
1746 enum DevFmtChannels schans;
1747 enum DevFmtType stype;
1748 ALCuint attrIdx = 0;
1749 ALCint gotFmt = 0;
1751 if(!attrList)
1753 WARN("Missing attributes for loopback device\n");
1754 return ALC_INVALID_VALUE;
1757 numMono = device->NumMonoSources;
1758 numStereo = device->NumStereoSources;
1759 numSends = device->NumAuxSends;
1760 schans = device->FmtChans;
1761 stype = device->FmtType;
1762 freq = device->Frequency;
1763 flags = device->Flags;
1765 while(attrList[attrIdx])
1767 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1769 ALCint val = attrList[attrIdx + 1];
1770 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1771 return ALC_INVALID_VALUE;
1772 schans = val;
1773 gotFmt |= GotChans;
1776 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1778 ALCint val = attrList[attrIdx + 1];
1779 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1780 return ALC_INVALID_VALUE;
1781 stype = val;
1782 gotFmt |= GotType;
1785 if(attrList[attrIdx] == ALC_FREQUENCY)
1787 freq = attrList[attrIdx + 1];
1788 if(freq < MIN_OUTPUT_RATE)
1789 return ALC_INVALID_VALUE;
1790 gotFmt |= GotFreq;
1793 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1795 numStereo = attrList[attrIdx + 1];
1796 if(numStereo > device->MaxNoOfSources)
1797 numStereo = device->MaxNoOfSources;
1799 numMono = device->MaxNoOfSources - numStereo;
1802 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1803 numSends = attrList[attrIdx + 1];
1805 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1807 if(attrList[attrIdx + 1] != ALC_FALSE)
1808 flags |= DEVICE_HRTF_REQUEST;
1809 else
1810 flags &= ~DEVICE_HRTF_REQUEST;
1813 attrIdx += 2;
1816 if(gotFmt != GotAll)
1818 WARN("Missing format for loopback device\n");
1819 return ALC_INVALID_VALUE;
1822 ConfigValueUInt(NULL, "sends", &numSends);
1823 numSends = minu(MAX_SENDS, numSends);
1825 if((device->Flags&DEVICE_RUNNING))
1826 V0(device->Backend,stop)();
1827 device->Flags = (flags & ~DEVICE_RUNNING);
1829 UpdateClockBase(device);
1831 device->Frequency = freq;
1832 device->FmtChans = schans;
1833 device->FmtType = stype;
1834 device->NumMonoSources = numMono;
1835 device->NumStereoSources = numStereo;
1836 device->NumAuxSends = numSends;
1838 else if(attrList && attrList[0])
1840 ALCuint freq, numMono, numStereo, numSends;
1841 ALCuint attrIdx = 0;
1843 /* If a context is already running on the device, stop playback so the
1844 * device attributes can be updated. */
1845 if((device->Flags&DEVICE_RUNNING))
1846 V0(device->Backend,stop)();
1847 device->Flags &= ~DEVICE_RUNNING;
1849 freq = device->Frequency;
1850 numMono = device->NumMonoSources;
1851 numStereo = device->NumStereoSources;
1852 numSends = device->NumAuxSends;
1854 while(attrList[attrIdx])
1856 if(attrList[attrIdx] == ALC_FREQUENCY)
1858 freq = attrList[attrIdx + 1];
1859 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1862 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1864 numStereo = attrList[attrIdx + 1];
1865 if(numStereo > device->MaxNoOfSources)
1866 numStereo = device->MaxNoOfSources;
1868 numMono = device->MaxNoOfSources - numStereo;
1871 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1872 numSends = attrList[attrIdx + 1];
1874 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1876 if(attrList[attrIdx + 1] != ALC_FALSE)
1877 device->Flags |= DEVICE_HRTF_REQUEST;
1878 else
1879 device->Flags &= ~DEVICE_HRTF_REQUEST;
1882 attrIdx += 2;
1885 ConfigValueUInt(NULL, "frequency", &freq);
1886 freq = maxu(freq, MIN_OUTPUT_RATE);
1888 ConfigValueUInt(NULL, "sends", &numSends);
1889 numSends = minu(MAX_SENDS, numSends);
1891 UpdateClockBase(device);
1893 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1894 device->Frequency;
1895 /* SSE and Neon do best with the update size being a multiple of 4 */
1896 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1897 device->UpdateSize = (device->UpdateSize+3)&~3;
1899 device->Frequency = freq;
1900 device->NumMonoSources = numMono;
1901 device->NumStereoSources = numStereo;
1902 device->NumAuxSends = numSends;
1905 if((device->Flags&DEVICE_RUNNING))
1906 return ALC_NO_ERROR;
1908 al_free(device->DryBuffer);
1909 device->DryBuffer = NULL;
1911 UpdateClockBase(device);
1913 if(device->Type != Loopback && ((device->Flags&DEVICE_HRTF_REQUEST) || GetConfigValueBool(NULL, "hrtf", 0)))
1915 if(!FindHrtfFormat(&device->FmtChans, &device->Frequency))
1916 device->Flags &= ~DEVICE_HRTF_REQUEST;
1917 else
1918 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST |
1919 DEVICE_HRTF_REQUEST;
1921 if(device->Type == Loopback && (device->Flags&DEVICE_HRTF_REQUEST))
1923 enum DevFmtChannels chans = device->FmtChans;
1924 ALCuint freq = device->Frequency;
1925 if(!FindHrtfFormat(&chans, &freq) || chans != device->FmtChans || freq != device->Frequency)
1927 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1928 DevFmtChannelsString(device->FmtChans), device->Frequency);
1929 device->Flags &= ~DEVICE_HRTF_REQUEST;
1933 oldFreq = device->Frequency;
1934 oldChans = device->FmtChans;
1935 oldType = device->FmtType;
1937 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1938 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1939 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1940 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1941 device->UpdateSize, device->NumUpdates
1944 if(V0(device->Backend,reset)() == ALC_FALSE)
1945 return ALC_INVALID_DEVICE;
1947 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1949 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1950 DevFmtChannelsString(device->FmtChans));
1951 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1953 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1955 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1956 DevFmtTypeString(device->FmtType));
1957 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1959 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1961 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1962 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1965 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1966 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1967 device->Frequency, device->UpdateSize, device->NumUpdates
1970 if((device->UpdateSize&3) != 0)
1972 if((CPUCapFlags&CPU_CAP_SSE))
1973 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1974 if((CPUCapFlags&CPU_CAP_NEON))
1975 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1978 device->Hrtf = NULL;
1979 if(device->FmtChans != DevFmtStereo)
1981 free(device->Bs2b);
1982 device->Bs2b = NULL;
1984 else
1986 bool headphones = device->IsHeadphones;
1987 const char *mode;
1988 int bs2blevel;
1989 int usehrtf;
1991 if(device->Type != Loopback && ConfigValueStr(NULL, "stereo-mode", &mode))
1993 if(strcasecmp(mode, "headphones") == 0)
1994 headphones = true;
1995 else if(strcasecmp(mode, "speakers") == 0)
1996 headphones = false;
1997 else if(strcasecmp(mode, "auto") != 0)
1998 ERR("Unexpected stereo-mode: %s\n", mode);
2001 if(device->Type == Loopback || !ConfigValueBool(NULL, "hrtf", &usehrtf))
2002 usehrtf = ((device->Flags&DEVICE_HRTF_REQUEST) || headphones);
2004 if(usehrtf)
2005 device->Hrtf = GetHrtf(device->FmtChans, device->Frequency);
2006 if(device->Hrtf)
2008 TRACE("HRTF enabled\n");
2009 free(device->Bs2b);
2010 device->Bs2b = NULL;
2012 else
2014 device->Flags &= ~DEVICE_HRTF_REQUEST;
2015 TRACE("HRTF disabled\n");
2017 bs2blevel = (headphones ? 5 : 0);
2018 if(device->Type != Loopback)
2019 ConfigValueInt(NULL, "cf_level", &bs2blevel);
2020 if(bs2blevel > 0 && bs2blevel <= 6)
2022 if(!device->Bs2b)
2024 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
2025 bs2b_clear(device->Bs2b);
2027 bs2b_set_srate(device->Bs2b, device->Frequency);
2028 bs2b_set_level(device->Bs2b, bs2blevel);
2029 TRACE("BS2B enabled\n");
2031 else
2033 free(device->Bs2b);
2034 device->Bs2b = NULL;
2035 TRACE("BS2B disabled\n");
2040 aluInitPanning(device);
2042 /* With HRTF enabled, virtual channels are allocated for B-Format and
2043 * effects renfering. Two extra channels are allocated for the actual HRTF-
2044 * filtered output.
2046 size = sizeof(device->DryBuffer[0]) * (device->NumChannels + (device->Hrtf ? 2 : 0));
2047 device->DryBuffer = al_calloc(16, size);
2048 if(!device->DryBuffer)
2050 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2051 return ALC_INVALID_DEVICE;
2054 V(device->Synth,update)(device);
2056 SetMixerFPUMode(&oldMode);
2057 V0(device->Backend,lock)();
2058 context = ATOMIC_LOAD(&device->ContextList);
2059 while(context)
2061 ALsizei pos;
2063 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2064 LockUIntMapRead(&context->EffectSlotMap);
2065 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2067 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2069 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2071 UnlockUIntMapRead(&context->EffectSlotMap);
2072 V0(device->Backend,unlock)();
2073 RestoreFPUMode(&oldMode);
2074 return ALC_INVALID_DEVICE;
2076 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2077 V(slot->EffectState,update)(device, slot);
2079 UnlockUIntMapRead(&context->EffectSlotMap);
2081 LockUIntMapRead(&context->SourceMap);
2082 for(pos = 0;pos < context->SourceMap.size;pos++)
2084 ALsource *source = context->SourceMap.array[pos].value;
2085 ALuint s = device->NumAuxSends;
2086 while(s < MAX_SENDS)
2088 if(source->Send[s].Slot)
2089 DecrementRef(&source->Send[s].Slot->ref);
2090 source->Send[s].Slot = NULL;
2091 source->Send[s].Gain = 1.0f;
2092 source->Send[s].GainHF = 1.0f;
2093 s++;
2095 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2097 UnlockUIntMapRead(&context->SourceMap);
2099 for(pos = 0;pos < context->VoiceCount;pos++)
2101 ALvoice *voice = &context->Voices[pos];
2102 ALsource *source = voice->Source;
2103 ALuint s = device->NumAuxSends;
2105 while(s < MAX_SENDS)
2107 voice->Send[s].Moving = AL_FALSE;
2108 voice->Send[s].Counter = 0;
2109 s++;
2112 if(source)
2114 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2115 voice->Update(voice, source, context);
2119 context = context->next;
2121 if(device->DefaultSlot)
2123 ALeffectslot *slot = device->DefaultSlot;
2125 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2127 V0(device->Backend,unlock)();
2128 RestoreFPUMode(&oldMode);
2129 return ALC_INVALID_DEVICE;
2131 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2132 V(slot->EffectState,update)(device, slot);
2134 V0(device->Backend,unlock)();
2135 RestoreFPUMode(&oldMode);
2137 if(!(device->Flags&DEVICE_PAUSED))
2139 if(V0(device->Backend,start)() == ALC_FALSE)
2140 return ALC_INVALID_DEVICE;
2141 device->Flags |= DEVICE_RUNNING;
2144 return ALC_NO_ERROR;
2147 /* FreeDevice
2149 * Frees the device structure, and destroys any objects the app failed to
2150 * delete. Called once there's no more references on the device.
2152 static ALCvoid FreeDevice(ALCdevice *device)
2154 TRACE("%p\n", device);
2156 V0(device->Backend,close)();
2157 DELETE_OBJ(device->Backend);
2158 device->Backend = NULL;
2160 DELETE_OBJ(device->Synth);
2161 device->Synth = NULL;
2163 if(device->DefaultSlot)
2165 ALeffectState *state = device->DefaultSlot->EffectState;
2166 device->DefaultSlot = NULL;
2167 DELETE_OBJ(state);
2170 if(device->DefaultSfont)
2171 ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
2172 device->DefaultSfont = NULL;
2174 if(device->BufferMap.size > 0)
2176 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2177 ReleaseALBuffers(device);
2179 ResetUIntMap(&device->BufferMap);
2181 if(device->EffectMap.size > 0)
2183 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2184 ReleaseALEffects(device);
2186 ResetUIntMap(&device->EffectMap);
2188 if(device->FilterMap.size > 0)
2190 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2191 ReleaseALFilters(device);
2193 ResetUIntMap(&device->FilterMap);
2195 if(device->SfontMap.size > 0)
2197 WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size);
2198 ReleaseALSoundfonts(device);
2200 ResetUIntMap(&device->SfontMap);
2202 if(device->PresetMap.size > 0)
2204 WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size);
2205 ReleaseALPresets(device);
2207 ResetUIntMap(&device->PresetMap);
2209 if(device->FontsoundMap.size > 0)
2211 WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size);
2212 ReleaseALFontsounds(device);
2214 ResetUIntMap(&device->FontsoundMap);
2216 free(device->Bs2b);
2217 device->Bs2b = NULL;
2219 AL_STRING_DEINIT(device->DeviceName);
2221 al_free(device->DryBuffer);
2222 device->DryBuffer = NULL;
2224 al_free(device);
2228 void ALCdevice_IncRef(ALCdevice *device)
2230 uint ref;
2231 ref = IncrementRef(&device->ref);
2232 TRACEREF("%p increasing refcount to %u\n", device, ref);
2235 void ALCdevice_DecRef(ALCdevice *device)
2237 uint ref;
2238 ref = DecrementRef(&device->ref);
2239 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2240 if(ref == 0) FreeDevice(device);
2243 /* VerifyDevice
2245 * Checks if the device handle is valid, and increments its ref count if so.
2247 static ALCdevice *VerifyDevice(ALCdevice *device)
2249 ALCdevice *tmpDevice;
2251 if(!device)
2252 return NULL;
2254 LockLists();
2255 tmpDevice = ATOMIC_LOAD(&DeviceList);
2256 while(tmpDevice && tmpDevice != device)
2257 tmpDevice = tmpDevice->next;
2259 if(tmpDevice)
2260 ALCdevice_IncRef(tmpDevice);
2261 UnlockLists();
2262 return tmpDevice;
2266 /* InitContext
2268 * Initializes context fields
2270 static ALvoid InitContext(ALCcontext *Context)
2272 //Initialise listener
2273 Context->Listener->Gain = 1.0f;
2274 Context->Listener->MetersPerUnit = 1.0f;
2275 aluVectorSet(&Context->Listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2276 aluVectorSet(&Context->Listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2277 Context->Listener->Forward[0] = 0.0f;
2278 Context->Listener->Forward[1] = 0.0f;
2279 Context->Listener->Forward[2] = -1.0f;
2280 Context->Listener->Up[0] = 0.0f;
2281 Context->Listener->Up[1] = 1.0f;
2282 Context->Listener->Up[2] = 0.0f;
2283 aluMatrixSet(&Context->Listener->Params.Matrix,
2284 1.0f, 0.0f, 0.0f, 0.0f,
2285 0.0f, 1.0f, 0.0f, 0.0f,
2286 0.0f, 0.0f, 1.0f, 0.0f,
2287 0.0f, 0.0f, 0.0f, 1.0f
2289 aluVectorSet(&Context->Listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2291 //Validate Context
2292 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2293 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2294 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2295 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2297 //Set globals
2298 Context->DistanceModel = DefaultDistanceModel;
2299 Context->SourceDistanceModel = AL_FALSE;
2300 Context->DopplerFactor = 1.0f;
2301 Context->DopplerVelocity = 1.0f;
2302 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2303 Context->DeferUpdates = AL_FALSE;
2305 Context->ExtensionList = alExtList;
2309 /* FreeContext
2311 * Cleans up the context, and destroys any remaining objects the app failed to
2312 * delete. Called once there's no more references on the context.
2314 static void FreeContext(ALCcontext *context)
2316 TRACE("%p\n", context);
2318 if(context->SourceMap.size > 0)
2320 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2321 ReleaseALSources(context);
2323 ResetUIntMap(&context->SourceMap);
2325 if(context->EffectSlotMap.size > 0)
2327 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2328 ReleaseALAuxiliaryEffectSlots(context);
2330 ResetUIntMap(&context->EffectSlotMap);
2332 al_free(context->Voices);
2333 context->Voices = NULL;
2334 context->VoiceCount = 0;
2335 context->MaxVoices = 0;
2337 VECTOR_DEINIT(context->ActiveAuxSlots);
2339 ALCdevice_DecRef(context->Device);
2340 context->Device = NULL;
2342 //Invalidate context
2343 memset(context, 0, sizeof(ALCcontext));
2344 al_free(context);
2347 /* ReleaseContext
2349 * Removes the context reference from the given device and removes it from
2350 * being current on the running thread or globally.
2352 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2354 ALCcontext *nextctx;
2355 ALCcontext *origctx;
2357 if(altss_get(LocalContext) == context)
2359 WARN("%p released while current on thread\n", context);
2360 altss_set(LocalContext, NULL);
2361 ALCcontext_DecRef(context);
2364 origctx = context;
2365 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2366 ALCcontext_DecRef(context);
2368 ALCdevice_Lock(device);
2369 origctx = context;
2370 nextctx = context->next;
2371 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2373 ALCcontext *list;
2374 do {
2375 list = origctx;
2376 origctx = context;
2377 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2379 ALCdevice_Unlock(device);
2381 ALCcontext_DecRef(context);
2384 void ALCcontext_IncRef(ALCcontext *context)
2386 uint ref;
2387 ref = IncrementRef(&context->ref);
2388 TRACEREF("%p increasing refcount to %u\n", context, ref);
2391 void ALCcontext_DecRef(ALCcontext *context)
2393 uint ref;
2394 ref = DecrementRef(&context->ref);
2395 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2396 if(ref == 0) FreeContext(context);
2399 static void ReleaseThreadCtx(void *ptr)
2401 WARN("%p current for thread being destroyed\n", ptr);
2402 ALCcontext_DecRef(ptr);
2405 /* VerifyContext
2407 * Checks that the given context is valid, and increments its reference count.
2409 static ALCcontext *VerifyContext(ALCcontext *context)
2411 ALCdevice *dev;
2413 LockLists();
2414 dev = ATOMIC_LOAD(&DeviceList);
2415 while(dev)
2417 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2418 while(ctx)
2420 if(ctx == context)
2422 ALCcontext_IncRef(ctx);
2423 UnlockLists();
2424 return ctx;
2426 ctx = ctx->next;
2428 dev = dev->next;
2430 UnlockLists();
2432 return NULL;
2436 /* GetContextRef
2438 * Returns the currently active context for this thread, and adds a reference
2439 * without locking it.
2441 ALCcontext *GetContextRef(void)
2443 ALCcontext *context;
2445 context = altss_get(LocalContext);
2446 if(context)
2447 ALCcontext_IncRef(context);
2448 else
2450 LockLists();
2451 context = ATOMIC_LOAD(&GlobalContext);
2452 if(context)
2453 ALCcontext_IncRef(context);
2454 UnlockLists();
2457 return context;
2461 /************************************************
2462 * Standard ALC functions
2463 ************************************************/
2465 /* alcGetError
2467 * Return last ALC generated error code for the given device
2469 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2471 ALCenum errorCode;
2473 if(VerifyDevice(device))
2475 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2476 ALCdevice_DecRef(device);
2478 else
2479 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2481 return errorCode;
2485 /* alcSuspendContext
2487 * Suspends updates for the given context
2489 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2491 if(!SuspendDefers)
2492 return;
2494 context = VerifyContext(context);
2495 if(!context)
2496 alcSetError(NULL, ALC_INVALID_CONTEXT);
2497 else
2499 ALCcontext_DeferUpdates(context);
2500 ALCcontext_DecRef(context);
2504 /* alcProcessContext
2506 * Resumes processing updates for the given context
2508 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2510 if(!SuspendDefers)
2511 return;
2513 context = VerifyContext(context);
2514 if(!context)
2515 alcSetError(NULL, ALC_INVALID_CONTEXT);
2516 else
2518 ALCcontext_ProcessUpdates(context);
2519 ALCcontext_DecRef(context);
2524 /* alcGetString
2526 * Returns information about the device, and error strings
2528 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2530 const ALCchar *value = NULL;
2532 switch(param)
2534 case ALC_NO_ERROR:
2535 value = alcNoError;
2536 break;
2538 case ALC_INVALID_ENUM:
2539 value = alcErrInvalidEnum;
2540 break;
2542 case ALC_INVALID_VALUE:
2543 value = alcErrInvalidValue;
2544 break;
2546 case ALC_INVALID_DEVICE:
2547 value = alcErrInvalidDevice;
2548 break;
2550 case ALC_INVALID_CONTEXT:
2551 value = alcErrInvalidContext;
2552 break;
2554 case ALC_OUT_OF_MEMORY:
2555 value = alcErrOutOfMemory;
2556 break;
2558 case ALC_DEVICE_SPECIFIER:
2559 value = alcDefaultName;
2560 break;
2562 case ALC_ALL_DEVICES_SPECIFIER:
2563 if(VerifyDevice(Device))
2565 value = al_string_get_cstr(Device->DeviceName);
2566 ALCdevice_DecRef(Device);
2568 else
2570 ProbeAllDevicesList();
2571 value = al_string_get_cstr(alcAllDevicesList);
2573 break;
2575 case ALC_CAPTURE_DEVICE_SPECIFIER:
2576 if(VerifyDevice(Device))
2578 value = al_string_get_cstr(Device->DeviceName);
2579 ALCdevice_DecRef(Device);
2581 else
2583 ProbeCaptureDeviceList();
2584 value = al_string_get_cstr(alcCaptureDeviceList);
2586 break;
2588 /* Default devices are always first in the list */
2589 case ALC_DEFAULT_DEVICE_SPECIFIER:
2590 value = alcDefaultName;
2591 break;
2593 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2594 if(al_string_empty(alcAllDevicesList))
2595 ProbeAllDevicesList();
2597 Device = VerifyDevice(Device);
2599 free(alcDefaultAllDevicesSpecifier);
2600 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2601 if(!alcDefaultAllDevicesSpecifier)
2602 alcSetError(Device, ALC_OUT_OF_MEMORY);
2604 value = alcDefaultAllDevicesSpecifier;
2605 if(Device) ALCdevice_DecRef(Device);
2606 break;
2608 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2609 if(al_string_empty(alcCaptureDeviceList))
2610 ProbeCaptureDeviceList();
2612 Device = VerifyDevice(Device);
2614 free(alcCaptureDefaultDeviceSpecifier);
2615 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2616 if(!alcCaptureDefaultDeviceSpecifier)
2617 alcSetError(Device, ALC_OUT_OF_MEMORY);
2619 value = alcCaptureDefaultDeviceSpecifier;
2620 if(Device) ALCdevice_DecRef(Device);
2621 break;
2623 case ALC_EXTENSIONS:
2624 if(!VerifyDevice(Device))
2625 value = alcNoDeviceExtList;
2626 else
2628 value = alcExtensionList;
2629 ALCdevice_DecRef(Device);
2631 break;
2633 default:
2634 Device = VerifyDevice(Device);
2635 alcSetError(Device, ALC_INVALID_ENUM);
2636 if(Device) ALCdevice_DecRef(Device);
2637 break;
2640 return value;
2644 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2646 ALCsizei i;
2648 if(size <= 0 || values == NULL)
2650 alcSetError(device, ALC_INVALID_VALUE);
2651 return 0;
2654 if(!device)
2656 switch(param)
2658 case ALC_MAJOR_VERSION:
2659 values[0] = alcMajorVersion;
2660 return 1;
2661 case ALC_MINOR_VERSION:
2662 values[0] = alcMinorVersion;
2663 return 1;
2665 case ALC_ATTRIBUTES_SIZE:
2666 case ALC_ALL_ATTRIBUTES:
2667 case ALC_FREQUENCY:
2668 case ALC_REFRESH:
2669 case ALC_SYNC:
2670 case ALC_MONO_SOURCES:
2671 case ALC_STEREO_SOURCES:
2672 case ALC_CAPTURE_SAMPLES:
2673 case ALC_FORMAT_CHANNELS_SOFT:
2674 case ALC_FORMAT_TYPE_SOFT:
2675 alcSetError(NULL, ALC_INVALID_DEVICE);
2676 return 0;
2678 default:
2679 alcSetError(NULL, ALC_INVALID_ENUM);
2680 return 0;
2682 return 0;
2685 if(device->Type == Capture)
2687 switch(param)
2689 case ALC_CAPTURE_SAMPLES:
2690 V0(device->Backend,lock)();
2691 values[0] = V0(device->Backend,availableSamples)();
2692 V0(device->Backend,unlock)();
2693 return 1;
2695 case ALC_CONNECTED:
2696 values[0] = device->Connected;
2697 return 1;
2699 default:
2700 alcSetError(device, ALC_INVALID_ENUM);
2701 return 0;
2703 return 0;
2706 /* render device */
2707 switch(param)
2709 case ALC_MAJOR_VERSION:
2710 values[0] = alcMajorVersion;
2711 return 1;
2713 case ALC_MINOR_VERSION:
2714 values[0] = alcMinorVersion;
2715 return 1;
2717 case ALC_EFX_MAJOR_VERSION:
2718 values[0] = alcEFXMajorVersion;
2719 return 1;
2721 case ALC_EFX_MINOR_VERSION:
2722 values[0] = alcEFXMinorVersion;
2723 return 1;
2725 case ALC_ATTRIBUTES_SIZE:
2726 values[0] = 15;
2727 return 1;
2729 case ALC_ALL_ATTRIBUTES:
2730 if(size < 15)
2732 alcSetError(device, ALC_INVALID_VALUE);
2733 return 0;
2736 i = 0;
2737 values[i++] = ALC_FREQUENCY;
2738 values[i++] = device->Frequency;
2740 if(device->Type != Loopback)
2742 values[i++] = ALC_REFRESH;
2743 values[i++] = device->Frequency / device->UpdateSize;
2745 values[i++] = ALC_SYNC;
2746 values[i++] = ALC_FALSE;
2748 else
2750 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2751 values[i++] = device->FmtChans;
2753 values[i++] = ALC_FORMAT_TYPE_SOFT;
2754 values[i++] = device->FmtType;
2757 values[i++] = ALC_MONO_SOURCES;
2758 values[i++] = device->NumMonoSources;
2760 values[i++] = ALC_STEREO_SOURCES;
2761 values[i++] = device->NumStereoSources;
2763 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2764 values[i++] = device->NumAuxSends;
2766 values[i++] = ALC_HRTF_SOFT;
2767 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2769 values[i++] = 0;
2770 return i;
2772 case ALC_FREQUENCY:
2773 values[0] = device->Frequency;
2774 return 1;
2776 case ALC_REFRESH:
2777 if(device->Type == Loopback)
2779 alcSetError(device, ALC_INVALID_DEVICE);
2780 return 0;
2782 values[0] = device->Frequency / device->UpdateSize;
2783 return 1;
2785 case ALC_SYNC:
2786 if(device->Type == Loopback)
2788 alcSetError(device, ALC_INVALID_DEVICE);
2789 return 0;
2791 values[0] = ALC_FALSE;
2792 return 1;
2794 case ALC_FORMAT_CHANNELS_SOFT:
2795 if(device->Type != Loopback)
2797 alcSetError(device, ALC_INVALID_DEVICE);
2798 return 0;
2800 values[0] = device->FmtChans;
2801 return 1;
2803 case ALC_FORMAT_TYPE_SOFT:
2804 if(device->Type != Loopback)
2806 alcSetError(device, ALC_INVALID_DEVICE);
2807 return 0;
2809 values[0] = device->FmtType;
2810 return 1;
2812 case ALC_MONO_SOURCES:
2813 values[0] = device->NumMonoSources;
2814 return 1;
2816 case ALC_STEREO_SOURCES:
2817 values[0] = device->NumStereoSources;
2818 return 1;
2820 case ALC_MAX_AUXILIARY_SENDS:
2821 values[0] = device->NumAuxSends;
2822 return 1;
2824 case ALC_CONNECTED:
2825 values[0] = device->Connected;
2826 return 1;
2828 case ALC_HRTF_SOFT:
2829 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2830 return 1;
2832 default:
2833 alcSetError(device, ALC_INVALID_ENUM);
2834 return 0;
2836 return 0;
2839 /* alcGetIntegerv
2841 * Returns information about the device and the version of OpenAL
2843 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2845 device = VerifyDevice(device);
2846 if(size <= 0 || values == NULL)
2847 alcSetError(device, ALC_INVALID_VALUE);
2848 else
2849 GetIntegerv(device, param, size, values);
2850 if(device) ALCdevice_DecRef(device);
2853 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2855 ALCint *ivals;
2856 ALsizei i;
2858 device = VerifyDevice(device);
2859 if(size <= 0 || values == NULL)
2860 alcSetError(device, ALC_INVALID_VALUE);
2861 else if(!device || device->Type == Capture)
2863 ivals = malloc(size * sizeof(ALCint));
2864 size = GetIntegerv(device, pname, size, ivals);
2865 for(i = 0;i < size;i++)
2866 values[i] = ivals[i];
2867 free(ivals);
2869 else /* render device */
2871 switch(pname)
2873 case ALC_ATTRIBUTES_SIZE:
2874 *values = 17;
2875 break;
2877 case ALC_ALL_ATTRIBUTES:
2878 if(size < 17)
2879 alcSetError(device, ALC_INVALID_VALUE);
2880 else
2882 int i = 0;
2884 V0(device->Backend,lock)();
2885 values[i++] = ALC_FREQUENCY;
2886 values[i++] = device->Frequency;
2888 if(device->Type != Loopback)
2890 values[i++] = ALC_REFRESH;
2891 values[i++] = device->Frequency / device->UpdateSize;
2893 values[i++] = ALC_SYNC;
2894 values[i++] = ALC_FALSE;
2896 else
2898 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2899 values[i++] = device->FmtChans;
2901 values[i++] = ALC_FORMAT_TYPE_SOFT;
2902 values[i++] = device->FmtType;
2905 values[i++] = ALC_MONO_SOURCES;
2906 values[i++] = device->NumMonoSources;
2908 values[i++] = ALC_STEREO_SOURCES;
2909 values[i++] = device->NumStereoSources;
2911 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2912 values[i++] = device->NumAuxSends;
2914 values[i++] = ALC_HRTF_SOFT;
2915 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2917 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2918 values[i++] = device->ClockBase +
2919 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2921 values[i++] = 0;
2922 V0(device->Backend,unlock)();
2924 break;
2926 case ALC_DEVICE_CLOCK_SOFT:
2927 V0(device->Backend,lock)();
2928 *values = device->ClockBase +
2929 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2930 V0(device->Backend,unlock)();
2931 break;
2933 default:
2934 ivals = malloc(size * sizeof(ALCint));
2935 size = GetIntegerv(device, pname, size, ivals);
2936 for(i = 0;i < size;i++)
2937 values[i] = ivals[i];
2938 free(ivals);
2939 break;
2942 if(device)
2943 ALCdevice_DecRef(device);
2947 /* alcIsExtensionPresent
2949 * Determines if there is support for a particular extension
2951 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2953 ALCboolean bResult = ALC_FALSE;
2955 device = VerifyDevice(device);
2957 if(!extName)
2958 alcSetError(device, ALC_INVALID_VALUE);
2959 else
2961 size_t len = strlen(extName);
2962 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2963 while(ptr && *ptr)
2965 if(strncasecmp(ptr, extName, len) == 0 &&
2966 (ptr[len] == '\0' || isspace(ptr[len])))
2968 bResult = ALC_TRUE;
2969 break;
2971 if((ptr=strchr(ptr, ' ')) != NULL)
2973 do {
2974 ++ptr;
2975 } while(isspace(*ptr));
2979 if(device)
2980 ALCdevice_DecRef(device);
2981 return bResult;
2985 /* alcGetProcAddress
2987 * Retrieves the function address for a particular extension function
2989 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2991 ALCvoid *ptr = NULL;
2993 if(!funcName)
2995 device = VerifyDevice(device);
2996 alcSetError(device, ALC_INVALID_VALUE);
2997 if(device) ALCdevice_DecRef(device);
2999 else
3001 ALsizei i = 0;
3002 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3003 i++;
3004 ptr = alcFunctions[i].address;
3007 return ptr;
3011 /* alcGetEnumValue
3013 * Get the value for a particular ALC enumeration name
3015 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3017 ALCenum val = 0;
3019 if(!enumName)
3021 device = VerifyDevice(device);
3022 alcSetError(device, ALC_INVALID_VALUE);
3023 if(device) ALCdevice_DecRef(device);
3025 else
3027 ALsizei i = 0;
3028 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3029 i++;
3030 val = enumeration[i].value;
3033 return val;
3037 /* alcCreateContext
3039 * Create and attach a context to the given device.
3041 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3043 ALCcontext *ALContext;
3044 ALCenum err;
3046 LockLists();
3047 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
3049 UnlockLists();
3050 alcSetError(device, ALC_INVALID_DEVICE);
3051 if(device) ALCdevice_DecRef(device);
3052 return NULL;
3055 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3057 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3059 UnlockLists();
3060 alcSetError(device, err);
3061 if(err == ALC_INVALID_DEVICE)
3063 V0(device->Backend,lock)();
3064 aluHandleDisconnect(device);
3065 V0(device->Backend,unlock)();
3067 ALCdevice_DecRef(device);
3068 return NULL;
3071 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3072 if(ALContext)
3074 InitRef(&ALContext->ref, 1);
3075 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3077 VECTOR_INIT(ALContext->ActiveAuxSlots);
3079 ALContext->VoiceCount = 0;
3080 ALContext->MaxVoices = 256;
3081 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3083 if(!ALContext || !ALContext->Voices)
3085 if(!ATOMIC_LOAD(&device->ContextList))
3087 V0(device->Backend,stop)();
3088 device->Flags &= ~DEVICE_RUNNING;
3090 UnlockLists();
3092 if(ALContext)
3094 al_free(ALContext->Voices);
3095 ALContext->Voices = NULL;
3097 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3099 al_free(ALContext);
3100 ALContext = NULL;
3103 alcSetError(device, ALC_OUT_OF_MEMORY);
3104 ALCdevice_DecRef(device);
3105 return NULL;
3108 ALContext->Device = device;
3109 ALCdevice_IncRef(device);
3110 InitContext(ALContext);
3113 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3114 do {
3115 ALContext->next = head;
3116 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3118 UnlockLists();
3120 ALCdevice_DecRef(device);
3122 TRACE("Created context %p\n", ALContext);
3123 return ALContext;
3126 /* alcDestroyContext
3128 * Remove a context from its device
3130 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3132 ALCdevice *Device;
3134 LockLists();
3135 /* alcGetContextsDevice sets an error for invalid contexts */
3136 Device = alcGetContextsDevice(context);
3137 if(Device)
3139 ReleaseContext(context, Device);
3140 if(!ATOMIC_LOAD(&Device->ContextList))
3142 V0(Device->Backend,stop)();
3143 Device->Flags &= ~DEVICE_RUNNING;
3146 UnlockLists();
3150 /* alcGetCurrentContext
3152 * Returns the currently active context on the calling thread
3154 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3156 ALCcontext *Context = altss_get(LocalContext);
3157 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3158 return Context;
3161 /* alcGetThreadContext
3163 * Returns the currently active thread-local context
3165 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3167 return altss_get(LocalContext);
3171 /* alcMakeContextCurrent
3173 * Makes the given context the active process-wide context, and removes the
3174 * thread-local context for the calling thread.
3176 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3178 /* context must be valid or NULL */
3179 if(context && !(context=VerifyContext(context)))
3181 alcSetError(NULL, ALC_INVALID_CONTEXT);
3182 return ALC_FALSE;
3184 /* context's reference count is already incremented */
3185 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3186 if(context) ALCcontext_DecRef(context);
3188 if((context=altss_get(LocalContext)) != NULL)
3190 altss_set(LocalContext, NULL);
3191 ALCcontext_DecRef(context);
3194 return ALC_TRUE;
3197 /* alcSetThreadContext
3199 * Makes the given context the active context for the current thread
3201 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3203 ALCcontext *old;
3205 /* context must be valid or NULL */
3206 if(context && !(context=VerifyContext(context)))
3208 alcSetError(NULL, ALC_INVALID_CONTEXT);
3209 return ALC_FALSE;
3211 /* context's reference count is already incremented */
3212 old = altss_get(LocalContext);
3213 altss_set(LocalContext, context);
3214 if(old) ALCcontext_DecRef(old);
3216 return ALC_TRUE;
3220 /* alcGetContextsDevice
3222 * Returns the device that a particular context is attached to
3224 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3226 ALCdevice *Device;
3228 if(!(Context=VerifyContext(Context)))
3230 alcSetError(NULL, ALC_INVALID_CONTEXT);
3231 return NULL;
3233 Device = Context->Device;
3234 ALCcontext_DecRef(Context);
3236 return Device;
3240 /* alcOpenDevice
3242 * Opens the named device.
3244 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3246 const ALCchar *fmt;
3247 ALCdevice *device;
3248 ALCenum err;
3250 DO_INITCONFIG();
3252 if(!PlaybackBackend.name)
3254 alcSetError(NULL, ALC_INVALID_VALUE);
3255 return NULL;
3258 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3259 deviceName = NULL;
3261 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3262 if(!device)
3264 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3265 return NULL;
3268 //Validate device
3269 InitRef(&device->ref, 1);
3270 device->Connected = ALC_TRUE;
3271 device->Type = Playback;
3272 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3274 device->Flags = 0;
3275 device->Bs2b = NULL;
3276 AL_STRING_INIT(device->DeviceName);
3277 device->DryBuffer = NULL;
3279 ATOMIC_INIT(&device->ContextList, NULL);
3281 device->ClockBase = 0;
3282 device->SamplesDone = 0;
3284 device->MaxNoOfSources = 256;
3285 device->AuxiliaryEffectSlotMax = 4;
3286 device->NumAuxSends = MAX_SENDS;
3288 InitUIntMap(&device->BufferMap, ~0);
3289 InitUIntMap(&device->EffectMap, ~0);
3290 InitUIntMap(&device->FilterMap, ~0);
3291 InitUIntMap(&device->SfontMap, ~0);
3292 InitUIntMap(&device->PresetMap, ~0);
3293 InitUIntMap(&device->FontsoundMap, ~0);
3295 //Set output format
3296 device->FmtChans = DevFmtChannelsDefault;
3297 device->FmtType = DevFmtTypeDefault;
3298 device->Frequency = DEFAULT_OUTPUT_RATE;
3299 device->IsHeadphones = AL_FALSE;
3300 device->NumUpdates = 4;
3301 device->UpdateSize = 1024;
3303 if(!PlaybackBackend.getFactory)
3304 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3305 ALCbackend_Playback);
3306 else
3308 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3309 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3311 if(!device->Backend)
3313 al_free(device);
3314 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3315 return NULL;
3319 if(ConfigValueStr(NULL, "channels", &fmt))
3321 static const struct {
3322 const char name[16];
3323 enum DevFmtChannels chans;
3324 } chanlist[] = {
3325 { "mono", DevFmtMono },
3326 { "stereo", DevFmtStereo },
3327 { "quad", DevFmtQuad },
3328 { "surround51", DevFmtX51 },
3329 { "surround61", DevFmtX61 },
3330 { "surround71", DevFmtX71 },
3331 { "surround51rear", DevFmtX51Rear },
3333 size_t i;
3335 for(i = 0;i < COUNTOF(chanlist);i++)
3337 if(strcasecmp(chanlist[i].name, fmt) == 0)
3339 device->FmtChans = chanlist[i].chans;
3340 device->Flags |= DEVICE_CHANNELS_REQUEST;
3341 break;
3344 if(i == COUNTOF(chanlist))
3345 ERR("Unsupported channels: %s\n", fmt);
3347 if(ConfigValueStr(NULL, "sample-type", &fmt))
3349 static const struct {
3350 const char name[16];
3351 enum DevFmtType type;
3352 } typelist[] = {
3353 { "int8", DevFmtByte },
3354 { "uint8", DevFmtUByte },
3355 { "int16", DevFmtShort },
3356 { "uint16", DevFmtUShort },
3357 { "int32", DevFmtInt },
3358 { "uint32", DevFmtUInt },
3359 { "float32", DevFmtFloat },
3361 size_t i;
3363 for(i = 0;i < COUNTOF(typelist);i++)
3365 if(strcasecmp(typelist[i].name, fmt) == 0)
3367 device->FmtType = typelist[i].type;
3368 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3369 break;
3372 if(i == COUNTOF(typelist))
3373 ERR("Unsupported sample-type: %s\n", fmt);
3376 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
3378 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3379 if(device->Frequency < MIN_OUTPUT_RATE)
3380 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3381 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3384 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
3385 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3387 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
3388 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3389 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3390 device->UpdateSize = (device->UpdateSize+3)&~3;
3392 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3393 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3395 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3396 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3398 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3399 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3401 device->NumStereoSources = 1;
3402 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3404 device->Synth = SynthCreate(device);
3405 if(!device->Synth)
3407 DELETE_OBJ(device->Backend);
3408 al_free(device);
3409 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3410 return NULL;
3413 // Find a playback device to open
3414 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3416 DELETE_OBJ(device->Synth);
3417 DELETE_OBJ(device->Backend);
3418 al_free(device);
3419 alcSetError(NULL, err);
3420 return NULL;
3423 if(DefaultEffect.type != AL_EFFECT_NULL)
3425 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3426 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3428 device->DefaultSlot = NULL;
3429 ERR("Failed to initialize the default effect slot\n");
3431 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3433 ALeffectState *state = device->DefaultSlot->EffectState;
3434 device->DefaultSlot = NULL;
3435 DELETE_OBJ(state);
3436 ERR("Failed to initialize the default effect\n");
3441 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3442 do {
3443 device->next = head;
3444 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3447 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3448 return device;
3451 /* alcCloseDevice
3453 * Closes the given device.
3455 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3457 ALCdevice *list, *origdev, *nextdev;
3458 ALCcontext *ctx;
3460 LockLists();
3461 list = ATOMIC_LOAD(&DeviceList);
3462 do {
3463 if(list == device)
3464 break;
3465 } while((list=list->next) != NULL);
3466 if(!list || list->Type == Capture)
3468 alcSetError(list, ALC_INVALID_DEVICE);
3469 UnlockLists();
3470 return ALC_FALSE;
3473 origdev = device;
3474 nextdev = device->next;
3475 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3477 do {
3478 list = origdev;
3479 origdev = device;
3480 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3482 UnlockLists();
3484 ctx = ATOMIC_LOAD(&device->ContextList);
3485 while(ctx != NULL)
3487 ALCcontext *next = ctx->next;
3488 WARN("Releasing context %p\n", ctx);
3489 ReleaseContext(ctx, device);
3490 ctx = next;
3492 if((device->Flags&DEVICE_RUNNING))
3493 V0(device->Backend,stop)();
3494 device->Flags &= ~DEVICE_RUNNING;
3496 ALCdevice_DecRef(device);
3498 return ALC_TRUE;
3502 /************************************************
3503 * ALC capture functions
3504 ************************************************/
3505 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3507 ALCdevice *device = NULL;
3508 ALCenum err;
3510 DO_INITCONFIG();
3512 if(!CaptureBackend.name)
3514 alcSetError(NULL, ALC_INVALID_VALUE);
3515 return NULL;
3518 if(samples <= 0)
3520 alcSetError(NULL, ALC_INVALID_VALUE);
3521 return NULL;
3524 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3525 deviceName = NULL;
3527 device = al_calloc(16, sizeof(ALCdevice));
3528 if(!device)
3530 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3531 return NULL;
3534 //Validate device
3535 InitRef(&device->ref, 1);
3536 device->Connected = ALC_TRUE;
3537 device->Type = Capture;
3539 AL_STRING_INIT(device->DeviceName);
3540 device->DryBuffer = NULL;
3542 InitUIntMap(&device->BufferMap, ~0);
3543 InitUIntMap(&device->EffectMap, ~0);
3544 InitUIntMap(&device->FilterMap, ~0);
3545 InitUIntMap(&device->SfontMap, ~0);
3546 InitUIntMap(&device->PresetMap, ~0);
3547 InitUIntMap(&device->FontsoundMap, ~0);
3549 if(!CaptureBackend.getFactory)
3550 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3551 ALCbackend_Capture);
3552 else
3554 ALCbackendFactory *factory = CaptureBackend.getFactory();
3555 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3557 if(!device->Backend)
3559 al_free(device);
3560 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3561 return NULL;
3564 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3565 device->Frequency = frequency;
3567 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3568 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3570 al_free(device);
3571 alcSetError(NULL, ALC_INVALID_ENUM);
3572 return NULL;
3574 device->IsHeadphones = AL_FALSE;
3576 device->UpdateSize = samples;
3577 device->NumUpdates = 1;
3579 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3581 al_free(device);
3582 alcSetError(NULL, err);
3583 return NULL;
3587 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3588 do {
3589 device->next = head;
3590 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3593 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3594 return device;
3597 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3599 ALCdevice *list, *next, *nextdev;
3601 LockLists();
3602 list = ATOMIC_LOAD(&DeviceList);
3603 do {
3604 if(list == device)
3605 break;
3606 } while((list=list->next) != NULL);
3607 if(!list || list->Type != Capture)
3609 alcSetError(list, ALC_INVALID_DEVICE);
3610 UnlockLists();
3611 return ALC_FALSE;
3614 next = device;
3615 nextdev = device->next;
3616 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3618 do {
3619 list = next;
3620 next = device;
3621 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3623 UnlockLists();
3625 ALCdevice_DecRef(device);
3627 return ALC_TRUE;
3630 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3632 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3633 alcSetError(device, ALC_INVALID_DEVICE);
3634 else
3636 V0(device->Backend,lock)();
3637 if(!device->Connected)
3638 alcSetError(device, ALC_INVALID_DEVICE);
3639 else if(!(device->Flags&DEVICE_RUNNING))
3641 if(V0(device->Backend,start)())
3642 device->Flags |= DEVICE_RUNNING;
3643 else
3645 aluHandleDisconnect(device);
3646 alcSetError(device, ALC_INVALID_DEVICE);
3649 V0(device->Backend,unlock)();
3652 if(device) ALCdevice_DecRef(device);
3655 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3657 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3658 alcSetError(device, ALC_INVALID_DEVICE);
3659 else
3661 V0(device->Backend,lock)();
3662 if((device->Flags&DEVICE_RUNNING))
3663 V0(device->Backend,stop)();
3664 device->Flags &= ~DEVICE_RUNNING;
3665 V0(device->Backend,unlock)();
3668 if(device) ALCdevice_DecRef(device);
3671 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3673 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3674 alcSetError(device, ALC_INVALID_DEVICE);
3675 else
3677 ALCenum err = ALC_INVALID_VALUE;
3679 V0(device->Backend,lock)();
3680 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3681 err = V(device->Backend,captureSamples)(buffer, samples);
3682 V0(device->Backend,unlock)();
3684 if(err != ALC_NO_ERROR)
3685 alcSetError(device, err);
3687 if(device) ALCdevice_DecRef(device);
3691 /************************************************
3692 * ALC loopback functions
3693 ************************************************/
3695 /* alcLoopbackOpenDeviceSOFT
3697 * Open a loopback device, for manual rendering.
3699 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3701 ALCbackendFactory *factory;
3702 ALCdevice *device;
3704 DO_INITCONFIG();
3706 /* Make sure the device name, if specified, is us. */
3707 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3709 alcSetError(NULL, ALC_INVALID_VALUE);
3710 return NULL;
3713 device = al_calloc(16, sizeof(ALCdevice));
3714 if(!device)
3716 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3717 return NULL;
3720 //Validate device
3721 InitRef(&device->ref, 1);
3722 device->Connected = ALC_TRUE;
3723 device->Type = Loopback;
3724 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3726 device->Flags = 0;
3727 device->Bs2b = NULL;
3728 AL_STRING_INIT(device->DeviceName);
3729 device->DryBuffer = NULL;
3731 ATOMIC_INIT(&device->ContextList, NULL);
3733 device->ClockBase = 0;
3734 device->SamplesDone = 0;
3736 device->MaxNoOfSources = 256;
3737 device->AuxiliaryEffectSlotMax = 4;
3738 device->NumAuxSends = MAX_SENDS;
3740 InitUIntMap(&device->BufferMap, ~0);
3741 InitUIntMap(&device->EffectMap, ~0);
3742 InitUIntMap(&device->FilterMap, ~0);
3743 InitUIntMap(&device->SfontMap, ~0);
3744 InitUIntMap(&device->PresetMap, ~0);
3745 InitUIntMap(&device->FontsoundMap, ~0);
3747 factory = ALCloopbackFactory_getFactory();
3748 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3749 if(!device->Backend)
3751 al_free(device);
3752 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3753 return NULL;
3756 //Set output format
3757 device->NumUpdates = 0;
3758 device->UpdateSize = 0;
3760 device->Frequency = DEFAULT_OUTPUT_RATE;
3761 device->FmtChans = DevFmtChannelsDefault;
3762 device->FmtType = DevFmtTypeDefault;
3763 device->IsHeadphones = AL_FALSE;
3765 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3766 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3768 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3769 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3771 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3772 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3774 device->NumStereoSources = 1;
3775 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3777 device->Synth = SynthCreate(device);
3778 if(!device->Synth)
3780 DELETE_OBJ(device->Backend);
3781 al_free(device);
3782 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3783 return NULL;
3786 // Open the "backend"
3787 V(device->Backend,open)("Loopback");
3790 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3791 do {
3792 device->next = head;
3793 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3796 TRACE("Created device %p\n", device);
3797 return device;
3800 /* alcIsRenderFormatSupportedSOFT
3802 * Determines if the loopback device supports the given format for rendering.
3804 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3806 ALCboolean ret = ALC_FALSE;
3808 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3809 alcSetError(device, ALC_INVALID_DEVICE);
3810 else if(freq <= 0)
3811 alcSetError(device, ALC_INVALID_VALUE);
3812 else
3814 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3815 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3816 freq >= MIN_OUTPUT_RATE)
3817 ret = ALC_TRUE;
3819 if(device) ALCdevice_DecRef(device);
3821 return ret;
3824 /* alcRenderSamplesSOFT
3826 * Renders some samples into a buffer, using the format last set by the
3827 * attributes given to alcCreateContext.
3829 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3831 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3832 alcSetError(device, ALC_INVALID_DEVICE);
3833 else if(samples < 0 || (samples > 0 && buffer == NULL))
3834 alcSetError(device, ALC_INVALID_VALUE);
3835 else
3836 aluMixData(device, buffer, samples);
3837 if(device) ALCdevice_DecRef(device);
3841 /************************************************
3842 * ALC DSP pause/resume functions
3843 ************************************************/
3845 /* alcDevicePauseSOFT
3847 * Pause the DSP to stop audio processing.
3849 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3851 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3852 alcSetError(device, ALC_INVALID_DEVICE);
3853 else
3855 LockLists();
3856 if((device->Flags&DEVICE_RUNNING))
3857 V0(device->Backend,stop)();
3858 device->Flags &= ~DEVICE_RUNNING;
3859 device->Flags |= DEVICE_PAUSED;
3860 UnlockLists();
3862 if(device) ALCdevice_DecRef(device);
3865 /* alcDeviceResumeSOFT
3867 * Resume the DSP to restart audio processing.
3869 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3871 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3872 alcSetError(device, ALC_INVALID_DEVICE);
3873 else
3875 LockLists();
3876 if((device->Flags&DEVICE_PAUSED))
3878 device->Flags &= ~DEVICE_PAUSED;
3879 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3881 if(V0(device->Backend,start)() != ALC_FALSE)
3882 device->Flags |= DEVICE_RUNNING;
3883 else
3885 alcSetError(device, ALC_INVALID_DEVICE);
3886 V0(device->Backend,lock)();
3887 aluHandleDisconnect(device);
3888 V0(device->Backend,unlock)();
3892 UnlockLists();
3894 if(device) ALCdevice_DecRef(device);