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