Add an option to prevent spawning a JACK server
[openal-soft.git] / Alc / ALc.c
bloba680390f633f870c94ef145fcd186bda8164e751
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_PULSEAUDIO
65 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
66 #endif
67 #ifdef HAVE_ALSA
68 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
69 #endif
70 #ifdef HAVE_COREAUDIO
71 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
72 #endif
73 #ifdef HAVE_OSS
74 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
75 #endif
76 #ifdef HAVE_SOLARIS
77 { "solaris", NULL, alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs },
78 #endif
79 #ifdef HAVE_SNDIO
80 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
81 #endif
82 #ifdef HAVE_QSA
83 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
84 #endif
85 #ifdef HAVE_JACK
86 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, 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(!ExchangeInt(&context->DeferUpdates, AL_TRUE))
1604 ALboolean UpdateSources;
1605 ALvoice *voice, *voice_end;
1606 ALeffectslot **slot, **slot_end;
1607 /* Make sure all pending updates are performed */
1608 UpdateSources = ATOMIC_EXCHANGE(ALenum, &context->UpdateSources, AL_FALSE);
1610 voice = context->Voices;
1611 voice_end = voice + context->VoiceCount;
1612 while(voice != voice_end)
1614 ALsource *source = voice->Source;
1615 if(!source) goto next;
1617 if(source->state != AL_PLAYING && source->state != AL_PAUSED)
1619 voice->Source = NULL;
1620 goto next;
1623 if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || UpdateSources)
1624 voice->Update(voice, source, context);
1625 next:
1626 voice++;
1629 slot = VECTOR_ITER_BEGIN(context->ActiveAuxSlots);
1630 slot_end = VECTOR_ITER_END(context->ActiveAuxSlots);
1631 while(slot != slot_end)
1633 if(ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE))
1634 V((*slot)->EffectState,update)(context->Device, *slot);
1635 slot++;
1638 V0(device->Backend,unlock)();
1640 RestoreFPUMode(&oldMode);
1643 /* ALCcontext_ProcessUpdates
1645 * Resumes update processing after being deferred.
1647 void ALCcontext_ProcessUpdates(ALCcontext *context)
1649 ALCdevice *device = context->Device;
1651 V0(device->Backend,lock)();
1652 if(ExchangeInt(&context->DeferUpdates, AL_FALSE))
1654 ALsizei pos;
1656 LockUIntMapRead(&context->SourceMap);
1657 for(pos = 0;pos < context->SourceMap.size;pos++)
1659 ALsource *Source = context->SourceMap.array[pos].value;
1660 ALenum new_state;
1662 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1663 Source->Offset >= 0.0)
1665 ReadLock(&Source->queue_lock);
1666 ApplyOffset(Source);
1667 ReadUnlock(&Source->queue_lock);
1670 new_state = ExchangeInt(&Source->new_state, AL_NONE);
1671 if(new_state)
1672 SetSourceState(Source, context, new_state);
1674 UnlockUIntMapRead(&context->SourceMap);
1676 V0(device->Backend,unlock)();
1680 /* alcSetError
1682 * Stores the latest ALC device error
1684 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1686 if(TrapALCError)
1688 #ifdef _WIN32
1689 /* DebugBreak() will cause an exception if there is no debugger */
1690 if(IsDebuggerPresent())
1691 DebugBreak();
1692 #elif defined(SIGTRAP)
1693 raise(SIGTRAP);
1694 #endif
1697 if(device)
1698 ATOMIC_STORE(&device->LastError, errorCode);
1699 else
1700 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1704 /* UpdateClockBase
1706 * Updates the device's base clock time with however many samples have been
1707 * done. This is used so frequency changes on the device don't cause the time
1708 * to jump forward or back.
1710 static inline void UpdateClockBase(ALCdevice *device)
1712 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1713 device->SamplesDone = 0;
1716 /* UpdateDeviceParams
1718 * Updates device parameters according to the attribute list (caller is
1719 * responsible for holding the list lock).
1721 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1723 ALCcontext *context;
1724 enum DevFmtChannels oldChans;
1725 enum DevFmtType oldType;
1726 ALCuint oldFreq;
1727 FPUCtl oldMode;
1728 size_t size;
1730 // Check for attributes
1731 if(device->Type == Loopback)
1733 enum {
1734 GotFreq = 1<<0,
1735 GotChans = 1<<1,
1736 GotType = 1<<2,
1737 GotAll = GotFreq|GotChans|GotType
1739 ALCuint freq, numMono, numStereo, numSends, flags;
1740 enum DevFmtChannels schans;
1741 enum DevFmtType stype;
1742 ALCuint attrIdx = 0;
1743 ALCint gotFmt = 0;
1745 if(!attrList)
1747 WARN("Missing attributes for loopback device\n");
1748 return ALC_INVALID_VALUE;
1751 numMono = device->NumMonoSources;
1752 numStereo = device->NumStereoSources;
1753 numSends = device->NumAuxSends;
1754 schans = device->FmtChans;
1755 stype = device->FmtType;
1756 freq = device->Frequency;
1757 flags = device->Flags;
1759 while(attrList[attrIdx])
1761 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1763 ALCint val = attrList[attrIdx + 1];
1764 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1765 return ALC_INVALID_VALUE;
1766 schans = val;
1767 gotFmt |= GotChans;
1770 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1772 ALCint val = attrList[attrIdx + 1];
1773 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1774 return ALC_INVALID_VALUE;
1775 stype = val;
1776 gotFmt |= GotType;
1779 if(attrList[attrIdx] == ALC_FREQUENCY)
1781 freq = attrList[attrIdx + 1];
1782 if(freq < MIN_OUTPUT_RATE)
1783 return ALC_INVALID_VALUE;
1784 gotFmt |= GotFreq;
1787 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1789 numStereo = attrList[attrIdx + 1];
1790 if(numStereo > device->MaxNoOfSources)
1791 numStereo = device->MaxNoOfSources;
1793 numMono = device->MaxNoOfSources - numStereo;
1796 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1797 numSends = attrList[attrIdx + 1];
1799 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1801 if(attrList[attrIdx + 1] != ALC_FALSE)
1802 flags |= DEVICE_HRTF_REQUEST;
1803 else
1804 flags &= ~DEVICE_HRTF_REQUEST;
1807 attrIdx += 2;
1810 if(gotFmt != GotAll)
1812 WARN("Missing format for loopback device\n");
1813 return ALC_INVALID_VALUE;
1816 ConfigValueUInt(NULL, "sends", &numSends);
1817 numSends = minu(MAX_SENDS, numSends);
1819 if((device->Flags&DEVICE_RUNNING))
1820 V0(device->Backend,stop)();
1821 device->Flags = (flags & ~DEVICE_RUNNING);
1823 UpdateClockBase(device);
1825 device->Frequency = freq;
1826 device->FmtChans = schans;
1827 device->FmtType = stype;
1828 device->NumMonoSources = numMono;
1829 device->NumStereoSources = numStereo;
1830 device->NumAuxSends = numSends;
1832 else if(attrList && attrList[0])
1834 ALCuint freq, numMono, numStereo, numSends;
1835 ALCuint attrIdx = 0;
1837 /* If a context is already running on the device, stop playback so the
1838 * device attributes can be updated. */
1839 if((device->Flags&DEVICE_RUNNING))
1840 V0(device->Backend,stop)();
1841 device->Flags &= ~DEVICE_RUNNING;
1843 freq = device->Frequency;
1844 numMono = device->NumMonoSources;
1845 numStereo = device->NumStereoSources;
1846 numSends = device->NumAuxSends;
1848 while(attrList[attrIdx])
1850 if(attrList[attrIdx] == ALC_FREQUENCY)
1852 freq = attrList[attrIdx + 1];
1853 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1856 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1858 numStereo = attrList[attrIdx + 1];
1859 if(numStereo > device->MaxNoOfSources)
1860 numStereo = device->MaxNoOfSources;
1862 numMono = device->MaxNoOfSources - numStereo;
1865 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1866 numSends = attrList[attrIdx + 1];
1868 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1870 if(attrList[attrIdx + 1] != ALC_FALSE)
1871 device->Flags |= DEVICE_HRTF_REQUEST;
1872 else
1873 device->Flags &= ~DEVICE_HRTF_REQUEST;
1876 attrIdx += 2;
1879 ConfigValueUInt(NULL, "frequency", &freq);
1880 freq = maxu(freq, MIN_OUTPUT_RATE);
1882 ConfigValueUInt(NULL, "sends", &numSends);
1883 numSends = minu(MAX_SENDS, numSends);
1885 UpdateClockBase(device);
1887 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1888 device->Frequency;
1889 /* SSE and Neon do best with the update size being a multiple of 4 */
1890 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1891 device->UpdateSize = (device->UpdateSize+3)&~3;
1893 device->Frequency = freq;
1894 device->NumMonoSources = numMono;
1895 device->NumStereoSources = numStereo;
1896 device->NumAuxSends = numSends;
1899 if((device->Flags&DEVICE_RUNNING))
1900 return ALC_NO_ERROR;
1902 al_free(device->DryBuffer);
1903 device->DryBuffer = NULL;
1905 UpdateClockBase(device);
1907 if(device->Type != Loopback && ((device->Flags&DEVICE_HRTF_REQUEST) || GetConfigValueBool(NULL, "hrtf", 0)))
1909 if(!FindHrtfFormat(&device->FmtChans, &device->Frequency))
1910 device->Flags &= ~DEVICE_HRTF_REQUEST;
1911 else
1912 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST |
1913 DEVICE_HRTF_REQUEST;
1915 if(device->Type == Loopback && (device->Flags&DEVICE_HRTF_REQUEST))
1917 enum DevFmtChannels chans = device->FmtChans;
1918 ALCuint freq = device->Frequency;
1919 if(!FindHrtfFormat(&chans, &freq) || chans != device->FmtChans || freq != device->Frequency)
1921 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1922 DevFmtChannelsString(device->FmtChans), device->Frequency);
1923 device->Flags &= ~DEVICE_HRTF_REQUEST;
1927 oldFreq = device->Frequency;
1928 oldChans = device->FmtChans;
1929 oldType = device->FmtType;
1931 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1932 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1933 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1934 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1935 device->UpdateSize, device->NumUpdates
1938 if(V0(device->Backend,reset)() == ALC_FALSE)
1939 return ALC_INVALID_DEVICE;
1941 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1943 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1944 DevFmtChannelsString(device->FmtChans));
1945 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1947 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1949 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1950 DevFmtTypeString(device->FmtType));
1951 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1953 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1955 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1956 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1959 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1960 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1961 device->Frequency, device->UpdateSize, device->NumUpdates
1964 if((device->UpdateSize&3) != 0)
1966 if((CPUCapFlags&CPU_CAP_SSE))
1967 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1968 if((CPUCapFlags&CPU_CAP_NEON))
1969 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1972 device->Hrtf = NULL;
1973 if(device->FmtChans != DevFmtStereo)
1975 free(device->Bs2b);
1976 device->Bs2b = NULL;
1978 else
1980 bool headphones = device->IsHeadphones;
1981 const char *mode;
1982 int bs2blevel;
1983 int usehrtf;
1985 if(device->Type != Loopback && ConfigValueStr(NULL, "stereo-mode", &mode))
1987 if(strcasecmp(mode, "headphones") == 0)
1988 headphones = true;
1989 else if(strcasecmp(mode, "speakers") == 0)
1990 headphones = false;
1991 else if(strcasecmp(mode, "auto") != 0)
1992 ERR("Unexpected stereo-mode: %s\n", mode);
1995 if(device->Type == Loopback || !ConfigValueBool(NULL, "hrtf", &usehrtf))
1996 usehrtf = ((device->Flags&DEVICE_HRTF_REQUEST) || headphones);
1998 if(usehrtf)
1999 device->Hrtf = GetHrtf(device->FmtChans, device->Frequency);
2000 if(device->Hrtf)
2001 TRACE("HRTF enabled\n");
2002 else
2004 device->Flags &= ~DEVICE_HRTF_REQUEST;
2005 TRACE("HRTF disabled\n");
2007 bs2blevel = (headphones ? 5 : 0);
2008 if(device->Type != Loopback)
2009 ConfigValueInt(NULL, "cf_level", &bs2blevel);
2010 if(bs2blevel > 0 && bs2blevel <= 6)
2012 if(!device->Bs2b)
2014 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
2015 bs2b_clear(device->Bs2b);
2017 bs2b_set_srate(device->Bs2b, device->Frequency);
2018 bs2b_set_level(device->Bs2b, bs2blevel);
2019 TRACE("BS2B enabled\n");
2021 else
2023 free(device->Bs2b);
2024 device->Bs2b = NULL;
2025 TRACE("BS2B disabled\n");
2030 aluInitPanning(device);
2032 /* With HRTF enabled, virtual channels are allocated for B-Format and
2033 * effects renfering. Two extra channels are allocated for the actual HRTF-
2034 * filtered output.
2036 size = sizeof(device->DryBuffer[0]) * (device->NumChannels + (device->Hrtf ? 2 : 0));
2037 device->DryBuffer = al_calloc(16, size);
2038 if(!device->DryBuffer)
2040 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2041 return ALC_INVALID_DEVICE;
2044 V(device->Synth,update)(device);
2046 SetMixerFPUMode(&oldMode);
2047 V0(device->Backend,lock)();
2048 context = ATOMIC_LOAD(&device->ContextList);
2049 while(context)
2051 ALsizei pos;
2053 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2054 LockUIntMapRead(&context->EffectSlotMap);
2055 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2057 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2059 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2061 UnlockUIntMapRead(&context->EffectSlotMap);
2062 V0(device->Backend,unlock)();
2063 RestoreFPUMode(&oldMode);
2064 return ALC_INVALID_DEVICE;
2066 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2067 V(slot->EffectState,update)(device, slot);
2069 UnlockUIntMapRead(&context->EffectSlotMap);
2071 LockUIntMapRead(&context->SourceMap);
2072 for(pos = 0;pos < context->SourceMap.size;pos++)
2074 ALsource *source = context->SourceMap.array[pos].value;
2075 ALuint s = device->NumAuxSends;
2076 while(s < MAX_SENDS)
2078 if(source->Send[s].Slot)
2079 DecrementRef(&source->Send[s].Slot->ref);
2080 source->Send[s].Slot = NULL;
2081 source->Send[s].Gain = 1.0f;
2082 source->Send[s].GainHF = 1.0f;
2083 s++;
2085 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2087 UnlockUIntMapRead(&context->SourceMap);
2089 for(pos = 0;pos < context->VoiceCount;pos++)
2091 ALvoice *voice = &context->Voices[pos];
2092 ALsource *source = voice->Source;
2093 ALuint s = device->NumAuxSends;
2095 while(s < MAX_SENDS)
2097 voice->Send[s].Moving = AL_FALSE;
2098 voice->Send[s].Counter = 0;
2099 s++;
2102 if(source)
2104 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2105 voice->Update(voice, source, context);
2109 context = context->next;
2111 if(device->DefaultSlot)
2113 ALeffectslot *slot = device->DefaultSlot;
2115 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2117 V0(device->Backend,unlock)();
2118 RestoreFPUMode(&oldMode);
2119 return ALC_INVALID_DEVICE;
2121 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2122 V(slot->EffectState,update)(device, slot);
2124 V0(device->Backend,unlock)();
2125 RestoreFPUMode(&oldMode);
2127 if(!(device->Flags&DEVICE_PAUSED))
2129 if(V0(device->Backend,start)() == ALC_FALSE)
2130 return ALC_INVALID_DEVICE;
2131 device->Flags |= DEVICE_RUNNING;
2134 return ALC_NO_ERROR;
2137 /* FreeDevice
2139 * Frees the device structure, and destroys any objects the app failed to
2140 * delete. Called once there's no more references on the device.
2142 static ALCvoid FreeDevice(ALCdevice *device)
2144 TRACE("%p\n", device);
2146 V0(device->Backend,close)();
2147 DELETE_OBJ(device->Backend);
2148 device->Backend = NULL;
2150 DELETE_OBJ(device->Synth);
2151 device->Synth = NULL;
2153 if(device->DefaultSlot)
2155 ALeffectState *state = device->DefaultSlot->EffectState;
2156 device->DefaultSlot = NULL;
2157 DELETE_OBJ(state);
2160 if(device->DefaultSfont)
2161 ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
2162 device->DefaultSfont = NULL;
2164 if(device->BufferMap.size > 0)
2166 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2167 ReleaseALBuffers(device);
2169 ResetUIntMap(&device->BufferMap);
2171 if(device->EffectMap.size > 0)
2173 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2174 ReleaseALEffects(device);
2176 ResetUIntMap(&device->EffectMap);
2178 if(device->FilterMap.size > 0)
2180 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2181 ReleaseALFilters(device);
2183 ResetUIntMap(&device->FilterMap);
2185 if(device->SfontMap.size > 0)
2187 WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size);
2188 ReleaseALSoundfonts(device);
2190 ResetUIntMap(&device->SfontMap);
2192 if(device->PresetMap.size > 0)
2194 WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size);
2195 ReleaseALPresets(device);
2197 ResetUIntMap(&device->PresetMap);
2199 if(device->FontsoundMap.size > 0)
2201 WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size);
2202 ReleaseALFontsounds(device);
2204 ResetUIntMap(&device->FontsoundMap);
2206 free(device->Bs2b);
2207 device->Bs2b = NULL;
2209 AL_STRING_DEINIT(device->DeviceName);
2211 al_free(device->DryBuffer);
2212 device->DryBuffer = NULL;
2214 al_free(device);
2218 void ALCdevice_IncRef(ALCdevice *device)
2220 uint ref;
2221 ref = IncrementRef(&device->ref);
2222 TRACEREF("%p increasing refcount to %u\n", device, ref);
2225 void ALCdevice_DecRef(ALCdevice *device)
2227 uint ref;
2228 ref = DecrementRef(&device->ref);
2229 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2230 if(ref == 0) FreeDevice(device);
2233 /* VerifyDevice
2235 * Checks if the device handle is valid, and increments its ref count if so.
2237 static ALCdevice *VerifyDevice(ALCdevice *device)
2239 ALCdevice *tmpDevice;
2241 if(!device)
2242 return NULL;
2244 LockLists();
2245 tmpDevice = ATOMIC_LOAD(&DeviceList);
2246 while(tmpDevice && tmpDevice != device)
2247 tmpDevice = tmpDevice->next;
2249 if(tmpDevice)
2250 ALCdevice_IncRef(tmpDevice);
2251 UnlockLists();
2252 return tmpDevice;
2256 /* InitContext
2258 * Initializes context fields
2260 static ALvoid InitContext(ALCcontext *Context)
2262 //Initialise listener
2263 Context->Listener->Gain = 1.0f;
2264 Context->Listener->MetersPerUnit = 1.0f;
2265 aluVectorSet(&Context->Listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2266 aluVectorSet(&Context->Listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2267 Context->Listener->Forward[0] = 0.0f;
2268 Context->Listener->Forward[1] = 0.0f;
2269 Context->Listener->Forward[2] = -1.0f;
2270 Context->Listener->Up[0] = 0.0f;
2271 Context->Listener->Up[1] = 1.0f;
2272 Context->Listener->Up[2] = 0.0f;
2273 aluMatrixSet(&Context->Listener->Params.Matrix,
2274 1.0f, 0.0f, 0.0f, 0.0f,
2275 0.0f, 1.0f, 0.0f, 0.0f,
2276 0.0f, 0.0f, 1.0f, 0.0f,
2277 0.0f, 0.0f, 0.0f, 1.0f
2279 aluVectorSet(&Context->Listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2281 //Validate Context
2282 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2283 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2284 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2285 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2287 //Set globals
2288 Context->DistanceModel = DefaultDistanceModel;
2289 Context->SourceDistanceModel = AL_FALSE;
2290 Context->DopplerFactor = 1.0f;
2291 Context->DopplerVelocity = 1.0f;
2292 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2293 Context->DeferUpdates = AL_FALSE;
2295 Context->ExtensionList = alExtList;
2299 /* FreeContext
2301 * Cleans up the context, and destroys any remaining objects the app failed to
2302 * delete. Called once there's no more references on the context.
2304 static void FreeContext(ALCcontext *context)
2306 TRACE("%p\n", context);
2308 if(context->SourceMap.size > 0)
2310 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2311 ReleaseALSources(context);
2313 ResetUIntMap(&context->SourceMap);
2315 if(context->EffectSlotMap.size > 0)
2317 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2318 ReleaseALAuxiliaryEffectSlots(context);
2320 ResetUIntMap(&context->EffectSlotMap);
2322 al_free(context->Voices);
2323 context->Voices = NULL;
2324 context->VoiceCount = 0;
2325 context->MaxVoices = 0;
2327 VECTOR_DEINIT(context->ActiveAuxSlots);
2329 ALCdevice_DecRef(context->Device);
2330 context->Device = NULL;
2332 //Invalidate context
2333 memset(context, 0, sizeof(ALCcontext));
2334 al_free(context);
2337 /* ReleaseContext
2339 * Removes the context reference from the given device and removes it from
2340 * being current on the running thread or globally.
2342 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2344 ALCcontext *nextctx;
2345 ALCcontext *origctx;
2347 if(altss_get(LocalContext) == context)
2349 WARN("%p released while current on thread\n", context);
2350 altss_set(LocalContext, NULL);
2351 ALCcontext_DecRef(context);
2354 origctx = context;
2355 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2356 ALCcontext_DecRef(context);
2358 ALCdevice_Lock(device);
2359 origctx = context;
2360 nextctx = context->next;
2361 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2363 ALCcontext *list;
2364 do {
2365 list = origctx;
2366 origctx = context;
2367 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2369 ALCdevice_Unlock(device);
2371 ALCcontext_DecRef(context);
2374 void ALCcontext_IncRef(ALCcontext *context)
2376 uint ref;
2377 ref = IncrementRef(&context->ref);
2378 TRACEREF("%p increasing refcount to %u\n", context, ref);
2381 void ALCcontext_DecRef(ALCcontext *context)
2383 uint ref;
2384 ref = DecrementRef(&context->ref);
2385 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2386 if(ref == 0) FreeContext(context);
2389 static void ReleaseThreadCtx(void *ptr)
2391 WARN("%p current for thread being destroyed\n", ptr);
2392 ALCcontext_DecRef(ptr);
2395 /* VerifyContext
2397 * Checks that the given context is valid, and increments its reference count.
2399 static ALCcontext *VerifyContext(ALCcontext *context)
2401 ALCdevice *dev;
2403 LockLists();
2404 dev = ATOMIC_LOAD(&DeviceList);
2405 while(dev)
2407 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2408 while(ctx)
2410 if(ctx == context)
2412 ALCcontext_IncRef(ctx);
2413 UnlockLists();
2414 return ctx;
2416 ctx = ctx->next;
2418 dev = dev->next;
2420 UnlockLists();
2422 return NULL;
2426 /* GetContextRef
2428 * Returns the currently active context for this thread, and adds a reference
2429 * without locking it.
2431 ALCcontext *GetContextRef(void)
2433 ALCcontext *context;
2435 context = altss_get(LocalContext);
2436 if(context)
2437 ALCcontext_IncRef(context);
2438 else
2440 LockLists();
2441 context = ATOMIC_LOAD(&GlobalContext);
2442 if(context)
2443 ALCcontext_IncRef(context);
2444 UnlockLists();
2447 return context;
2451 /************************************************
2452 * Standard ALC functions
2453 ************************************************/
2455 /* alcGetError
2457 * Return last ALC generated error code for the given device
2459 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2461 ALCenum errorCode;
2463 if(VerifyDevice(device))
2465 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2466 ALCdevice_DecRef(device);
2468 else
2469 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2471 return errorCode;
2475 /* alcSuspendContext
2477 * Suspends updates for the given context
2479 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2481 if(!SuspendDefers)
2482 return;
2484 context = VerifyContext(context);
2485 if(!context)
2486 alcSetError(NULL, ALC_INVALID_CONTEXT);
2487 else
2489 ALCcontext_DeferUpdates(context);
2490 ALCcontext_DecRef(context);
2494 /* alcProcessContext
2496 * Resumes processing updates for the given context
2498 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2500 if(!SuspendDefers)
2501 return;
2503 context = VerifyContext(context);
2504 if(!context)
2505 alcSetError(NULL, ALC_INVALID_CONTEXT);
2506 else
2508 ALCcontext_ProcessUpdates(context);
2509 ALCcontext_DecRef(context);
2514 /* alcGetString
2516 * Returns information about the device, and error strings
2518 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2520 const ALCchar *value = NULL;
2522 switch(param)
2524 case ALC_NO_ERROR:
2525 value = alcNoError;
2526 break;
2528 case ALC_INVALID_ENUM:
2529 value = alcErrInvalidEnum;
2530 break;
2532 case ALC_INVALID_VALUE:
2533 value = alcErrInvalidValue;
2534 break;
2536 case ALC_INVALID_DEVICE:
2537 value = alcErrInvalidDevice;
2538 break;
2540 case ALC_INVALID_CONTEXT:
2541 value = alcErrInvalidContext;
2542 break;
2544 case ALC_OUT_OF_MEMORY:
2545 value = alcErrOutOfMemory;
2546 break;
2548 case ALC_DEVICE_SPECIFIER:
2549 value = alcDefaultName;
2550 break;
2552 case ALC_ALL_DEVICES_SPECIFIER:
2553 if(VerifyDevice(Device))
2555 value = al_string_get_cstr(Device->DeviceName);
2556 ALCdevice_DecRef(Device);
2558 else
2560 ProbeAllDevicesList();
2561 value = al_string_get_cstr(alcAllDevicesList);
2563 break;
2565 case ALC_CAPTURE_DEVICE_SPECIFIER:
2566 if(VerifyDevice(Device))
2568 value = al_string_get_cstr(Device->DeviceName);
2569 ALCdevice_DecRef(Device);
2571 else
2573 ProbeCaptureDeviceList();
2574 value = al_string_get_cstr(alcCaptureDeviceList);
2576 break;
2578 /* Default devices are always first in the list */
2579 case ALC_DEFAULT_DEVICE_SPECIFIER:
2580 value = alcDefaultName;
2581 break;
2583 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2584 if(al_string_empty(alcAllDevicesList))
2585 ProbeAllDevicesList();
2587 Device = VerifyDevice(Device);
2589 free(alcDefaultAllDevicesSpecifier);
2590 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2591 if(!alcDefaultAllDevicesSpecifier)
2592 alcSetError(Device, ALC_OUT_OF_MEMORY);
2594 value = alcDefaultAllDevicesSpecifier;
2595 if(Device) ALCdevice_DecRef(Device);
2596 break;
2598 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2599 if(al_string_empty(alcCaptureDeviceList))
2600 ProbeCaptureDeviceList();
2602 Device = VerifyDevice(Device);
2604 free(alcCaptureDefaultDeviceSpecifier);
2605 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2606 if(!alcCaptureDefaultDeviceSpecifier)
2607 alcSetError(Device, ALC_OUT_OF_MEMORY);
2609 value = alcCaptureDefaultDeviceSpecifier;
2610 if(Device) ALCdevice_DecRef(Device);
2611 break;
2613 case ALC_EXTENSIONS:
2614 if(!VerifyDevice(Device))
2615 value = alcNoDeviceExtList;
2616 else
2618 value = alcExtensionList;
2619 ALCdevice_DecRef(Device);
2621 break;
2623 default:
2624 Device = VerifyDevice(Device);
2625 alcSetError(Device, ALC_INVALID_ENUM);
2626 if(Device) ALCdevice_DecRef(Device);
2627 break;
2630 return value;
2634 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2636 ALCsizei i;
2638 if(size <= 0 || values == NULL)
2640 alcSetError(device, ALC_INVALID_VALUE);
2641 return 0;
2644 if(!device)
2646 switch(param)
2648 case ALC_MAJOR_VERSION:
2649 values[0] = alcMajorVersion;
2650 return 1;
2651 case ALC_MINOR_VERSION:
2652 values[0] = alcMinorVersion;
2653 return 1;
2655 case ALC_ATTRIBUTES_SIZE:
2656 case ALC_ALL_ATTRIBUTES:
2657 case ALC_FREQUENCY:
2658 case ALC_REFRESH:
2659 case ALC_SYNC:
2660 case ALC_MONO_SOURCES:
2661 case ALC_STEREO_SOURCES:
2662 case ALC_CAPTURE_SAMPLES:
2663 case ALC_FORMAT_CHANNELS_SOFT:
2664 case ALC_FORMAT_TYPE_SOFT:
2665 alcSetError(NULL, ALC_INVALID_DEVICE);
2666 return 0;
2668 default:
2669 alcSetError(NULL, ALC_INVALID_ENUM);
2670 return 0;
2672 return 0;
2675 if(device->Type == Capture)
2677 switch(param)
2679 case ALC_CAPTURE_SAMPLES:
2680 V0(device->Backend,lock)();
2681 values[0] = V0(device->Backend,availableSamples)();
2682 V0(device->Backend,unlock)();
2683 return 1;
2685 case ALC_CONNECTED:
2686 values[0] = device->Connected;
2687 return 1;
2689 default:
2690 alcSetError(device, ALC_INVALID_ENUM);
2691 return 0;
2693 return 0;
2696 /* render device */
2697 switch(param)
2699 case ALC_MAJOR_VERSION:
2700 values[0] = alcMajorVersion;
2701 return 1;
2703 case ALC_MINOR_VERSION:
2704 values[0] = alcMinorVersion;
2705 return 1;
2707 case ALC_EFX_MAJOR_VERSION:
2708 values[0] = alcEFXMajorVersion;
2709 return 1;
2711 case ALC_EFX_MINOR_VERSION:
2712 values[0] = alcEFXMinorVersion;
2713 return 1;
2715 case ALC_ATTRIBUTES_SIZE:
2716 values[0] = 15;
2717 return 1;
2719 case ALC_ALL_ATTRIBUTES:
2720 if(size < 15)
2722 alcSetError(device, ALC_INVALID_VALUE);
2723 return 0;
2726 i = 0;
2727 values[i++] = ALC_FREQUENCY;
2728 values[i++] = device->Frequency;
2730 if(device->Type != Loopback)
2732 values[i++] = ALC_REFRESH;
2733 values[i++] = device->Frequency / device->UpdateSize;
2735 values[i++] = ALC_SYNC;
2736 values[i++] = ALC_FALSE;
2738 else
2740 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2741 values[i++] = device->FmtChans;
2743 values[i++] = ALC_FORMAT_TYPE_SOFT;
2744 values[i++] = device->FmtType;
2747 values[i++] = ALC_MONO_SOURCES;
2748 values[i++] = device->NumMonoSources;
2750 values[i++] = ALC_STEREO_SOURCES;
2751 values[i++] = device->NumStereoSources;
2753 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2754 values[i++] = device->NumAuxSends;
2756 values[i++] = ALC_HRTF_SOFT;
2757 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2759 values[i++] = 0;
2760 return i;
2762 case ALC_FREQUENCY:
2763 values[0] = device->Frequency;
2764 return 1;
2766 case ALC_REFRESH:
2767 if(device->Type == Loopback)
2769 alcSetError(device, ALC_INVALID_DEVICE);
2770 return 0;
2772 values[0] = device->Frequency / device->UpdateSize;
2773 return 1;
2775 case ALC_SYNC:
2776 if(device->Type == Loopback)
2778 alcSetError(device, ALC_INVALID_DEVICE);
2779 return 0;
2781 values[0] = ALC_FALSE;
2782 return 1;
2784 case ALC_FORMAT_CHANNELS_SOFT:
2785 if(device->Type != Loopback)
2787 alcSetError(device, ALC_INVALID_DEVICE);
2788 return 0;
2790 values[0] = device->FmtChans;
2791 return 1;
2793 case ALC_FORMAT_TYPE_SOFT:
2794 if(device->Type != Loopback)
2796 alcSetError(device, ALC_INVALID_DEVICE);
2797 return 0;
2799 values[0] = device->FmtType;
2800 return 1;
2802 case ALC_MONO_SOURCES:
2803 values[0] = device->NumMonoSources;
2804 return 1;
2806 case ALC_STEREO_SOURCES:
2807 values[0] = device->NumStereoSources;
2808 return 1;
2810 case ALC_MAX_AUXILIARY_SENDS:
2811 values[0] = device->NumAuxSends;
2812 return 1;
2814 case ALC_CONNECTED:
2815 values[0] = device->Connected;
2816 return 1;
2818 case ALC_HRTF_SOFT:
2819 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2820 return 1;
2822 default:
2823 alcSetError(device, ALC_INVALID_ENUM);
2824 return 0;
2826 return 0;
2829 /* alcGetIntegerv
2831 * Returns information about the device and the version of OpenAL
2833 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2835 device = VerifyDevice(device);
2836 if(size <= 0 || values == NULL)
2837 alcSetError(device, ALC_INVALID_VALUE);
2838 else
2839 GetIntegerv(device, param, size, values);
2840 if(device) ALCdevice_DecRef(device);
2843 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2845 ALCint *ivals;
2846 ALsizei i;
2848 device = VerifyDevice(device);
2849 if(size <= 0 || values == NULL)
2850 alcSetError(device, ALC_INVALID_VALUE);
2851 else if(!device || device->Type == Capture)
2853 ivals = malloc(size * sizeof(ALCint));
2854 size = GetIntegerv(device, pname, size, ivals);
2855 for(i = 0;i < size;i++)
2856 values[i] = ivals[i];
2857 free(ivals);
2859 else /* render device */
2861 switch(pname)
2863 case ALC_ATTRIBUTES_SIZE:
2864 *values = 17;
2865 break;
2867 case ALC_ALL_ATTRIBUTES:
2868 if(size < 17)
2869 alcSetError(device, ALC_INVALID_VALUE);
2870 else
2872 int i = 0;
2874 V0(device->Backend,lock)();
2875 values[i++] = ALC_FREQUENCY;
2876 values[i++] = device->Frequency;
2878 if(device->Type != Loopback)
2880 values[i++] = ALC_REFRESH;
2881 values[i++] = device->Frequency / device->UpdateSize;
2883 values[i++] = ALC_SYNC;
2884 values[i++] = ALC_FALSE;
2886 else
2888 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2889 values[i++] = device->FmtChans;
2891 values[i++] = ALC_FORMAT_TYPE_SOFT;
2892 values[i++] = device->FmtType;
2895 values[i++] = ALC_MONO_SOURCES;
2896 values[i++] = device->NumMonoSources;
2898 values[i++] = ALC_STEREO_SOURCES;
2899 values[i++] = device->NumStereoSources;
2901 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2902 values[i++] = device->NumAuxSends;
2904 values[i++] = ALC_HRTF_SOFT;
2905 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2907 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2908 values[i++] = device->ClockBase +
2909 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2911 values[i++] = 0;
2912 V0(device->Backend,unlock)();
2914 break;
2916 case ALC_DEVICE_CLOCK_SOFT:
2917 V0(device->Backend,lock)();
2918 *values = device->ClockBase +
2919 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2920 V0(device->Backend,unlock)();
2921 break;
2923 default:
2924 ivals = malloc(size * sizeof(ALCint));
2925 size = GetIntegerv(device, pname, size, ivals);
2926 for(i = 0;i < size;i++)
2927 values[i] = ivals[i];
2928 free(ivals);
2929 break;
2932 if(device)
2933 ALCdevice_DecRef(device);
2937 /* alcIsExtensionPresent
2939 * Determines if there is support for a particular extension
2941 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2943 ALCboolean bResult = ALC_FALSE;
2945 device = VerifyDevice(device);
2947 if(!extName)
2948 alcSetError(device, ALC_INVALID_VALUE);
2949 else
2951 size_t len = strlen(extName);
2952 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2953 while(ptr && *ptr)
2955 if(strncasecmp(ptr, extName, len) == 0 &&
2956 (ptr[len] == '\0' || isspace(ptr[len])))
2958 bResult = ALC_TRUE;
2959 break;
2961 if((ptr=strchr(ptr, ' ')) != NULL)
2963 do {
2964 ++ptr;
2965 } while(isspace(*ptr));
2969 if(device)
2970 ALCdevice_DecRef(device);
2971 return bResult;
2975 /* alcGetProcAddress
2977 * Retrieves the function address for a particular extension function
2979 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2981 ALCvoid *ptr = NULL;
2983 if(!funcName)
2985 device = VerifyDevice(device);
2986 alcSetError(device, ALC_INVALID_VALUE);
2987 if(device) ALCdevice_DecRef(device);
2989 else
2991 ALsizei i = 0;
2992 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
2993 i++;
2994 ptr = alcFunctions[i].address;
2997 return ptr;
3001 /* alcGetEnumValue
3003 * Get the value for a particular ALC enumeration name
3005 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3007 ALCenum val = 0;
3009 if(!enumName)
3011 device = VerifyDevice(device);
3012 alcSetError(device, ALC_INVALID_VALUE);
3013 if(device) ALCdevice_DecRef(device);
3015 else
3017 ALsizei i = 0;
3018 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3019 i++;
3020 val = enumeration[i].value;
3023 return val;
3027 /* alcCreateContext
3029 * Create and attach a context to the given device.
3031 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3033 ALCcontext *ALContext;
3034 ALCenum err;
3036 LockLists();
3037 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
3039 UnlockLists();
3040 alcSetError(device, ALC_INVALID_DEVICE);
3041 if(device) ALCdevice_DecRef(device);
3042 return NULL;
3045 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3047 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3049 UnlockLists();
3050 alcSetError(device, err);
3051 if(err == ALC_INVALID_DEVICE)
3053 V0(device->Backend,lock)();
3054 aluHandleDisconnect(device);
3055 V0(device->Backend,unlock)();
3057 ALCdevice_DecRef(device);
3058 return NULL;
3061 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3062 if(ALContext)
3064 InitRef(&ALContext->ref, 1);
3065 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3067 VECTOR_INIT(ALContext->ActiveAuxSlots);
3069 ALContext->VoiceCount = 0;
3070 ALContext->MaxVoices = 256;
3071 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3073 if(!ALContext || !ALContext->Voices)
3075 if(!ATOMIC_LOAD(&device->ContextList))
3077 V0(device->Backend,stop)();
3078 device->Flags &= ~DEVICE_RUNNING;
3080 UnlockLists();
3082 if(ALContext)
3084 al_free(ALContext->Voices);
3085 ALContext->Voices = NULL;
3087 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3089 al_free(ALContext);
3090 ALContext = NULL;
3093 alcSetError(device, ALC_OUT_OF_MEMORY);
3094 ALCdevice_DecRef(device);
3095 return NULL;
3098 ALContext->Device = device;
3099 ALCdevice_IncRef(device);
3100 InitContext(ALContext);
3103 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3104 do {
3105 ALContext->next = head;
3106 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3108 UnlockLists();
3110 ALCdevice_DecRef(device);
3112 TRACE("Created context %p\n", ALContext);
3113 return ALContext;
3116 /* alcDestroyContext
3118 * Remove a context from its device
3120 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3122 ALCdevice *Device;
3124 LockLists();
3125 /* alcGetContextsDevice sets an error for invalid contexts */
3126 Device = alcGetContextsDevice(context);
3127 if(Device)
3129 ReleaseContext(context, Device);
3130 if(!ATOMIC_LOAD(&Device->ContextList))
3132 V0(Device->Backend,stop)();
3133 Device->Flags &= ~DEVICE_RUNNING;
3136 UnlockLists();
3140 /* alcGetCurrentContext
3142 * Returns the currently active context on the calling thread
3144 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3146 ALCcontext *Context = altss_get(LocalContext);
3147 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3148 return Context;
3151 /* alcGetThreadContext
3153 * Returns the currently active thread-local context
3155 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3157 return altss_get(LocalContext);
3161 /* alcMakeContextCurrent
3163 * Makes the given context the active process-wide context, and removes the
3164 * thread-local context for the calling thread.
3166 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3168 /* context must be valid or NULL */
3169 if(context && !(context=VerifyContext(context)))
3171 alcSetError(NULL, ALC_INVALID_CONTEXT);
3172 return ALC_FALSE;
3174 /* context's reference count is already incremented */
3175 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3176 if(context) ALCcontext_DecRef(context);
3178 if((context=altss_get(LocalContext)) != NULL)
3180 altss_set(LocalContext, NULL);
3181 ALCcontext_DecRef(context);
3184 return ALC_TRUE;
3187 /* alcSetThreadContext
3189 * Makes the given context the active context for the current thread
3191 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3193 ALCcontext *old;
3195 /* context must be valid or NULL */
3196 if(context && !(context=VerifyContext(context)))
3198 alcSetError(NULL, ALC_INVALID_CONTEXT);
3199 return ALC_FALSE;
3201 /* context's reference count is already incremented */
3202 old = altss_get(LocalContext);
3203 altss_set(LocalContext, context);
3204 if(old) ALCcontext_DecRef(old);
3206 return ALC_TRUE;
3210 /* alcGetContextsDevice
3212 * Returns the device that a particular context is attached to
3214 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3216 ALCdevice *Device;
3218 if(!(Context=VerifyContext(Context)))
3220 alcSetError(NULL, ALC_INVALID_CONTEXT);
3221 return NULL;
3223 Device = Context->Device;
3224 ALCcontext_DecRef(Context);
3226 return Device;
3230 /* alcOpenDevice
3232 * Opens the named device.
3234 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3236 const ALCchar *fmt;
3237 ALCdevice *device;
3238 ALCenum err;
3240 DO_INITCONFIG();
3242 if(!PlaybackBackend.name)
3244 alcSetError(NULL, ALC_INVALID_VALUE);
3245 return NULL;
3248 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3249 deviceName = NULL;
3251 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3252 if(!device)
3254 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3255 return NULL;
3258 //Validate device
3259 InitRef(&device->ref, 1);
3260 device->Connected = ALC_TRUE;
3261 device->Type = Playback;
3262 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3264 device->Flags = 0;
3265 device->Bs2b = NULL;
3266 AL_STRING_INIT(device->DeviceName);
3267 device->DryBuffer = NULL;
3269 ATOMIC_INIT(&device->ContextList, NULL);
3271 device->ClockBase = 0;
3272 device->SamplesDone = 0;
3274 device->MaxNoOfSources = 256;
3275 device->AuxiliaryEffectSlotMax = 4;
3276 device->NumAuxSends = MAX_SENDS;
3278 InitUIntMap(&device->BufferMap, ~0);
3279 InitUIntMap(&device->EffectMap, ~0);
3280 InitUIntMap(&device->FilterMap, ~0);
3281 InitUIntMap(&device->SfontMap, ~0);
3282 InitUIntMap(&device->PresetMap, ~0);
3283 InitUIntMap(&device->FontsoundMap, ~0);
3285 //Set output format
3286 device->FmtChans = DevFmtChannelsDefault;
3287 device->FmtType = DevFmtTypeDefault;
3288 device->Frequency = DEFAULT_OUTPUT_RATE;
3289 device->IsHeadphones = AL_FALSE;
3290 device->NumUpdates = 4;
3291 device->UpdateSize = 1024;
3293 if(!PlaybackBackend.getFactory)
3294 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3295 ALCbackend_Playback);
3296 else
3298 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3299 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3301 if(!device->Backend)
3303 al_free(device);
3304 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3305 return NULL;
3309 if(ConfigValueStr(NULL, "channels", &fmt))
3311 static const struct {
3312 const char name[16];
3313 enum DevFmtChannels chans;
3314 } chanlist[] = {
3315 { "mono", DevFmtMono },
3316 { "stereo", DevFmtStereo },
3317 { "quad", DevFmtQuad },
3318 { "surround51", DevFmtX51 },
3319 { "surround61", DevFmtX61 },
3320 { "surround71", DevFmtX71 },
3321 { "surround51rear", DevFmtX51Rear },
3323 size_t i;
3325 for(i = 0;i < COUNTOF(chanlist);i++)
3327 if(strcasecmp(chanlist[i].name, fmt) == 0)
3329 device->FmtChans = chanlist[i].chans;
3330 device->Flags |= DEVICE_CHANNELS_REQUEST;
3331 break;
3334 if(i == COUNTOF(chanlist))
3335 ERR("Unsupported channels: %s\n", fmt);
3337 if(ConfigValueStr(NULL, "sample-type", &fmt))
3339 static const struct {
3340 const char name[16];
3341 enum DevFmtType type;
3342 } typelist[] = {
3343 { "int8", DevFmtByte },
3344 { "uint8", DevFmtUByte },
3345 { "int16", DevFmtShort },
3346 { "uint16", DevFmtUShort },
3347 { "int32", DevFmtInt },
3348 { "uint32", DevFmtUInt },
3349 { "float32", DevFmtFloat },
3351 size_t i;
3353 for(i = 0;i < COUNTOF(typelist);i++)
3355 if(strcasecmp(typelist[i].name, fmt) == 0)
3357 device->FmtType = typelist[i].type;
3358 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3359 break;
3362 if(i == COUNTOF(typelist))
3363 ERR("Unsupported sample-type: %s\n", fmt);
3366 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
3368 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3369 if(device->Frequency < MIN_OUTPUT_RATE)
3370 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3371 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3374 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
3375 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3377 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
3378 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3379 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3380 device->UpdateSize = (device->UpdateSize+3)&~3;
3382 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3383 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3385 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3386 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3388 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3389 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3391 device->NumStereoSources = 1;
3392 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3394 device->Synth = SynthCreate(device);
3395 if(!device->Synth)
3397 DELETE_OBJ(device->Backend);
3398 al_free(device);
3399 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3400 return NULL;
3403 // Find a playback device to open
3404 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3406 DELETE_OBJ(device->Synth);
3407 DELETE_OBJ(device->Backend);
3408 al_free(device);
3409 alcSetError(NULL, err);
3410 return NULL;
3413 if(DefaultEffect.type != AL_EFFECT_NULL)
3415 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3416 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3418 device->DefaultSlot = NULL;
3419 ERR("Failed to initialize the default effect slot\n");
3421 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3423 ALeffectState *state = device->DefaultSlot->EffectState;
3424 device->DefaultSlot = NULL;
3425 DELETE_OBJ(state);
3426 ERR("Failed to initialize the default effect\n");
3431 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3432 do {
3433 device->next = head;
3434 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3437 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3438 return device;
3441 /* alcCloseDevice
3443 * Closes the given device.
3445 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3447 ALCdevice *list, *origdev, *nextdev;
3448 ALCcontext *ctx;
3450 LockLists();
3451 list = ATOMIC_LOAD(&DeviceList);
3452 do {
3453 if(list == device)
3454 break;
3455 } while((list=list->next) != NULL);
3456 if(!list || list->Type == Capture)
3458 alcSetError(list, ALC_INVALID_DEVICE);
3459 UnlockLists();
3460 return ALC_FALSE;
3463 origdev = device;
3464 nextdev = device->next;
3465 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3467 do {
3468 list = origdev;
3469 origdev = device;
3470 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3472 UnlockLists();
3474 ctx = ATOMIC_LOAD(&device->ContextList);
3475 while(ctx != NULL)
3477 ALCcontext *next = ctx->next;
3478 WARN("Releasing context %p\n", ctx);
3479 ReleaseContext(ctx, device);
3480 ctx = next;
3482 if((device->Flags&DEVICE_RUNNING))
3483 V0(device->Backend,stop)();
3484 device->Flags &= ~DEVICE_RUNNING;
3486 ALCdevice_DecRef(device);
3488 return ALC_TRUE;
3492 /************************************************
3493 * ALC capture functions
3494 ************************************************/
3495 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3497 ALCdevice *device = NULL;
3498 ALCenum err;
3500 DO_INITCONFIG();
3502 if(!CaptureBackend.name)
3504 alcSetError(NULL, ALC_INVALID_VALUE);
3505 return NULL;
3508 if(samples <= 0)
3510 alcSetError(NULL, ALC_INVALID_VALUE);
3511 return NULL;
3514 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3515 deviceName = NULL;
3517 device = al_calloc(16, sizeof(ALCdevice));
3518 if(!device)
3520 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3521 return NULL;
3524 //Validate device
3525 InitRef(&device->ref, 1);
3526 device->Connected = ALC_TRUE;
3527 device->Type = Capture;
3529 AL_STRING_INIT(device->DeviceName);
3530 device->DryBuffer = NULL;
3532 InitUIntMap(&device->BufferMap, ~0);
3533 InitUIntMap(&device->EffectMap, ~0);
3534 InitUIntMap(&device->FilterMap, ~0);
3535 InitUIntMap(&device->SfontMap, ~0);
3536 InitUIntMap(&device->PresetMap, ~0);
3537 InitUIntMap(&device->FontsoundMap, ~0);
3539 if(!CaptureBackend.getFactory)
3540 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3541 ALCbackend_Capture);
3542 else
3544 ALCbackendFactory *factory = CaptureBackend.getFactory();
3545 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3547 if(!device->Backend)
3549 al_free(device);
3550 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3551 return NULL;
3554 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3555 device->Frequency = frequency;
3557 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3558 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3560 al_free(device);
3561 alcSetError(NULL, ALC_INVALID_ENUM);
3562 return NULL;
3564 device->IsHeadphones = AL_FALSE;
3566 device->UpdateSize = samples;
3567 device->NumUpdates = 1;
3569 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3571 al_free(device);
3572 alcSetError(NULL, err);
3573 return NULL;
3577 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3578 do {
3579 device->next = head;
3580 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3583 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3584 return device;
3587 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3589 ALCdevice *list, *next, *nextdev;
3591 LockLists();
3592 list = ATOMIC_LOAD(&DeviceList);
3593 do {
3594 if(list == device)
3595 break;
3596 } while((list=list->next) != NULL);
3597 if(!list || list->Type != Capture)
3599 alcSetError(list, ALC_INVALID_DEVICE);
3600 UnlockLists();
3601 return ALC_FALSE;
3604 next = device;
3605 nextdev = device->next;
3606 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3608 do {
3609 list = next;
3610 next = device;
3611 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3613 UnlockLists();
3615 ALCdevice_DecRef(device);
3617 return ALC_TRUE;
3620 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3622 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3623 alcSetError(device, ALC_INVALID_DEVICE);
3624 else
3626 V0(device->Backend,lock)();
3627 if(!device->Connected)
3628 alcSetError(device, ALC_INVALID_DEVICE);
3629 else if(!(device->Flags&DEVICE_RUNNING))
3631 if(V0(device->Backend,start)())
3632 device->Flags |= DEVICE_RUNNING;
3633 else
3635 aluHandleDisconnect(device);
3636 alcSetError(device, ALC_INVALID_DEVICE);
3639 V0(device->Backend,unlock)();
3642 if(device) ALCdevice_DecRef(device);
3645 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3647 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3648 alcSetError(device, ALC_INVALID_DEVICE);
3649 else
3651 V0(device->Backend,lock)();
3652 if((device->Flags&DEVICE_RUNNING))
3653 V0(device->Backend,stop)();
3654 device->Flags &= ~DEVICE_RUNNING;
3655 V0(device->Backend,unlock)();
3658 if(device) ALCdevice_DecRef(device);
3661 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3663 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3664 alcSetError(device, ALC_INVALID_DEVICE);
3665 else
3667 ALCenum err = ALC_INVALID_VALUE;
3669 V0(device->Backend,lock)();
3670 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3671 err = V(device->Backend,captureSamples)(buffer, samples);
3672 V0(device->Backend,unlock)();
3674 if(err != ALC_NO_ERROR)
3675 alcSetError(device, err);
3677 if(device) ALCdevice_DecRef(device);
3681 /************************************************
3682 * ALC loopback functions
3683 ************************************************/
3685 /* alcLoopbackOpenDeviceSOFT
3687 * Open a loopback device, for manual rendering.
3689 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3691 ALCbackendFactory *factory;
3692 ALCdevice *device;
3694 DO_INITCONFIG();
3696 /* Make sure the device name, if specified, is us. */
3697 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3699 alcSetError(NULL, ALC_INVALID_VALUE);
3700 return NULL;
3703 device = al_calloc(16, sizeof(ALCdevice));
3704 if(!device)
3706 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3707 return NULL;
3710 //Validate device
3711 InitRef(&device->ref, 1);
3712 device->Connected = ALC_TRUE;
3713 device->Type = Loopback;
3714 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3716 device->Flags = 0;
3717 device->Bs2b = NULL;
3718 AL_STRING_INIT(device->DeviceName);
3719 device->DryBuffer = NULL;
3721 ATOMIC_INIT(&device->ContextList, NULL);
3723 device->ClockBase = 0;
3724 device->SamplesDone = 0;
3726 device->MaxNoOfSources = 256;
3727 device->AuxiliaryEffectSlotMax = 4;
3728 device->NumAuxSends = MAX_SENDS;
3730 InitUIntMap(&device->BufferMap, ~0);
3731 InitUIntMap(&device->EffectMap, ~0);
3732 InitUIntMap(&device->FilterMap, ~0);
3733 InitUIntMap(&device->SfontMap, ~0);
3734 InitUIntMap(&device->PresetMap, ~0);
3735 InitUIntMap(&device->FontsoundMap, ~0);
3737 factory = ALCloopbackFactory_getFactory();
3738 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3739 if(!device->Backend)
3741 al_free(device);
3742 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3743 return NULL;
3746 //Set output format
3747 device->NumUpdates = 0;
3748 device->UpdateSize = 0;
3750 device->Frequency = DEFAULT_OUTPUT_RATE;
3751 device->FmtChans = DevFmtChannelsDefault;
3752 device->FmtType = DevFmtTypeDefault;
3753 device->IsHeadphones = AL_FALSE;
3755 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3756 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3758 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3759 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3761 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3762 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3764 device->NumStereoSources = 1;
3765 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3767 device->Synth = SynthCreate(device);
3768 if(!device->Synth)
3770 DELETE_OBJ(device->Backend);
3771 al_free(device);
3772 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3773 return NULL;
3776 // Open the "backend"
3777 V(device->Backend,open)("Loopback");
3780 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3781 do {
3782 device->next = head;
3783 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3786 TRACE("Created device %p\n", device);
3787 return device;
3790 /* alcIsRenderFormatSupportedSOFT
3792 * Determines if the loopback device supports the given format for rendering.
3794 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3796 ALCboolean ret = ALC_FALSE;
3798 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3799 alcSetError(device, ALC_INVALID_DEVICE);
3800 else if(freq <= 0)
3801 alcSetError(device, ALC_INVALID_VALUE);
3802 else
3804 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3805 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3806 freq >= MIN_OUTPUT_RATE)
3807 ret = ALC_TRUE;
3809 if(device) ALCdevice_DecRef(device);
3811 return ret;
3814 /* alcRenderSamplesSOFT
3816 * Renders some samples into a buffer, using the format last set by the
3817 * attributes given to alcCreateContext.
3819 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3821 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3822 alcSetError(device, ALC_INVALID_DEVICE);
3823 else if(samples < 0 || (samples > 0 && buffer == NULL))
3824 alcSetError(device, ALC_INVALID_VALUE);
3825 else
3826 aluMixData(device, buffer, samples);
3827 if(device) ALCdevice_DecRef(device);
3831 /************************************************
3832 * ALC DSP pause/resume functions
3833 ************************************************/
3835 /* alcDevicePauseSOFT
3837 * Pause the DSP to stop audio processing.
3839 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3841 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3842 alcSetError(device, ALC_INVALID_DEVICE);
3843 else
3845 LockLists();
3846 if((device->Flags&DEVICE_RUNNING))
3847 V0(device->Backend,stop)();
3848 device->Flags &= ~DEVICE_RUNNING;
3849 device->Flags |= DEVICE_PAUSED;
3850 UnlockLists();
3852 if(device) ALCdevice_DecRef(device);
3855 /* alcDeviceResumeSOFT
3857 * Resume the DSP to restart audio processing.
3859 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3861 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3862 alcSetError(device, ALC_INVALID_DEVICE);
3863 else
3865 LockLists();
3866 if((device->Flags&DEVICE_PAUSED))
3868 device->Flags &= ~DEVICE_PAUSED;
3869 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3871 if(V0(device->Backend,start)() != ALC_FALSE)
3872 device->Flags |= DEVICE_RUNNING;
3873 else
3875 alcSetError(device, ALC_INVALID_DEVICE);
3876 V0(device->Backend,lock)();
3877 aluHandleDisconnect(device);
3878 V0(device->Backend,unlock)();
3882 UnlockLists();
3884 if(device) ALCdevice_DecRef(device);