Rework HRTF decision logic
[openal-soft.git] / Alc / ALc.c
blob8b14746d33e703c92c17309e24fa9a1f24dca5e6
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include <ctype.h>
28 #include <signal.h>
30 #include "alMain.h"
31 #include "alSource.h"
32 #include "alListener.h"
33 #include "alThunk.h"
34 #include "alSource.h"
35 #include "alBuffer.h"
36 #include "alAuxEffectSlot.h"
37 #include "alError.h"
38 #include "alMidi.h"
39 #include "bs2b.h"
40 #include "alu.h"
42 #include "compat.h"
43 #include "threads.h"
44 #include "alstring.h"
46 #include "backends/base.h"
47 #include "midi/base.h"
50 /************************************************
51 * Backends
52 ************************************************/
53 struct BackendInfo {
54 const char *name;
55 ALCbackendFactory* (*getFactory)(void);
56 ALCboolean (*Init)(BackendFuncs*);
57 void (*Deinit)(void);
58 void (*Probe)(enum DevProbe);
59 BackendFuncs Funcs;
62 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
63 static struct BackendInfo BackendList[] = {
64 #ifdef HAVE_PULSEAUDIO
65 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
66 #endif
67 #ifdef HAVE_ALSA
68 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
69 #endif
70 #ifdef HAVE_COREAUDIO
71 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
72 #endif
73 #ifdef HAVE_OSS
74 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
75 #endif
76 #ifdef HAVE_SOLARIS
77 { "solaris", NULL, alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs },
78 #endif
79 #ifdef HAVE_SNDIO
80 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
81 #endif
82 #ifdef HAVE_QSA
83 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
84 #endif
85 #ifdef HAVE_MMDEVAPI
86 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
87 #endif
88 #ifdef HAVE_DSOUND
89 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
90 #endif
91 #ifdef HAVE_WINMM
92 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
93 #endif
94 #ifdef HAVE_PORTAUDIO
95 { "port", NULL, alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs },
96 #endif
97 #ifdef HAVE_OPENSL
98 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
99 #endif
101 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
102 #ifdef HAVE_WAVE
103 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
104 #endif
106 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
108 #undef EmptyFuncs
110 static struct BackendInfo PlaybackBackend;
111 static struct BackendInfo CaptureBackend;
114 /************************************************
115 * Functions, enums, and errors
116 ************************************************/
117 typedef struct ALCfunction {
118 const ALCchar *funcName;
119 ALCvoid *address;
120 } ALCfunction;
122 typedef struct ALCenums {
123 const ALCchar *enumName;
124 ALCenum value;
125 } ALCenums;
127 #define DECL(x) { #x, (ALCvoid*)(x) }
128 static const ALCfunction alcFunctions[] = {
129 DECL(alcCreateContext),
130 DECL(alcMakeContextCurrent),
131 DECL(alcProcessContext),
132 DECL(alcSuspendContext),
133 DECL(alcDestroyContext),
134 DECL(alcGetCurrentContext),
135 DECL(alcGetContextsDevice),
136 DECL(alcOpenDevice),
137 DECL(alcCloseDevice),
138 DECL(alcGetError),
139 DECL(alcIsExtensionPresent),
140 DECL(alcGetProcAddress),
141 DECL(alcGetEnumValue),
142 DECL(alcGetString),
143 DECL(alcGetIntegerv),
144 DECL(alcCaptureOpenDevice),
145 DECL(alcCaptureCloseDevice),
146 DECL(alcCaptureStart),
147 DECL(alcCaptureStop),
148 DECL(alcCaptureSamples),
150 DECL(alcSetThreadContext),
151 DECL(alcGetThreadContext),
153 DECL(alcLoopbackOpenDeviceSOFT),
154 DECL(alcIsRenderFormatSupportedSOFT),
155 DECL(alcRenderSamplesSOFT),
157 DECL(alcDevicePauseSOFT),
158 DECL(alcDeviceResumeSOFT),
160 DECL(alcGetInteger64vSOFT),
162 DECL(alEnable),
163 DECL(alDisable),
164 DECL(alIsEnabled),
165 DECL(alGetString),
166 DECL(alGetBooleanv),
167 DECL(alGetIntegerv),
168 DECL(alGetFloatv),
169 DECL(alGetDoublev),
170 DECL(alGetBoolean),
171 DECL(alGetInteger),
172 DECL(alGetFloat),
173 DECL(alGetDouble),
174 DECL(alGetError),
175 DECL(alIsExtensionPresent),
176 DECL(alGetProcAddress),
177 DECL(alGetEnumValue),
178 DECL(alListenerf),
179 DECL(alListener3f),
180 DECL(alListenerfv),
181 DECL(alListeneri),
182 DECL(alListener3i),
183 DECL(alListeneriv),
184 DECL(alGetListenerf),
185 DECL(alGetListener3f),
186 DECL(alGetListenerfv),
187 DECL(alGetListeneri),
188 DECL(alGetListener3i),
189 DECL(alGetListeneriv),
190 DECL(alGenSources),
191 DECL(alDeleteSources),
192 DECL(alIsSource),
193 DECL(alSourcef),
194 DECL(alSource3f),
195 DECL(alSourcefv),
196 DECL(alSourcei),
197 DECL(alSource3i),
198 DECL(alSourceiv),
199 DECL(alGetSourcef),
200 DECL(alGetSource3f),
201 DECL(alGetSourcefv),
202 DECL(alGetSourcei),
203 DECL(alGetSource3i),
204 DECL(alGetSourceiv),
205 DECL(alSourcePlayv),
206 DECL(alSourceStopv),
207 DECL(alSourceRewindv),
208 DECL(alSourcePausev),
209 DECL(alSourcePlay),
210 DECL(alSourceStop),
211 DECL(alSourceRewind),
212 DECL(alSourcePause),
213 DECL(alSourceQueueBuffers),
214 DECL(alSourceUnqueueBuffers),
215 DECL(alGenBuffers),
216 DECL(alDeleteBuffers),
217 DECL(alIsBuffer),
218 DECL(alBufferData),
219 DECL(alBufferf),
220 DECL(alBuffer3f),
221 DECL(alBufferfv),
222 DECL(alBufferi),
223 DECL(alBuffer3i),
224 DECL(alBufferiv),
225 DECL(alGetBufferf),
226 DECL(alGetBuffer3f),
227 DECL(alGetBufferfv),
228 DECL(alGetBufferi),
229 DECL(alGetBuffer3i),
230 DECL(alGetBufferiv),
231 DECL(alDopplerFactor),
232 DECL(alDopplerVelocity),
233 DECL(alSpeedOfSound),
234 DECL(alDistanceModel),
236 DECL(alGenFilters),
237 DECL(alDeleteFilters),
238 DECL(alIsFilter),
239 DECL(alFilteri),
240 DECL(alFilteriv),
241 DECL(alFilterf),
242 DECL(alFilterfv),
243 DECL(alGetFilteri),
244 DECL(alGetFilteriv),
245 DECL(alGetFilterf),
246 DECL(alGetFilterfv),
247 DECL(alGenEffects),
248 DECL(alDeleteEffects),
249 DECL(alIsEffect),
250 DECL(alEffecti),
251 DECL(alEffectiv),
252 DECL(alEffectf),
253 DECL(alEffectfv),
254 DECL(alGetEffecti),
255 DECL(alGetEffectiv),
256 DECL(alGetEffectf),
257 DECL(alGetEffectfv),
258 DECL(alGenAuxiliaryEffectSlots),
259 DECL(alDeleteAuxiliaryEffectSlots),
260 DECL(alIsAuxiliaryEffectSlot),
261 DECL(alAuxiliaryEffectSloti),
262 DECL(alAuxiliaryEffectSlotiv),
263 DECL(alAuxiliaryEffectSlotf),
264 DECL(alAuxiliaryEffectSlotfv),
265 DECL(alGetAuxiliaryEffectSloti),
266 DECL(alGetAuxiliaryEffectSlotiv),
267 DECL(alGetAuxiliaryEffectSlotf),
268 DECL(alGetAuxiliaryEffectSlotfv),
270 DECL(alBufferSubDataSOFT),
272 DECL(alBufferSamplesSOFT),
273 DECL(alBufferSubSamplesSOFT),
274 DECL(alGetBufferSamplesSOFT),
275 DECL(alIsBufferFormatSupportedSOFT),
277 DECL(alDeferUpdatesSOFT),
278 DECL(alProcessUpdatesSOFT),
280 DECL(alSourcedSOFT),
281 DECL(alSource3dSOFT),
282 DECL(alSourcedvSOFT),
283 DECL(alGetSourcedSOFT),
284 DECL(alGetSource3dSOFT),
285 DECL(alGetSourcedvSOFT),
286 DECL(alSourcei64SOFT),
287 DECL(alSource3i64SOFT),
288 DECL(alSourcei64vSOFT),
289 DECL(alGetSourcei64SOFT),
290 DECL(alGetSource3i64SOFT),
291 DECL(alGetSourcei64vSOFT),
293 DECL(alGenSoundfontsSOFT),
294 DECL(alDeleteSoundfontsSOFT),
295 DECL(alIsSoundfontSOFT),
296 DECL(alGetSoundfontivSOFT),
297 DECL(alSoundfontPresetsSOFT),
298 DECL(alGenPresetsSOFT),
299 DECL(alDeletePresetsSOFT),
300 DECL(alIsPresetSOFT),
301 DECL(alPresetiSOFT),
302 DECL(alPresetivSOFT),
303 DECL(alGetPresetivSOFT),
304 DECL(alPresetFontsoundsSOFT),
305 DECL(alGenFontsoundsSOFT),
306 DECL(alDeleteFontsoundsSOFT),
307 DECL(alIsFontsoundSOFT),
308 DECL(alFontsoundiSOFT),
309 DECL(alFontsound2iSOFT),
310 DECL(alFontsoundivSOFT),
311 DECL(alGetFontsoundivSOFT),
312 DECL(alFontsoundModulatoriSOFT),
313 DECL(alGetFontsoundModulatorivSOFT),
314 DECL(alMidiSoundfontSOFT),
315 DECL(alMidiSoundfontvSOFT),
316 DECL(alMidiEventSOFT),
317 DECL(alMidiSysExSOFT),
318 DECL(alMidiPlaySOFT),
319 DECL(alMidiPauseSOFT),
320 DECL(alMidiStopSOFT),
321 DECL(alMidiResetSOFT),
322 DECL(alMidiGainSOFT),
323 DECL(alGetInteger64SOFT),
324 DECL(alGetInteger64vSOFT),
325 DECL(alLoadSoundfontSOFT),
327 { NULL, NULL }
329 #undef DECL
331 #define DECL(x) { #x, (x) }
332 static const ALCenums enumeration[] = {
333 DECL(ALC_INVALID),
334 DECL(ALC_FALSE),
335 DECL(ALC_TRUE),
337 DECL(ALC_MAJOR_VERSION),
338 DECL(ALC_MINOR_VERSION),
339 DECL(ALC_ATTRIBUTES_SIZE),
340 DECL(ALC_ALL_ATTRIBUTES),
341 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
342 DECL(ALC_DEVICE_SPECIFIER),
343 DECL(ALC_ALL_DEVICES_SPECIFIER),
344 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
345 DECL(ALC_EXTENSIONS),
346 DECL(ALC_FREQUENCY),
347 DECL(ALC_REFRESH),
348 DECL(ALC_SYNC),
349 DECL(ALC_MONO_SOURCES),
350 DECL(ALC_STEREO_SOURCES),
351 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
352 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
353 DECL(ALC_CAPTURE_SAMPLES),
354 DECL(ALC_CONNECTED),
356 DECL(ALC_EFX_MAJOR_VERSION),
357 DECL(ALC_EFX_MINOR_VERSION),
358 DECL(ALC_MAX_AUXILIARY_SENDS),
360 DECL(ALC_FORMAT_CHANNELS_SOFT),
361 DECL(ALC_FORMAT_TYPE_SOFT),
363 DECL(ALC_MONO_SOFT),
364 DECL(ALC_STEREO_SOFT),
365 DECL(ALC_QUAD_SOFT),
366 DECL(ALC_5POINT1_SOFT),
367 DECL(ALC_6POINT1_SOFT),
368 DECL(ALC_7POINT1_SOFT),
370 DECL(ALC_BYTE_SOFT),
371 DECL(ALC_UNSIGNED_BYTE_SOFT),
372 DECL(ALC_SHORT_SOFT),
373 DECL(ALC_UNSIGNED_SHORT_SOFT),
374 DECL(ALC_INT_SOFT),
375 DECL(ALC_UNSIGNED_INT_SOFT),
376 DECL(ALC_FLOAT_SOFT),
378 DECL(ALC_NO_ERROR),
379 DECL(ALC_INVALID_DEVICE),
380 DECL(ALC_INVALID_CONTEXT),
381 DECL(ALC_INVALID_ENUM),
382 DECL(ALC_INVALID_VALUE),
383 DECL(ALC_OUT_OF_MEMORY),
386 DECL(AL_INVALID),
387 DECL(AL_NONE),
388 DECL(AL_FALSE),
389 DECL(AL_TRUE),
391 DECL(AL_SOURCE_RELATIVE),
392 DECL(AL_CONE_INNER_ANGLE),
393 DECL(AL_CONE_OUTER_ANGLE),
394 DECL(AL_PITCH),
395 DECL(AL_POSITION),
396 DECL(AL_DIRECTION),
397 DECL(AL_VELOCITY),
398 DECL(AL_LOOPING),
399 DECL(AL_BUFFER),
400 DECL(AL_GAIN),
401 DECL(AL_MIN_GAIN),
402 DECL(AL_MAX_GAIN),
403 DECL(AL_ORIENTATION),
404 DECL(AL_REFERENCE_DISTANCE),
405 DECL(AL_ROLLOFF_FACTOR),
406 DECL(AL_CONE_OUTER_GAIN),
407 DECL(AL_MAX_DISTANCE),
408 DECL(AL_SEC_OFFSET),
409 DECL(AL_SAMPLE_OFFSET),
410 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
411 DECL(AL_BYTE_OFFSET),
412 DECL(AL_BYTE_RW_OFFSETS_SOFT),
413 DECL(AL_SOURCE_TYPE),
414 DECL(AL_STATIC),
415 DECL(AL_STREAMING),
416 DECL(AL_UNDETERMINED),
417 DECL(AL_METERS_PER_UNIT),
418 DECL(AL_DIRECT_CHANNELS_SOFT),
420 DECL(AL_DIRECT_FILTER),
421 DECL(AL_AUXILIARY_SEND_FILTER),
422 DECL(AL_AIR_ABSORPTION_FACTOR),
423 DECL(AL_ROOM_ROLLOFF_FACTOR),
424 DECL(AL_CONE_OUTER_GAINHF),
425 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
426 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
427 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
429 DECL(AL_SOURCE_STATE),
430 DECL(AL_INITIAL),
431 DECL(AL_PLAYING),
432 DECL(AL_PAUSED),
433 DECL(AL_STOPPED),
435 DECL(AL_BUFFERS_QUEUED),
436 DECL(AL_BUFFERS_PROCESSED),
438 DECL(AL_FORMAT_MONO8),
439 DECL(AL_FORMAT_MONO16),
440 DECL(AL_FORMAT_MONO_FLOAT32),
441 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
442 DECL(AL_FORMAT_STEREO8),
443 DECL(AL_FORMAT_STEREO16),
444 DECL(AL_FORMAT_STEREO_FLOAT32),
445 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
446 DECL(AL_FORMAT_MONO_IMA4),
447 DECL(AL_FORMAT_STEREO_IMA4),
448 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
449 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
450 DECL(AL_FORMAT_QUAD8_LOKI),
451 DECL(AL_FORMAT_QUAD16_LOKI),
452 DECL(AL_FORMAT_QUAD8),
453 DECL(AL_FORMAT_QUAD16),
454 DECL(AL_FORMAT_QUAD32),
455 DECL(AL_FORMAT_51CHN8),
456 DECL(AL_FORMAT_51CHN16),
457 DECL(AL_FORMAT_51CHN32),
458 DECL(AL_FORMAT_61CHN8),
459 DECL(AL_FORMAT_61CHN16),
460 DECL(AL_FORMAT_61CHN32),
461 DECL(AL_FORMAT_71CHN8),
462 DECL(AL_FORMAT_71CHN16),
463 DECL(AL_FORMAT_71CHN32),
464 DECL(AL_FORMAT_REAR8),
465 DECL(AL_FORMAT_REAR16),
466 DECL(AL_FORMAT_REAR32),
467 DECL(AL_FORMAT_MONO_MULAW),
468 DECL(AL_FORMAT_MONO_MULAW_EXT),
469 DECL(AL_FORMAT_STEREO_MULAW),
470 DECL(AL_FORMAT_STEREO_MULAW_EXT),
471 DECL(AL_FORMAT_QUAD_MULAW),
472 DECL(AL_FORMAT_51CHN_MULAW),
473 DECL(AL_FORMAT_61CHN_MULAW),
474 DECL(AL_FORMAT_71CHN_MULAW),
475 DECL(AL_FORMAT_REAR_MULAW),
476 DECL(AL_FORMAT_MONO_ALAW_EXT),
477 DECL(AL_FORMAT_STEREO_ALAW_EXT),
479 DECL(AL_MONO8_SOFT),
480 DECL(AL_MONO16_SOFT),
481 DECL(AL_MONO32F_SOFT),
482 DECL(AL_STEREO8_SOFT),
483 DECL(AL_STEREO16_SOFT),
484 DECL(AL_STEREO32F_SOFT),
485 DECL(AL_QUAD8_SOFT),
486 DECL(AL_QUAD16_SOFT),
487 DECL(AL_QUAD32F_SOFT),
488 DECL(AL_REAR8_SOFT),
489 DECL(AL_REAR16_SOFT),
490 DECL(AL_REAR32F_SOFT),
491 DECL(AL_5POINT1_8_SOFT),
492 DECL(AL_5POINT1_16_SOFT),
493 DECL(AL_5POINT1_32F_SOFT),
494 DECL(AL_6POINT1_8_SOFT),
495 DECL(AL_6POINT1_16_SOFT),
496 DECL(AL_6POINT1_32F_SOFT),
497 DECL(AL_7POINT1_8_SOFT),
498 DECL(AL_7POINT1_16_SOFT),
499 DECL(AL_7POINT1_32F_SOFT),
500 DECL(AL_FORMAT_BFORMAT2D_8),
501 DECL(AL_FORMAT_BFORMAT2D_16),
502 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
503 DECL(AL_FORMAT_BFORMAT2D_MULAW),
504 DECL(AL_FORMAT_BFORMAT3D_8),
505 DECL(AL_FORMAT_BFORMAT3D_16),
506 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
507 DECL(AL_FORMAT_BFORMAT3D_MULAW),
509 DECL(AL_MONO_SOFT),
510 DECL(AL_STEREO_SOFT),
511 DECL(AL_QUAD_SOFT),
512 DECL(AL_REAR_SOFT),
513 DECL(AL_5POINT1_SOFT),
514 DECL(AL_6POINT1_SOFT),
515 DECL(AL_7POINT1_SOFT),
517 DECL(AL_BYTE_SOFT),
518 DECL(AL_UNSIGNED_BYTE_SOFT),
519 DECL(AL_SHORT_SOFT),
520 DECL(AL_UNSIGNED_SHORT_SOFT),
521 DECL(AL_INT_SOFT),
522 DECL(AL_UNSIGNED_INT_SOFT),
523 DECL(AL_FLOAT_SOFT),
524 DECL(AL_DOUBLE_SOFT),
525 DECL(AL_BYTE3_SOFT),
526 DECL(AL_UNSIGNED_BYTE3_SOFT),
528 DECL(AL_FREQUENCY),
529 DECL(AL_BITS),
530 DECL(AL_CHANNELS),
531 DECL(AL_SIZE),
532 DECL(AL_INTERNAL_FORMAT_SOFT),
533 DECL(AL_BYTE_LENGTH_SOFT),
534 DECL(AL_SAMPLE_LENGTH_SOFT),
535 DECL(AL_SEC_LENGTH_SOFT),
536 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
537 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
539 DECL(AL_UNUSED),
540 DECL(AL_PENDING),
541 DECL(AL_PROCESSED),
543 DECL(AL_NO_ERROR),
544 DECL(AL_INVALID_NAME),
545 DECL(AL_INVALID_ENUM),
546 DECL(AL_INVALID_VALUE),
547 DECL(AL_INVALID_OPERATION),
548 DECL(AL_OUT_OF_MEMORY),
550 DECL(AL_VENDOR),
551 DECL(AL_VERSION),
552 DECL(AL_RENDERER),
553 DECL(AL_EXTENSIONS),
555 DECL(AL_DOPPLER_FACTOR),
556 DECL(AL_DOPPLER_VELOCITY),
557 DECL(AL_DISTANCE_MODEL),
558 DECL(AL_SPEED_OF_SOUND),
559 DECL(AL_SOURCE_DISTANCE_MODEL),
560 DECL(AL_DEFERRED_UPDATES_SOFT),
562 DECL(AL_INVERSE_DISTANCE),
563 DECL(AL_INVERSE_DISTANCE_CLAMPED),
564 DECL(AL_LINEAR_DISTANCE),
565 DECL(AL_LINEAR_DISTANCE_CLAMPED),
566 DECL(AL_EXPONENT_DISTANCE),
567 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
569 DECL(AL_FILTER_TYPE),
570 DECL(AL_FILTER_NULL),
571 DECL(AL_FILTER_LOWPASS),
572 DECL(AL_FILTER_HIGHPASS),
573 DECL(AL_FILTER_BANDPASS),
575 DECL(AL_LOWPASS_GAIN),
576 DECL(AL_LOWPASS_GAINHF),
578 DECL(AL_HIGHPASS_GAIN),
579 DECL(AL_HIGHPASS_GAINLF),
581 DECL(AL_BANDPASS_GAIN),
582 DECL(AL_BANDPASS_GAINHF),
583 DECL(AL_BANDPASS_GAINLF),
585 DECL(AL_EFFECT_TYPE),
586 DECL(AL_EFFECT_NULL),
587 DECL(AL_EFFECT_REVERB),
588 DECL(AL_EFFECT_EAXREVERB),
589 DECL(AL_EFFECT_CHORUS),
590 DECL(AL_EFFECT_DISTORTION),
591 DECL(AL_EFFECT_ECHO),
592 DECL(AL_EFFECT_FLANGER),
593 #if 0
594 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
595 DECL(AL_EFFECT_VOCAL_MORPHER),
596 DECL(AL_EFFECT_PITCH_SHIFTER),
597 #endif
598 DECL(AL_EFFECT_RING_MODULATOR),
599 #if 0
600 DECL(AL_EFFECT_AUTOWAH),
601 #endif
602 DECL(AL_EFFECT_COMPRESSOR),
603 DECL(AL_EFFECT_EQUALIZER),
604 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
605 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
607 DECL(AL_EAXREVERB_DENSITY),
608 DECL(AL_EAXREVERB_DIFFUSION),
609 DECL(AL_EAXREVERB_GAIN),
610 DECL(AL_EAXREVERB_GAINHF),
611 DECL(AL_EAXREVERB_GAINLF),
612 DECL(AL_EAXREVERB_DECAY_TIME),
613 DECL(AL_EAXREVERB_DECAY_HFRATIO),
614 DECL(AL_EAXREVERB_DECAY_LFRATIO),
615 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
616 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
617 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
618 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
619 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
620 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
621 DECL(AL_EAXREVERB_ECHO_TIME),
622 DECL(AL_EAXREVERB_ECHO_DEPTH),
623 DECL(AL_EAXREVERB_MODULATION_TIME),
624 DECL(AL_EAXREVERB_MODULATION_DEPTH),
625 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
626 DECL(AL_EAXREVERB_HFREFERENCE),
627 DECL(AL_EAXREVERB_LFREFERENCE),
628 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
629 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
631 DECL(AL_REVERB_DENSITY),
632 DECL(AL_REVERB_DIFFUSION),
633 DECL(AL_REVERB_GAIN),
634 DECL(AL_REVERB_GAINHF),
635 DECL(AL_REVERB_DECAY_TIME),
636 DECL(AL_REVERB_DECAY_HFRATIO),
637 DECL(AL_REVERB_REFLECTIONS_GAIN),
638 DECL(AL_REVERB_REFLECTIONS_DELAY),
639 DECL(AL_REVERB_LATE_REVERB_GAIN),
640 DECL(AL_REVERB_LATE_REVERB_DELAY),
641 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
642 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
643 DECL(AL_REVERB_DECAY_HFLIMIT),
645 DECL(AL_CHORUS_WAVEFORM),
646 DECL(AL_CHORUS_PHASE),
647 DECL(AL_CHORUS_RATE),
648 DECL(AL_CHORUS_DEPTH),
649 DECL(AL_CHORUS_FEEDBACK),
650 DECL(AL_CHORUS_DELAY),
652 DECL(AL_DISTORTION_EDGE),
653 DECL(AL_DISTORTION_GAIN),
654 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
655 DECL(AL_DISTORTION_EQCENTER),
656 DECL(AL_DISTORTION_EQBANDWIDTH),
658 DECL(AL_ECHO_DELAY),
659 DECL(AL_ECHO_LRDELAY),
660 DECL(AL_ECHO_DAMPING),
661 DECL(AL_ECHO_FEEDBACK),
662 DECL(AL_ECHO_SPREAD),
664 DECL(AL_FLANGER_WAVEFORM),
665 DECL(AL_FLANGER_PHASE),
666 DECL(AL_FLANGER_RATE),
667 DECL(AL_FLANGER_DEPTH),
668 DECL(AL_FLANGER_FEEDBACK),
669 DECL(AL_FLANGER_DELAY),
671 DECL(AL_RING_MODULATOR_FREQUENCY),
672 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
673 DECL(AL_RING_MODULATOR_WAVEFORM),
675 #if 0
676 DECL(AL_AUTOWAH_ATTACK_TIME),
677 DECL(AL_AUTOWAH_PEAK_GAIN),
678 DECL(AL_AUTOWAH_RELEASE_TIME),
679 DECL(AL_AUTOWAH_RESONANCE),
680 #endif
682 DECL(AL_COMPRESSOR_ONOFF),
684 DECL(AL_EQUALIZER_LOW_GAIN),
685 DECL(AL_EQUALIZER_LOW_CUTOFF),
686 DECL(AL_EQUALIZER_MID1_GAIN),
687 DECL(AL_EQUALIZER_MID1_CENTER),
688 DECL(AL_EQUALIZER_MID1_WIDTH),
689 DECL(AL_EQUALIZER_MID2_GAIN),
690 DECL(AL_EQUALIZER_MID2_CENTER),
691 DECL(AL_EQUALIZER_MID2_WIDTH),
692 DECL(AL_EQUALIZER_HIGH_GAIN),
693 DECL(AL_EQUALIZER_HIGH_CUTOFF),
695 DECL(AL_DEDICATED_GAIN),
697 { NULL, (ALCenum)0 }
699 #undef DECL
701 static const ALCchar alcNoError[] = "No Error";
702 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
703 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
704 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
705 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
706 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
709 /************************************************
710 * Global variables
711 ************************************************/
713 /* Enumerated device names */
714 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
716 static al_string alcAllDevicesList;
717 static al_string alcCaptureDeviceList;
719 /* Default is always the first in the list */
720 static ALCchar *alcDefaultAllDevicesSpecifier;
721 static ALCchar *alcCaptureDefaultDeviceSpecifier;
723 /* Default context extensions */
724 static const ALchar alExtList[] =
725 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
726 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
727 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
728 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
729 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
730 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
731 "AL_SOFT_source_latency AL_SOFT_source_length";
733 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
735 /* Thread-local current context */
736 static altss_t LocalContext;
737 /* Process-wide current context */
738 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
740 /* Mixing thread piority level */
741 ALint RTPrioLevel;
743 FILE *LogFile;
744 #ifdef _DEBUG
745 enum LogLevel LogLevel = LogWarning;
746 #else
747 enum LogLevel LogLevel = LogError;
748 #endif
750 /* Flag to trap ALC device errors */
751 static ALCboolean TrapALCError = ALC_FALSE;
753 /* One-time configuration init control */
754 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
756 /* Default effect that applies to sources that don't have an effect on send 0 */
757 static ALeffect DefaultEffect;
759 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
760 * updates.
762 static ALCboolean SuspendDefers = ALC_TRUE;
765 /************************************************
766 * ALC information
767 ************************************************/
768 static const ALCchar alcNoDeviceExtList[] =
769 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
770 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
771 static const ALCchar alcExtensionList[] =
772 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
773 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
774 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
775 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
776 static const ALCint alcMajorVersion = 1;
777 static const ALCint alcMinorVersion = 1;
779 static const ALCint alcEFXMajorVersion = 1;
780 static const ALCint alcEFXMinorVersion = 0;
783 /************************************************
784 * Device lists
785 ************************************************/
786 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
788 static almtx_t ListLock;
789 static inline void LockLists(void)
791 int lockret = almtx_lock(&ListLock);
792 assert(lockret == althrd_success);
794 static inline void UnlockLists(void)
796 int unlockret = almtx_unlock(&ListLock);
797 assert(unlockret == althrd_success);
800 /************************************************
801 * Library initialization
802 ************************************************/
803 #if defined(_WIN32)
804 static void alc_init(void);
805 static void alc_deinit(void);
806 static void alc_deinit_safe(void);
808 #ifndef AL_LIBTYPE_STATIC
809 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
811 switch(reason)
813 case DLL_PROCESS_ATTACH:
814 /* Pin the DLL so we won't get unloaded until the process terminates */
815 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
816 (WCHAR*)hModule, &hModule);
817 alc_init();
818 break;
820 case DLL_THREAD_DETACH:
821 break;
823 case DLL_PROCESS_DETACH:
824 if(!lpReserved)
825 alc_deinit();
826 else
827 alc_deinit_safe();
828 break;
830 return TRUE;
832 #elif defined(_MSC_VER)
833 #pragma section(".CRT$XCU",read)
834 static void alc_constructor(void);
835 static void alc_destructor(void);
836 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
838 static void alc_constructor(void)
840 atexit(alc_destructor);
841 alc_init();
844 static void alc_destructor(void)
846 alc_deinit();
848 #elif defined(HAVE_GCC_DESTRUCTOR)
849 static void alc_init(void) __attribute__((constructor));
850 static void alc_deinit(void) __attribute__((destructor));
851 #else
852 #error "No static initialization available on this platform!"
853 #endif
855 #elif defined(HAVE_GCC_DESTRUCTOR)
857 static void alc_init(void) __attribute__((constructor));
858 static void alc_deinit(void) __attribute__((destructor));
860 #else
861 #error "No global initialization available on this platform!"
862 #endif
864 static void ReleaseThreadCtx(void *ptr);
865 static void alc_init(void)
867 const char *str;
868 int ret;
870 LogFile = stderr;
872 AL_STRING_INIT(alcAllDevicesList);
873 AL_STRING_INIT(alcCaptureDeviceList);
875 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
876 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
877 ConeScale *= 0.5f;
879 str = getenv("__ALSOFT_REVERSE_Z");
880 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
881 ZScale *= -1.0f;
883 ret = altss_create(&LocalContext, ReleaseThreadCtx);
884 assert(ret == althrd_success);
886 ret = almtx_init(&ListLock, almtx_recursive);
887 assert(ret == althrd_success);
889 ThunkInit();
892 static void alc_initconfig(void)
894 const char *devs, *str;
895 ALuint capfilter;
896 float valf;
897 int i, n;
899 str = getenv("ALSOFT_LOGLEVEL");
900 if(str)
902 long lvl = strtol(str, NULL, 0);
903 if(lvl >= NoLog && lvl <= LogRef)
904 LogLevel = lvl;
907 str = getenv("ALSOFT_LOGFILE");
908 if(str && str[0])
910 FILE *logfile = al_fopen(str, "wt");
911 if(logfile) LogFile = logfile;
912 else ERR("Failed to open log file '%s'\n", str);
916 char buf[1024] = "";
917 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
918 for(i = 1;BackendList[i].name;i++)
919 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
920 TRACE("Supported backends: %s\n", buf);
922 ReadALConfig();
924 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
925 if(str && *str)
927 if(strcasecmp(str, "ignore") == 0)
929 SuspendDefers = ALC_FALSE;
930 TRACE("Selected context suspend behavior, \"ignore\"\n");
932 else
933 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
936 capfilter = 0;
937 #if defined(HAVE_SSE4_1)
938 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE4_1;
939 #elif defined(HAVE_SSE2)
940 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
941 #elif defined(HAVE_SSE)
942 capfilter |= CPU_CAP_SSE;
943 #endif
944 #ifdef HAVE_NEON
945 capfilter |= CPU_CAP_NEON;
946 #endif
947 if(ConfigValueStr(NULL, "disable-cpu-exts", &str))
949 if(strcasecmp(str, "all") == 0)
950 capfilter = 0;
951 else
953 size_t len;
954 const char *next = str;
956 do {
957 str = next;
958 while(isspace(str[0]))
959 str++;
960 next = strchr(str, ',');
962 if(!str[0] || str[0] == ',')
963 continue;
965 len = (next ? ((size_t)(next-str)) : strlen(str));
966 while(len > 0 && isspace(str[len-1]))
967 len--;
968 if(len == 3 && strncasecmp(str, "sse", len) == 0)
969 capfilter &= ~CPU_CAP_SSE;
970 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
971 capfilter &= ~CPU_CAP_SSE2;
972 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
973 capfilter &= ~CPU_CAP_SSE4_1;
974 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
975 capfilter &= ~CPU_CAP_NEON;
976 else
977 WARN("Invalid CPU extension \"%s\"\n", str);
978 } while(next++);
981 FillCPUCaps(capfilter);
983 #ifdef _WIN32
984 RTPrioLevel = 1;
985 #else
986 RTPrioLevel = 0;
987 #endif
988 ConfigValueInt(NULL, "rt-prio", &RTPrioLevel);
990 if(ConfigValueStr(NULL, "resampler", &str))
992 if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
993 DefaultResampler = PointResampler;
994 else if(strcasecmp(str, "linear") == 0)
995 DefaultResampler = LinearResampler;
996 else if(strcasecmp(str, "cubic") == 0)
997 DefaultResampler = CubicResampler;
998 else
1000 char *end;
1002 n = strtol(str, &end, 0);
1003 if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == CubicResampler))
1004 DefaultResampler = n;
1005 else
1006 WARN("Invalid resampler: %s\n", str);
1010 str = getenv("ALSOFT_TRAP_ERROR");
1011 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1013 TrapALError = AL_TRUE;
1014 TrapALCError = AL_TRUE;
1016 else
1018 str = getenv("ALSOFT_TRAP_AL_ERROR");
1019 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1020 TrapALError = AL_TRUE;
1021 TrapALError = GetConfigValueBool(NULL, "trap-al-error", TrapALError);
1023 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1024 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1025 TrapALCError = ALC_TRUE;
1026 TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", TrapALCError);
1029 if(ConfigValueFloat("reverb", "boost", &valf))
1030 ReverbBoost *= powf(10.0f, valf / 20.0f);
1032 EmulateEAXReverb = GetConfigValueBool("reverb", "emulate-eax", AL_FALSE);
1034 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1035 ConfigValueStr(NULL, "drivers", &devs))
1037 int n;
1038 size_t len;
1039 const char *next = devs;
1040 int endlist, delitem;
1042 i = 0;
1043 do {
1044 devs = next;
1045 while(isspace(devs[0]))
1046 devs++;
1047 next = strchr(devs, ',');
1049 delitem = (devs[0] == '-');
1050 if(devs[0] == '-') devs++;
1052 if(!devs[0] || devs[0] == ',')
1054 endlist = 0;
1055 continue;
1057 endlist = 1;
1059 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1060 while(len > 0 && isspace(devs[len-1]))
1061 len--;
1062 for(n = i;BackendList[n].name;n++)
1064 if(len == strlen(BackendList[n].name) &&
1065 strncmp(BackendList[n].name, devs, len) == 0)
1067 if(delitem)
1069 do {
1070 BackendList[n] = BackendList[n+1];
1071 ++n;
1072 } while(BackendList[n].name);
1074 else
1076 struct BackendInfo Bkp = BackendList[n];
1077 while(n > i)
1079 BackendList[n] = BackendList[n-1];
1080 --n;
1082 BackendList[n] = Bkp;
1084 i++;
1086 break;
1089 } while(next++);
1091 if(endlist)
1093 BackendList[i].name = NULL;
1094 BackendList[i].getFactory = NULL;
1095 BackendList[i].Init = NULL;
1096 BackendList[i].Deinit = NULL;
1097 BackendList[i].Probe = NULL;
1101 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1103 if(BackendList[i].getFactory)
1105 ALCbackendFactory *factory = BackendList[i].getFactory();
1106 if(!V0(factory,init)())
1108 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1109 continue;
1112 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1113 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1115 PlaybackBackend = BackendList[i];
1116 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1118 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1120 CaptureBackend = BackendList[i];
1121 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1124 continue;
1127 if(!BackendList[i].Init(&BackendList[i].Funcs))
1129 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1130 continue;
1133 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1134 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1136 PlaybackBackend = BackendList[i];
1137 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1139 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1141 CaptureBackend = BackendList[i];
1142 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1146 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1147 V0(factory,init)();
1150 if(ConfigValueStr(NULL, "excludefx", &str))
1152 size_t len;
1153 const char *next = str;
1155 do {
1156 str = next;
1157 next = strchr(str, ',');
1159 if(!str[0] || next == str)
1160 continue;
1162 len = (next ? ((size_t)(next-str)) : strlen(str));
1163 for(n = 0;EffectList[n].name;n++)
1165 if(len == strlen(EffectList[n].name) &&
1166 strncmp(EffectList[n].name, str, len) == 0)
1167 DisabledEffects[EffectList[n].type] = AL_TRUE;
1169 } while(next++);
1172 InitEffectFactoryMap();
1174 InitEffect(&DefaultEffect);
1175 str = getenv("ALSOFT_DEFAULT_REVERB");
1176 if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str))
1177 LoadReverbPreset(str, &DefaultEffect);
1179 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1182 /************************************************
1183 * Library deinitialization
1184 ************************************************/
1185 static void alc_cleanup(void)
1187 ALCdevice *dev;
1189 AL_STRING_DEINIT(alcAllDevicesList);
1190 AL_STRING_DEINIT(alcCaptureDeviceList);
1192 free(alcDefaultAllDevicesSpecifier);
1193 alcDefaultAllDevicesSpecifier = NULL;
1194 free(alcCaptureDefaultDeviceSpecifier);
1195 alcCaptureDefaultDeviceSpecifier = NULL;
1197 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1199 ALCuint num = 0;
1200 do {
1201 num++;
1202 } while((dev=dev->next) != NULL);
1203 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1206 DeinitEffectFactoryMap();
1209 static void alc_deinit_safe(void)
1211 alc_cleanup();
1213 FreeHrtfs();
1214 FreeALConfig();
1216 ThunkExit();
1217 almtx_destroy(&ListLock);
1218 altss_delete(LocalContext);
1220 if(LogFile != stderr)
1221 fclose(LogFile);
1222 LogFile = NULL;
1225 static void alc_deinit(void)
1227 int i;
1229 alc_cleanup();
1231 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1232 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1234 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1236 if(!BackendList[i].getFactory)
1237 BackendList[i].Deinit();
1238 else
1240 ALCbackendFactory *factory = BackendList[i].getFactory();
1241 V0(factory,deinit)();
1245 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1246 V0(factory,deinit)();
1249 alc_deinit_safe();
1253 /************************************************
1254 * Device enumeration
1255 ************************************************/
1256 static void ProbeDevices(al_string *list, enum DevProbe type)
1258 DO_INITCONFIG();
1260 LockLists();
1261 al_string_clear(list);
1263 if(type == ALL_DEVICE_PROBE && (PlaybackBackend.Probe || PlaybackBackend.getFactory))
1265 if(!PlaybackBackend.getFactory)
1266 PlaybackBackend.Probe(type);
1267 else
1269 ALCbackendFactory *factory = PlaybackBackend.getFactory();
1270 V(factory,probe)(type);
1273 else if(type == CAPTURE_DEVICE_PROBE && (CaptureBackend.Probe || CaptureBackend.getFactory))
1275 if(!CaptureBackend.getFactory)
1276 CaptureBackend.Probe(type);
1277 else
1279 ALCbackendFactory *factory = CaptureBackend.getFactory();
1280 V(factory,probe)(type);
1283 UnlockLists();
1285 static void ProbeAllDevicesList(void)
1286 { ProbeDevices(&alcAllDevicesList, ALL_DEVICE_PROBE); }
1287 static void ProbeCaptureDeviceList(void)
1288 { ProbeDevices(&alcCaptureDeviceList, CAPTURE_DEVICE_PROBE); }
1290 static void AppendDevice(const ALCchar *name, al_string *devnames)
1292 size_t len = strlen(name);
1293 if(len > 0)
1294 al_string_append_range(devnames, name, name+len+1);
1296 void AppendAllDevicesList(const ALCchar *name)
1297 { AppendDevice(name, &alcAllDevicesList); }
1298 void AppendCaptureDeviceList(const ALCchar *name)
1299 { AppendDevice(name, &alcCaptureDeviceList); }
1302 /************************************************
1303 * Device format information
1304 ************************************************/
1305 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1307 switch(type)
1309 case DevFmtByte: return "Signed Byte";
1310 case DevFmtUByte: return "Unsigned Byte";
1311 case DevFmtShort: return "Signed Short";
1312 case DevFmtUShort: return "Unsigned Short";
1313 case DevFmtInt: return "Signed Int";
1314 case DevFmtUInt: return "Unsigned Int";
1315 case DevFmtFloat: return "Float";
1317 return "(unknown type)";
1319 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1321 switch(chans)
1323 case DevFmtMono: return "Mono";
1324 case DevFmtStereo: return "Stereo";
1325 case DevFmtQuad: return "Quadraphonic";
1326 case DevFmtX51: return "5.1 Surround";
1327 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1328 case DevFmtX61: return "6.1 Surround";
1329 case DevFmtX71: return "7.1 Surround";
1331 return "(unknown channels)";
1334 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1335 ALuint BytesFromDevFmt(enum DevFmtType type)
1337 switch(type)
1339 case DevFmtByte: return sizeof(ALbyte);
1340 case DevFmtUByte: return sizeof(ALubyte);
1341 case DevFmtShort: return sizeof(ALshort);
1342 case DevFmtUShort: return sizeof(ALushort);
1343 case DevFmtInt: return sizeof(ALint);
1344 case DevFmtUInt: return sizeof(ALuint);
1345 case DevFmtFloat: return sizeof(ALfloat);
1347 return 0;
1349 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1351 switch(chans)
1353 case DevFmtMono: return 1;
1354 case DevFmtStereo: return 2;
1355 case DevFmtQuad: return 4;
1356 case DevFmtX51: return 6;
1357 case DevFmtX51Rear: return 6;
1358 case DevFmtX61: return 7;
1359 case DevFmtX71: return 8;
1361 return 0;
1364 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1365 enum DevFmtChannels *chans, enum DevFmtType *type)
1367 static const struct {
1368 ALenum format;
1369 enum DevFmtChannels channels;
1370 enum DevFmtType type;
1371 } list[] = {
1372 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1373 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1374 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1376 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1377 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1378 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1380 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1381 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1382 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1384 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1385 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1386 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1388 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1389 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1390 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1392 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1393 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1394 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1396 ALuint i;
1398 for(i = 0;i < COUNTOF(list);i++)
1400 if(list[i].format == format)
1402 *chans = list[i].channels;
1403 *type = list[i].type;
1404 return AL_TRUE;
1408 return AL_FALSE;
1411 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1413 switch(type)
1415 case ALC_BYTE_SOFT:
1416 case ALC_UNSIGNED_BYTE_SOFT:
1417 case ALC_SHORT_SOFT:
1418 case ALC_UNSIGNED_SHORT_SOFT:
1419 case ALC_INT_SOFT:
1420 case ALC_UNSIGNED_INT_SOFT:
1421 case ALC_FLOAT_SOFT:
1422 return ALC_TRUE;
1424 return ALC_FALSE;
1427 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1429 switch(channels)
1431 case ALC_MONO_SOFT:
1432 case ALC_STEREO_SOFT:
1433 case ALC_QUAD_SOFT:
1434 case ALC_5POINT1_SOFT:
1435 case ALC_6POINT1_SOFT:
1436 case ALC_7POINT1_SOFT:
1437 return ALC_TRUE;
1439 return ALC_FALSE;
1443 /************************************************
1444 * Miscellaneous ALC helpers
1445 ************************************************/
1446 extern inline void LockContext(ALCcontext *context);
1447 extern inline void UnlockContext(ALCcontext *context);
1449 ALint64 ALCdevice_GetLatency(ALCdevice *device)
1451 return V0(device->Backend,getLatency)();
1454 void ALCdevice_Lock(ALCdevice *device)
1456 V0(device->Backend,lock)();
1459 void ALCdevice_Unlock(ALCdevice *device)
1461 V0(device->Backend,unlock)();
1465 /* SetDefaultWFXChannelOrder
1467 * Sets the default channel order used by WaveFormatEx.
1469 void SetDefaultWFXChannelOrder(ALCdevice *device)
1471 ALuint i;
1473 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1474 device->ChannelName[i] = InvalidChannel;
1476 switch(device->FmtChans)
1478 case DevFmtMono:
1479 device->ChannelName[0] = FrontCenter;
1480 break;
1481 case DevFmtStereo:
1482 device->ChannelName[0] = FrontLeft;
1483 device->ChannelName[1] = FrontRight;
1484 break;
1485 case DevFmtQuad:
1486 device->ChannelName[0] = FrontLeft;
1487 device->ChannelName[1] = FrontRight;
1488 device->ChannelName[2] = BackLeft;
1489 device->ChannelName[3] = BackRight;
1490 break;
1491 case DevFmtX51:
1492 device->ChannelName[0] = FrontLeft;
1493 device->ChannelName[1] = FrontRight;
1494 device->ChannelName[2] = FrontCenter;
1495 device->ChannelName[3] = LFE;
1496 device->ChannelName[4] = SideLeft;
1497 device->ChannelName[5] = SideRight;
1498 break;
1499 case DevFmtX51Rear:
1500 device->ChannelName[0] = FrontLeft;
1501 device->ChannelName[1] = FrontRight;
1502 device->ChannelName[2] = FrontCenter;
1503 device->ChannelName[3] = LFE;
1504 device->ChannelName[4] = BackLeft;
1505 device->ChannelName[5] = BackRight;
1506 break;
1507 case DevFmtX61:
1508 device->ChannelName[0] = FrontLeft;
1509 device->ChannelName[1] = FrontRight;
1510 device->ChannelName[2] = FrontCenter;
1511 device->ChannelName[3] = LFE;
1512 device->ChannelName[4] = BackCenter;
1513 device->ChannelName[5] = SideLeft;
1514 device->ChannelName[6] = SideRight;
1515 break;
1516 case DevFmtX71:
1517 device->ChannelName[0] = FrontLeft;
1518 device->ChannelName[1] = FrontRight;
1519 device->ChannelName[2] = FrontCenter;
1520 device->ChannelName[3] = LFE;
1521 device->ChannelName[4] = BackLeft;
1522 device->ChannelName[5] = BackRight;
1523 device->ChannelName[6] = SideLeft;
1524 device->ChannelName[7] = SideRight;
1525 break;
1529 /* SetDefaultChannelOrder
1531 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1533 void SetDefaultChannelOrder(ALCdevice *device)
1535 ALuint i;
1537 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1538 device->ChannelName[i] = InvalidChannel;
1540 switch(device->FmtChans)
1542 case DevFmtX51Rear:
1543 device->ChannelName[0] = FrontLeft;
1544 device->ChannelName[1] = FrontRight;
1545 device->ChannelName[2] = BackLeft;
1546 device->ChannelName[3] = BackRight;
1547 device->ChannelName[4] = FrontCenter;
1548 device->ChannelName[5] = LFE;
1549 return;
1550 case DevFmtX71:
1551 device->ChannelName[0] = FrontLeft;
1552 device->ChannelName[1] = FrontRight;
1553 device->ChannelName[2] = BackLeft;
1554 device->ChannelName[3] = BackRight;
1555 device->ChannelName[4] = FrontCenter;
1556 device->ChannelName[5] = LFE;
1557 device->ChannelName[6] = SideLeft;
1558 device->ChannelName[7] = SideRight;
1559 return;
1561 /* Same as WFX order */
1562 case DevFmtMono:
1563 case DevFmtStereo:
1564 case DevFmtQuad:
1565 case DevFmtX51:
1566 case DevFmtX61:
1567 SetDefaultWFXChannelOrder(device);
1568 break;
1572 extern inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan);
1575 /* ALCcontext_DeferUpdates
1577 * Defers/suspends updates for the given context's listener and sources. This
1578 * does *NOT* stop mixing, but rather prevents certain property changes from
1579 * taking effect.
1581 void ALCcontext_DeferUpdates(ALCcontext *context)
1583 ALCdevice *device = context->Device;
1584 FPUCtl oldMode;
1586 SetMixerFPUMode(&oldMode);
1588 V0(device->Backend,lock)();
1589 if(!ExchangeInt(&context->DeferUpdates, AL_TRUE))
1591 ALboolean UpdateSources;
1592 ALvoice *voice, *voice_end;
1593 ALeffectslot **slot, **slot_end;
1594 /* Make sure all pending updates are performed */
1595 UpdateSources = ATOMIC_EXCHANGE(ALenum, &context->UpdateSources, AL_FALSE);
1597 voice = context->Voices;
1598 voice_end = voice + context->VoiceCount;
1599 while(voice != voice_end)
1601 ALsource *source = voice->Source;
1602 if(!source) goto next;
1604 if(source->state != AL_PLAYING && source->state != AL_PAUSED)
1606 voice->Source = NULL;
1607 goto next;
1610 if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || UpdateSources)
1611 voice->Update(voice, source, context);
1612 next:
1613 voice++;
1616 slot = VECTOR_ITER_BEGIN(context->ActiveAuxSlots);
1617 slot_end = VECTOR_ITER_END(context->ActiveAuxSlots);
1618 while(slot != slot_end)
1620 if(ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE))
1621 V((*slot)->EffectState,update)(context->Device, *slot);
1622 slot++;
1625 V0(device->Backend,unlock)();
1627 RestoreFPUMode(&oldMode);
1630 /* ALCcontext_ProcessUpdates
1632 * Resumes update processing after being deferred.
1634 void ALCcontext_ProcessUpdates(ALCcontext *context)
1636 ALCdevice *device = context->Device;
1638 V0(device->Backend,lock)();
1639 if(ExchangeInt(&context->DeferUpdates, AL_FALSE))
1641 ALsizei pos;
1643 LockUIntMapRead(&context->SourceMap);
1644 for(pos = 0;pos < context->SourceMap.size;pos++)
1646 ALsource *Source = context->SourceMap.array[pos].value;
1647 ALenum new_state;
1649 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1650 Source->Offset >= 0.0)
1652 ReadLock(&Source->queue_lock);
1653 ApplyOffset(Source);
1654 ReadUnlock(&Source->queue_lock);
1657 new_state = ExchangeInt(&Source->new_state, AL_NONE);
1658 if(new_state)
1659 SetSourceState(Source, context, new_state);
1661 UnlockUIntMapRead(&context->SourceMap);
1663 V0(device->Backend,unlock)();
1667 /* alcSetError
1669 * Stores the latest ALC device error
1671 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1673 if(TrapALCError)
1675 #ifdef _WIN32
1676 /* DebugBreak() will cause an exception if there is no debugger */
1677 if(IsDebuggerPresent())
1678 DebugBreak();
1679 #elif defined(SIGTRAP)
1680 raise(SIGTRAP);
1681 #endif
1684 if(device)
1685 ATOMIC_STORE(&device->LastError, errorCode);
1686 else
1687 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1691 /* UpdateClockBase
1693 * Updates the device's base clock time with however many samples have been
1694 * done. This is used so frequency changes on the device don't cause the time
1695 * to jump forward or back.
1697 static inline void UpdateClockBase(ALCdevice *device)
1699 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1700 device->SamplesDone = 0;
1703 /* UpdateDeviceParams
1705 * Updates device parameters according to the attribute list (caller is
1706 * responsible for holding the list lock).
1708 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1710 ALCcontext *context;
1711 enum DevFmtChannels oldChans;
1712 enum DevFmtType oldType;
1713 ALCuint oldFreq;
1714 FPUCtl oldMode;
1715 size_t size;
1717 // Check for attributes
1718 if(device->Type == Loopback)
1720 enum {
1721 GotFreq = 1<<0,
1722 GotChans = 1<<1,
1723 GotType = 1<<2,
1724 GotAll = GotFreq|GotChans|GotType
1726 ALCuint freq, numMono, numStereo, numSends, flags;
1727 enum DevFmtChannels schans;
1728 enum DevFmtType stype;
1729 ALCuint attrIdx = 0;
1730 ALCint gotFmt = 0;
1732 if(!attrList)
1734 WARN("Missing attributes for loopback device\n");
1735 return ALC_INVALID_VALUE;
1738 numMono = device->NumMonoSources;
1739 numStereo = device->NumStereoSources;
1740 numSends = device->NumAuxSends;
1741 schans = device->FmtChans;
1742 stype = device->FmtType;
1743 freq = device->Frequency;
1744 flags = device->Flags;
1746 while(attrList[attrIdx])
1748 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1750 ALCint val = attrList[attrIdx + 1];
1751 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1752 return ALC_INVALID_VALUE;
1753 schans = val;
1754 gotFmt |= GotChans;
1757 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1759 ALCint val = attrList[attrIdx + 1];
1760 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1761 return ALC_INVALID_VALUE;
1762 stype = val;
1763 gotFmt |= GotType;
1766 if(attrList[attrIdx] == ALC_FREQUENCY)
1768 freq = attrList[attrIdx + 1];
1769 if(freq < MIN_OUTPUT_RATE)
1770 return ALC_INVALID_VALUE;
1771 gotFmt |= GotFreq;
1774 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1776 numStereo = attrList[attrIdx + 1];
1777 if(numStereo > device->MaxNoOfSources)
1778 numStereo = device->MaxNoOfSources;
1780 numMono = device->MaxNoOfSources - numStereo;
1783 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1784 numSends = attrList[attrIdx + 1];
1786 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1788 if(attrList[attrIdx + 1] != ALC_FALSE)
1789 flags |= DEVICE_HRTF_REQUEST;
1790 else
1791 flags &= ~DEVICE_HRTF_REQUEST;
1794 attrIdx += 2;
1797 if(gotFmt != GotAll)
1799 WARN("Missing format for loopback device\n");
1800 return ALC_INVALID_VALUE;
1803 ConfigValueUInt(NULL, "sends", &numSends);
1804 numSends = minu(MAX_SENDS, numSends);
1806 if((device->Flags&DEVICE_RUNNING))
1807 V0(device->Backend,stop)();
1808 device->Flags = (flags & ~DEVICE_RUNNING);
1810 UpdateClockBase(device);
1812 device->Frequency = freq;
1813 device->FmtChans = schans;
1814 device->FmtType = stype;
1815 device->NumMonoSources = numMono;
1816 device->NumStereoSources = numStereo;
1817 device->NumAuxSends = numSends;
1819 else if(attrList && attrList[0])
1821 ALCuint freq, numMono, numStereo, numSends;
1822 ALCuint attrIdx = 0;
1824 /* If a context is already running on the device, stop playback so the
1825 * device attributes can be updated. */
1826 if((device->Flags&DEVICE_RUNNING))
1827 V0(device->Backend,stop)();
1828 device->Flags &= ~DEVICE_RUNNING;
1830 freq = device->Frequency;
1831 numMono = device->NumMonoSources;
1832 numStereo = device->NumStereoSources;
1833 numSends = device->NumAuxSends;
1835 while(attrList[attrIdx])
1837 if(attrList[attrIdx] == ALC_FREQUENCY)
1839 freq = attrList[attrIdx + 1];
1840 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1843 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1845 numStereo = attrList[attrIdx + 1];
1846 if(numStereo > device->MaxNoOfSources)
1847 numStereo = device->MaxNoOfSources;
1849 numMono = device->MaxNoOfSources - numStereo;
1852 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1853 numSends = attrList[attrIdx + 1];
1855 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1857 if(attrList[attrIdx + 1] != ALC_FALSE)
1858 device->Flags |= DEVICE_HRTF_REQUEST;
1859 else
1860 device->Flags &= ~DEVICE_HRTF_REQUEST;
1863 attrIdx += 2;
1866 ConfigValueUInt(NULL, "frequency", &freq);
1867 freq = maxu(freq, MIN_OUTPUT_RATE);
1869 ConfigValueUInt(NULL, "sends", &numSends);
1870 numSends = minu(MAX_SENDS, numSends);
1872 UpdateClockBase(device);
1874 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1875 device->Frequency;
1876 /* SSE and Neon do best with the update size being a multiple of 4 */
1877 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1878 device->UpdateSize = (device->UpdateSize+3)&~3;
1880 device->Frequency = freq;
1881 device->NumMonoSources = numMono;
1882 device->NumStereoSources = numStereo;
1883 device->NumAuxSends = numSends;
1886 if((device->Flags&DEVICE_RUNNING))
1887 return ALC_NO_ERROR;
1889 al_free(device->DryBuffer);
1890 device->DryBuffer = NULL;
1892 UpdateClockBase(device);
1894 if((device->Flags&DEVICE_HRTF_REQUEST))
1896 if(device->Type != Loopback)
1898 if(!FindHrtfFormat(&device->FmtChans, &device->Frequency))
1899 device->Flags &= ~DEVICE_HRTF_REQUEST;
1900 else
1901 device->Flags |= DEVICE_CHANNELS_REQUEST |
1902 DEVICE_FREQUENCY_REQUEST;
1904 else
1906 enum DevFmtChannels chans = device->FmtChans;
1907 ALCuint freq = device->Frequency;
1908 if(!FindHrtfFormat(&chans, &freq) || chans != device->FmtChans || freq != device->Frequency)
1910 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1911 DevFmtChannelsString(device->FmtChans), device->Frequency);
1912 device->Flags &= ~DEVICE_HRTF_REQUEST;
1917 oldFreq = device->Frequency;
1918 oldChans = device->FmtChans;
1919 oldType = device->FmtType;
1921 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1922 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1923 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1924 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1925 device->UpdateSize, device->NumUpdates
1928 if(V0(device->Backend,reset)() == ALC_FALSE)
1929 return ALC_INVALID_DEVICE;
1931 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1933 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1934 DevFmtChannelsString(device->FmtChans));
1935 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1937 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1939 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1940 DevFmtTypeString(device->FmtType));
1941 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1943 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1945 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1946 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1949 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1950 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1951 device->Frequency, device->UpdateSize, device->NumUpdates
1954 if((device->UpdateSize&3) != 0)
1956 if((CPUCapFlags&CPU_CAP_SSE))
1957 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1958 if((CPUCapFlags&CPU_CAP_NEON))
1959 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1962 device->Hrtf = NULL;
1963 if(device->FmtChans != DevFmtStereo)
1965 TRACE("HRTF %s\n", "disabled");
1966 free(device->Bs2b);
1967 device->Bs2b = NULL;
1968 TRACE("BS2B disabled\n");
1970 else
1972 bool headphones = false;
1973 const char *mode;
1974 int usehrtf;
1976 if(ConfigValueStr(NULL, "stereo-mode", &mode))
1978 if(strcasecmp(mode, "headphones") == 0)
1979 headphones = true;
1980 else if(strcasecmp(mode, "speakers") == 0)
1981 headphones = false;
1982 else if(strcasecmp(mode, "auto") != 0)
1983 ERR("Unexpected stereo-mode: %s\n", mode);
1986 if(!ConfigValueBool(NULL, "hrtf", &usehrtf))
1987 usehrtf = ((device->Flags&DEVICE_HRTF_REQUEST) || headphones);
1989 if(usehrtf)
1990 device->Hrtf = GetHrtf(device->FmtChans, device->Frequency);
1991 if(!device->Hrtf)
1992 device->Flags &= ~DEVICE_HRTF_REQUEST;
1993 TRACE("HRTF %s\n", device->Hrtf?"enabled":"disabled");
1995 if(!device->Hrtf && device->Bs2bLevel > 0 && device->Bs2bLevel <= 6)
1997 if(!device->Bs2b)
1999 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
2000 bs2b_clear(device->Bs2b);
2002 bs2b_set_srate(device->Bs2b, device->Frequency);
2003 bs2b_set_level(device->Bs2b, device->Bs2bLevel);
2004 TRACE("BS2B level %d\n", device->Bs2bLevel);
2006 else
2008 free(device->Bs2b);
2009 device->Bs2b = NULL;
2010 TRACE("BS2B disabled\n");
2014 aluInitPanning(device);
2016 /* With HRTF enabled, the channels are virtual and get positioned around
2017 * the virtual listener. Two extra channels are allocated for the actual
2018 * HRTF-filtered output.
2020 size = sizeof(device->DryBuffer[0]) * (device->NumChannels + (device->Hrtf ? 2 : 0));
2021 device->DryBuffer = al_calloc(16, size);
2022 if(!device->DryBuffer)
2024 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2025 return ALC_INVALID_DEVICE;
2028 V(device->Synth,update)(device);
2030 SetMixerFPUMode(&oldMode);
2031 V0(device->Backend,lock)();
2032 context = ATOMIC_LOAD(&device->ContextList);
2033 while(context)
2035 ALsizei pos;
2037 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2038 LockUIntMapRead(&context->EffectSlotMap);
2039 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2041 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2043 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2045 UnlockUIntMapRead(&context->EffectSlotMap);
2046 V0(device->Backend,unlock)();
2047 RestoreFPUMode(&oldMode);
2048 return ALC_INVALID_DEVICE;
2050 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2051 V(slot->EffectState,update)(device, slot);
2053 UnlockUIntMapRead(&context->EffectSlotMap);
2055 LockUIntMapRead(&context->SourceMap);
2056 for(pos = 0;pos < context->SourceMap.size;pos++)
2058 ALsource *source = context->SourceMap.array[pos].value;
2059 ALuint s = device->NumAuxSends;
2060 while(s < MAX_SENDS)
2062 if(source->Send[s].Slot)
2063 DecrementRef(&source->Send[s].Slot->ref);
2064 source->Send[s].Slot = NULL;
2065 source->Send[s].Gain = 1.0f;
2066 source->Send[s].GainHF = 1.0f;
2067 s++;
2069 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2071 UnlockUIntMapRead(&context->SourceMap);
2073 for(pos = 0;pos < context->VoiceCount;pos++)
2075 ALvoice *voice = &context->Voices[pos];
2076 ALsource *source = voice->Source;
2077 ALuint s = device->NumAuxSends;
2079 while(s < MAX_SENDS)
2081 voice->Send[s].Moving = AL_FALSE;
2082 voice->Send[s].Counter = 0;
2083 s++;
2086 if(source)
2088 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2089 voice->Update(voice, source, context);
2093 context = context->next;
2095 if(device->DefaultSlot)
2097 ALeffectslot *slot = device->DefaultSlot;
2099 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2101 V0(device->Backend,unlock)();
2102 RestoreFPUMode(&oldMode);
2103 return ALC_INVALID_DEVICE;
2105 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2106 V(slot->EffectState,update)(device, slot);
2108 V0(device->Backend,unlock)();
2109 RestoreFPUMode(&oldMode);
2111 if(!(device->Flags&DEVICE_PAUSED))
2113 if(V0(device->Backend,start)() == ALC_FALSE)
2114 return ALC_INVALID_DEVICE;
2115 device->Flags |= DEVICE_RUNNING;
2118 return ALC_NO_ERROR;
2121 /* FreeDevice
2123 * Frees the device structure, and destroys any objects the app failed to
2124 * delete. Called once there's no more references on the device.
2126 static ALCvoid FreeDevice(ALCdevice *device)
2128 TRACE("%p\n", device);
2130 V0(device->Backend,close)();
2131 DELETE_OBJ(device->Backend);
2132 device->Backend = NULL;
2134 DELETE_OBJ(device->Synth);
2135 device->Synth = NULL;
2137 if(device->DefaultSlot)
2139 ALeffectState *state = device->DefaultSlot->EffectState;
2140 device->DefaultSlot = NULL;
2141 DELETE_OBJ(state);
2144 if(device->DefaultSfont)
2145 ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
2146 device->DefaultSfont = NULL;
2148 if(device->BufferMap.size > 0)
2150 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2151 ReleaseALBuffers(device);
2153 ResetUIntMap(&device->BufferMap);
2155 if(device->EffectMap.size > 0)
2157 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2158 ReleaseALEffects(device);
2160 ResetUIntMap(&device->EffectMap);
2162 if(device->FilterMap.size > 0)
2164 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2165 ReleaseALFilters(device);
2167 ResetUIntMap(&device->FilterMap);
2169 if(device->SfontMap.size > 0)
2171 WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size);
2172 ReleaseALSoundfonts(device);
2174 ResetUIntMap(&device->SfontMap);
2176 if(device->PresetMap.size > 0)
2178 WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size);
2179 ReleaseALPresets(device);
2181 ResetUIntMap(&device->PresetMap);
2183 if(device->FontsoundMap.size > 0)
2185 WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size);
2186 ReleaseALFontsounds(device);
2188 ResetUIntMap(&device->FontsoundMap);
2190 free(device->Bs2b);
2191 device->Bs2b = NULL;
2193 AL_STRING_DEINIT(device->DeviceName);
2195 al_free(device->DryBuffer);
2196 device->DryBuffer = NULL;
2198 al_free(device);
2202 void ALCdevice_IncRef(ALCdevice *device)
2204 uint ref;
2205 ref = IncrementRef(&device->ref);
2206 TRACEREF("%p increasing refcount to %u\n", device, ref);
2209 void ALCdevice_DecRef(ALCdevice *device)
2211 uint ref;
2212 ref = DecrementRef(&device->ref);
2213 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2214 if(ref == 0) FreeDevice(device);
2217 /* VerifyDevice
2219 * Checks if the device handle is valid, and increments its ref count if so.
2221 static ALCdevice *VerifyDevice(ALCdevice *device)
2223 ALCdevice *tmpDevice;
2225 if(!device)
2226 return NULL;
2228 LockLists();
2229 tmpDevice = ATOMIC_LOAD(&DeviceList);
2230 while(tmpDevice && tmpDevice != device)
2231 tmpDevice = tmpDevice->next;
2233 if(tmpDevice)
2234 ALCdevice_IncRef(tmpDevice);
2235 UnlockLists();
2236 return tmpDevice;
2240 /* InitContext
2242 * Initializes context fields
2244 static ALvoid InitContext(ALCcontext *Context)
2246 ALint i, j;
2248 //Initialise listener
2249 Context->Listener->Gain = 1.0f;
2250 Context->Listener->MetersPerUnit = 1.0f;
2251 Context->Listener->Position[0] = 0.0f;
2252 Context->Listener->Position[1] = 0.0f;
2253 Context->Listener->Position[2] = 0.0f;
2254 Context->Listener->Velocity[0] = 0.0f;
2255 Context->Listener->Velocity[1] = 0.0f;
2256 Context->Listener->Velocity[2] = 0.0f;
2257 Context->Listener->Forward[0] = 0.0f;
2258 Context->Listener->Forward[1] = 0.0f;
2259 Context->Listener->Forward[2] = -1.0f;
2260 Context->Listener->Up[0] = 0.0f;
2261 Context->Listener->Up[1] = 1.0f;
2262 Context->Listener->Up[2] = 0.0f;
2263 for(i = 0;i < 4;i++)
2265 for(j = 0;j < 4;j++)
2266 Context->Listener->Params.Matrix[i][j] = ((i==j) ? 1.0f : 0.0f);
2268 for(i = 0;i < 3;i++)
2269 Context->Listener->Params.Velocity[i] = 0.0f;
2271 //Validate Context
2272 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2273 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2274 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2275 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2277 //Set globals
2278 Context->DistanceModel = DefaultDistanceModel;
2279 Context->SourceDistanceModel = AL_FALSE;
2280 Context->DopplerFactor = 1.0f;
2281 Context->DopplerVelocity = 1.0f;
2282 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2283 Context->DeferUpdates = AL_FALSE;
2285 Context->ExtensionList = alExtList;
2289 /* FreeContext
2291 * Cleans up the context, and destroys any remaining objects the app failed to
2292 * delete. Called once there's no more references on the context.
2294 static void FreeContext(ALCcontext *context)
2296 TRACE("%p\n", context);
2298 if(context->SourceMap.size > 0)
2300 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2301 ReleaseALSources(context);
2303 ResetUIntMap(&context->SourceMap);
2305 if(context->EffectSlotMap.size > 0)
2307 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2308 ReleaseALAuxiliaryEffectSlots(context);
2310 ResetUIntMap(&context->EffectSlotMap);
2312 al_free(context->Voices);
2313 context->Voices = NULL;
2314 context->VoiceCount = 0;
2315 context->MaxVoices = 0;
2317 VECTOR_DEINIT(context->ActiveAuxSlots);
2319 ALCdevice_DecRef(context->Device);
2320 context->Device = NULL;
2322 //Invalidate context
2323 memset(context, 0, sizeof(ALCcontext));
2324 al_free(context);
2327 /* ReleaseContext
2329 * Removes the context reference from the given device and removes it from
2330 * being current on the running thread or globally.
2332 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2334 ALCcontext *nextctx;
2335 ALCcontext *origctx;
2337 if(altss_get(LocalContext) == context)
2339 WARN("%p released while current on thread\n", context);
2340 altss_set(LocalContext, NULL);
2341 ALCcontext_DecRef(context);
2344 origctx = context;
2345 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2346 ALCcontext_DecRef(context);
2348 ALCdevice_Lock(device);
2349 origctx = context;
2350 nextctx = context->next;
2351 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2353 ALCcontext *list;
2354 do {
2355 list = origctx;
2356 origctx = context;
2357 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2359 ALCdevice_Unlock(device);
2361 ALCcontext_DecRef(context);
2364 void ALCcontext_IncRef(ALCcontext *context)
2366 uint ref;
2367 ref = IncrementRef(&context->ref);
2368 TRACEREF("%p increasing refcount to %u\n", context, ref);
2371 void ALCcontext_DecRef(ALCcontext *context)
2373 uint ref;
2374 ref = DecrementRef(&context->ref);
2375 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2376 if(ref == 0) FreeContext(context);
2379 static void ReleaseThreadCtx(void *ptr)
2381 WARN("%p current for thread being destroyed\n", ptr);
2382 ALCcontext_DecRef(ptr);
2385 /* VerifyContext
2387 * Checks that the given context is valid, and increments its reference count.
2389 static ALCcontext *VerifyContext(ALCcontext *context)
2391 ALCdevice *dev;
2393 LockLists();
2394 dev = ATOMIC_LOAD(&DeviceList);
2395 while(dev)
2397 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2398 while(ctx)
2400 if(ctx == context)
2402 ALCcontext_IncRef(ctx);
2403 UnlockLists();
2404 return ctx;
2406 ctx = ctx->next;
2408 dev = dev->next;
2410 UnlockLists();
2412 return NULL;
2416 /* GetContextRef
2418 * Returns the currently active context for this thread, and adds a reference
2419 * without locking it.
2421 ALCcontext *GetContextRef(void)
2423 ALCcontext *context;
2425 context = altss_get(LocalContext);
2426 if(context)
2427 ALCcontext_IncRef(context);
2428 else
2430 LockLists();
2431 context = ATOMIC_LOAD(&GlobalContext);
2432 if(context)
2433 ALCcontext_IncRef(context);
2434 UnlockLists();
2437 return context;
2441 /************************************************
2442 * Standard ALC functions
2443 ************************************************/
2445 /* alcGetError
2447 * Return last ALC generated error code for the given device
2449 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2451 ALCenum errorCode;
2453 if(VerifyDevice(device))
2455 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2456 ALCdevice_DecRef(device);
2458 else
2459 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2461 return errorCode;
2465 /* alcSuspendContext
2467 * Suspends updates for the given context
2469 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2471 if(!SuspendDefers)
2472 return;
2474 context = VerifyContext(context);
2475 if(!context)
2476 alcSetError(NULL, ALC_INVALID_CONTEXT);
2477 else
2479 ALCcontext_DeferUpdates(context);
2480 ALCcontext_DecRef(context);
2484 /* alcProcessContext
2486 * Resumes processing updates for the given context
2488 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2490 if(!SuspendDefers)
2491 return;
2493 context = VerifyContext(context);
2494 if(!context)
2495 alcSetError(NULL, ALC_INVALID_CONTEXT);
2496 else
2498 ALCcontext_ProcessUpdates(context);
2499 ALCcontext_DecRef(context);
2504 /* alcGetString
2506 * Returns information about the device, and error strings
2508 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2510 const ALCchar *value = NULL;
2512 switch(param)
2514 case ALC_NO_ERROR:
2515 value = alcNoError;
2516 break;
2518 case ALC_INVALID_ENUM:
2519 value = alcErrInvalidEnum;
2520 break;
2522 case ALC_INVALID_VALUE:
2523 value = alcErrInvalidValue;
2524 break;
2526 case ALC_INVALID_DEVICE:
2527 value = alcErrInvalidDevice;
2528 break;
2530 case ALC_INVALID_CONTEXT:
2531 value = alcErrInvalidContext;
2532 break;
2534 case ALC_OUT_OF_MEMORY:
2535 value = alcErrOutOfMemory;
2536 break;
2538 case ALC_DEVICE_SPECIFIER:
2539 value = alcDefaultName;
2540 break;
2542 case ALC_ALL_DEVICES_SPECIFIER:
2543 if(VerifyDevice(Device))
2545 value = al_string_get_cstr(Device->DeviceName);
2546 ALCdevice_DecRef(Device);
2548 else
2550 ProbeAllDevicesList();
2551 value = al_string_get_cstr(alcAllDevicesList);
2553 break;
2555 case ALC_CAPTURE_DEVICE_SPECIFIER:
2556 if(VerifyDevice(Device))
2558 value = al_string_get_cstr(Device->DeviceName);
2559 ALCdevice_DecRef(Device);
2561 else
2563 ProbeCaptureDeviceList();
2564 value = al_string_get_cstr(alcCaptureDeviceList);
2566 break;
2568 /* Default devices are always first in the list */
2569 case ALC_DEFAULT_DEVICE_SPECIFIER:
2570 value = alcDefaultName;
2571 break;
2573 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2574 if(al_string_empty(alcAllDevicesList))
2575 ProbeAllDevicesList();
2577 Device = VerifyDevice(Device);
2579 free(alcDefaultAllDevicesSpecifier);
2580 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2581 if(!alcDefaultAllDevicesSpecifier)
2582 alcSetError(Device, ALC_OUT_OF_MEMORY);
2584 value = alcDefaultAllDevicesSpecifier;
2585 if(Device) ALCdevice_DecRef(Device);
2586 break;
2588 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2589 if(al_string_empty(alcCaptureDeviceList))
2590 ProbeCaptureDeviceList();
2592 Device = VerifyDevice(Device);
2594 free(alcCaptureDefaultDeviceSpecifier);
2595 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2596 if(!alcCaptureDefaultDeviceSpecifier)
2597 alcSetError(Device, ALC_OUT_OF_MEMORY);
2599 value = alcCaptureDefaultDeviceSpecifier;
2600 if(Device) ALCdevice_DecRef(Device);
2601 break;
2603 case ALC_EXTENSIONS:
2604 if(!VerifyDevice(Device))
2605 value = alcNoDeviceExtList;
2606 else
2608 value = alcExtensionList;
2609 ALCdevice_DecRef(Device);
2611 break;
2613 default:
2614 Device = VerifyDevice(Device);
2615 alcSetError(Device, ALC_INVALID_ENUM);
2616 if(Device) ALCdevice_DecRef(Device);
2617 break;
2620 return value;
2624 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2626 ALCsizei i;
2628 if(size <= 0 || values == NULL)
2630 alcSetError(device, ALC_INVALID_VALUE);
2631 return 0;
2634 if(!device)
2636 switch(param)
2638 case ALC_MAJOR_VERSION:
2639 values[0] = alcMajorVersion;
2640 return 1;
2641 case ALC_MINOR_VERSION:
2642 values[0] = alcMinorVersion;
2643 return 1;
2645 case ALC_ATTRIBUTES_SIZE:
2646 case ALC_ALL_ATTRIBUTES:
2647 case ALC_FREQUENCY:
2648 case ALC_REFRESH:
2649 case ALC_SYNC:
2650 case ALC_MONO_SOURCES:
2651 case ALC_STEREO_SOURCES:
2652 case ALC_CAPTURE_SAMPLES:
2653 case ALC_FORMAT_CHANNELS_SOFT:
2654 case ALC_FORMAT_TYPE_SOFT:
2655 alcSetError(NULL, ALC_INVALID_DEVICE);
2656 return 0;
2658 default:
2659 alcSetError(NULL, ALC_INVALID_ENUM);
2660 return 0;
2662 return 0;
2665 if(device->Type == Capture)
2667 switch(param)
2669 case ALC_CAPTURE_SAMPLES:
2670 ALCdevice_Lock(device);
2671 values[0] = V0(device->Backend,availableSamples)();
2672 ALCdevice_Unlock(device);
2673 return 1;
2675 case ALC_CONNECTED:
2676 values[0] = device->Connected;
2677 return 1;
2679 default:
2680 alcSetError(device, ALC_INVALID_ENUM);
2681 return 0;
2683 return 0;
2686 /* render device */
2687 switch(param)
2689 case ALC_MAJOR_VERSION:
2690 values[0] = alcMajorVersion;
2691 return 1;
2693 case ALC_MINOR_VERSION:
2694 values[0] = alcMinorVersion;
2695 return 1;
2697 case ALC_EFX_MAJOR_VERSION:
2698 values[0] = alcEFXMajorVersion;
2699 return 1;
2701 case ALC_EFX_MINOR_VERSION:
2702 values[0] = alcEFXMinorVersion;
2703 return 1;
2705 case ALC_ATTRIBUTES_SIZE:
2706 values[0] = 15;
2707 return 1;
2709 case ALC_ALL_ATTRIBUTES:
2710 if(size < 15)
2712 alcSetError(device, ALC_INVALID_VALUE);
2713 return 0;
2716 i = 0;
2717 values[i++] = ALC_FREQUENCY;
2718 values[i++] = device->Frequency;
2720 if(device->Type != Loopback)
2722 values[i++] = ALC_REFRESH;
2723 values[i++] = device->Frequency / device->UpdateSize;
2725 values[i++] = ALC_SYNC;
2726 values[i++] = ALC_FALSE;
2728 else
2730 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2731 values[i++] = device->FmtChans;
2733 values[i++] = ALC_FORMAT_TYPE_SOFT;
2734 values[i++] = device->FmtType;
2737 values[i++] = ALC_MONO_SOURCES;
2738 values[i++] = device->NumMonoSources;
2740 values[i++] = ALC_STEREO_SOURCES;
2741 values[i++] = device->NumStereoSources;
2743 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2744 values[i++] = device->NumAuxSends;
2746 values[i++] = ALC_HRTF_SOFT;
2747 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2749 values[i++] = 0;
2750 return i;
2752 case ALC_FREQUENCY:
2753 values[0] = device->Frequency;
2754 return 1;
2756 case ALC_REFRESH:
2757 if(device->Type == Loopback)
2759 alcSetError(device, ALC_INVALID_DEVICE);
2760 return 0;
2762 values[0] = device->Frequency / device->UpdateSize;
2763 return 1;
2765 case ALC_SYNC:
2766 if(device->Type == Loopback)
2768 alcSetError(device, ALC_INVALID_DEVICE);
2769 return 0;
2771 values[0] = ALC_FALSE;
2772 return 1;
2774 case ALC_FORMAT_CHANNELS_SOFT:
2775 if(device->Type != Loopback)
2777 alcSetError(device, ALC_INVALID_DEVICE);
2778 return 0;
2780 values[0] = device->FmtChans;
2781 return 1;
2783 case ALC_FORMAT_TYPE_SOFT:
2784 if(device->Type != Loopback)
2786 alcSetError(device, ALC_INVALID_DEVICE);
2787 return 0;
2789 values[0] = device->FmtType;
2790 return 1;
2792 case ALC_MONO_SOURCES:
2793 values[0] = device->NumMonoSources;
2794 return 1;
2796 case ALC_STEREO_SOURCES:
2797 values[0] = device->NumStereoSources;
2798 return 1;
2800 case ALC_MAX_AUXILIARY_SENDS:
2801 values[0] = device->NumAuxSends;
2802 return 1;
2804 case ALC_CONNECTED:
2805 values[0] = device->Connected;
2806 return 1;
2808 case ALC_HRTF_SOFT:
2809 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2810 return 1;
2812 default:
2813 alcSetError(device, ALC_INVALID_ENUM);
2814 return 0;
2816 return 0;
2819 /* alcGetIntegerv
2821 * Returns information about the device and the version of OpenAL
2823 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2825 device = VerifyDevice(device);
2826 if(size <= 0 || values == NULL)
2827 alcSetError(device, ALC_INVALID_VALUE);
2828 else
2829 GetIntegerv(device, param, size, values);
2830 if(device) ALCdevice_DecRef(device);
2833 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2835 ALCint *ivals;
2836 ALsizei i;
2838 device = VerifyDevice(device);
2839 if(size <= 0 || values == NULL)
2840 alcSetError(device, ALC_INVALID_VALUE);
2841 else if(!device || device->Type == Capture)
2843 ivals = malloc(size * sizeof(ALCint));
2844 size = GetIntegerv(device, pname, size, ivals);
2845 for(i = 0;i < size;i++)
2846 values[i] = ivals[i];
2847 free(ivals);
2849 else /* render device */
2851 switch(pname)
2853 case ALC_ATTRIBUTES_SIZE:
2854 *values = 17;
2855 break;
2857 case ALC_ALL_ATTRIBUTES:
2858 if(size < 17)
2859 alcSetError(device, ALC_INVALID_VALUE);
2860 else
2862 int i = 0;
2864 V0(device->Backend,lock)();
2865 values[i++] = ALC_FREQUENCY;
2866 values[i++] = device->Frequency;
2868 if(device->Type != Loopback)
2870 values[i++] = ALC_REFRESH;
2871 values[i++] = device->Frequency / device->UpdateSize;
2873 values[i++] = ALC_SYNC;
2874 values[i++] = ALC_FALSE;
2876 else
2878 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2879 values[i++] = device->FmtChans;
2881 values[i++] = ALC_FORMAT_TYPE_SOFT;
2882 values[i++] = device->FmtType;
2885 values[i++] = ALC_MONO_SOURCES;
2886 values[i++] = device->NumMonoSources;
2888 values[i++] = ALC_STEREO_SOURCES;
2889 values[i++] = device->NumStereoSources;
2891 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2892 values[i++] = device->NumAuxSends;
2894 values[i++] = ALC_HRTF_SOFT;
2895 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2897 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2898 values[i++] = device->ClockBase +
2899 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2901 values[i++] = 0;
2902 V0(device->Backend,unlock)();
2904 break;
2906 case ALC_DEVICE_CLOCK_SOFT:
2907 V0(device->Backend,lock)();
2908 *values = device->ClockBase +
2909 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2910 V0(device->Backend,unlock)();
2911 break;
2913 default:
2914 ivals = malloc(size * sizeof(ALCint));
2915 size = GetIntegerv(device, pname, size, ivals);
2916 for(i = 0;i < size;i++)
2917 values[i] = ivals[i];
2918 free(ivals);
2919 break;
2922 if(device)
2923 ALCdevice_DecRef(device);
2927 /* alcIsExtensionPresent
2929 * Determines if there is support for a particular extension
2931 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2933 ALCboolean bResult = ALC_FALSE;
2935 device = VerifyDevice(device);
2937 if(!extName)
2938 alcSetError(device, ALC_INVALID_VALUE);
2939 else
2941 size_t len = strlen(extName);
2942 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2943 while(ptr && *ptr)
2945 if(strncasecmp(ptr, extName, len) == 0 &&
2946 (ptr[len] == '\0' || isspace(ptr[len])))
2948 bResult = ALC_TRUE;
2949 break;
2951 if((ptr=strchr(ptr, ' ')) != NULL)
2953 do {
2954 ++ptr;
2955 } while(isspace(*ptr));
2959 if(device)
2960 ALCdevice_DecRef(device);
2961 return bResult;
2965 /* alcGetProcAddress
2967 * Retrieves the function address for a particular extension function
2969 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2971 ALCvoid *ptr = NULL;
2973 if(!funcName)
2975 device = VerifyDevice(device);
2976 alcSetError(device, ALC_INVALID_VALUE);
2977 if(device) ALCdevice_DecRef(device);
2979 else
2981 ALsizei i = 0;
2982 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
2983 i++;
2984 ptr = alcFunctions[i].address;
2987 return ptr;
2991 /* alcGetEnumValue
2993 * Get the value for a particular ALC enumeration name
2995 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
2997 ALCenum val = 0;
2999 if(!enumName)
3001 device = VerifyDevice(device);
3002 alcSetError(device, ALC_INVALID_VALUE);
3003 if(device) ALCdevice_DecRef(device);
3005 else
3007 ALsizei i = 0;
3008 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3009 i++;
3010 val = enumeration[i].value;
3013 return val;
3017 /* alcCreateContext
3019 * Create and attach a context to the given device.
3021 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3023 ALCcontext *ALContext;
3024 ALCenum err;
3026 LockLists();
3027 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
3029 UnlockLists();
3030 alcSetError(device, ALC_INVALID_DEVICE);
3031 if(device) ALCdevice_DecRef(device);
3032 return NULL;
3035 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3037 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3039 UnlockLists();
3040 alcSetError(device, err);
3041 if(err == ALC_INVALID_DEVICE)
3043 ALCdevice_Lock(device);
3044 aluHandleDisconnect(device);
3045 ALCdevice_Unlock(device);
3047 ALCdevice_DecRef(device);
3048 return NULL;
3051 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3052 if(ALContext)
3054 InitRef(&ALContext->ref, 1);
3055 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3057 VECTOR_INIT(ALContext->ActiveAuxSlots);
3059 ALContext->VoiceCount = 0;
3060 ALContext->MaxVoices = 256;
3061 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3063 if(!ALContext || !ALContext->Voices)
3065 if(!ATOMIC_LOAD(&device->ContextList))
3067 V0(device->Backend,stop)();
3068 device->Flags &= ~DEVICE_RUNNING;
3070 UnlockLists();
3072 if(ALContext)
3074 al_free(ALContext->Voices);
3075 ALContext->Voices = NULL;
3077 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3079 al_free(ALContext);
3080 ALContext = NULL;
3083 alcSetError(device, ALC_OUT_OF_MEMORY);
3084 ALCdevice_DecRef(device);
3085 return NULL;
3088 ALContext->Device = device;
3089 ALCdevice_IncRef(device);
3090 InitContext(ALContext);
3093 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3094 do {
3095 ALContext->next = head;
3096 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3098 UnlockLists();
3100 ALCdevice_DecRef(device);
3102 TRACE("Created context %p\n", ALContext);
3103 return ALContext;
3106 /* alcDestroyContext
3108 * Remove a context from its device
3110 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3112 ALCdevice *Device;
3114 LockLists();
3115 /* alcGetContextsDevice sets an error for invalid contexts */
3116 Device = alcGetContextsDevice(context);
3117 if(Device)
3119 ReleaseContext(context, Device);
3120 if(!ATOMIC_LOAD(&Device->ContextList))
3122 V0(Device->Backend,stop)();
3123 Device->Flags &= ~DEVICE_RUNNING;
3126 UnlockLists();
3130 /* alcGetCurrentContext
3132 * Returns the currently active context on the calling thread
3134 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3136 ALCcontext *Context = altss_get(LocalContext);
3137 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3138 return Context;
3141 /* alcGetThreadContext
3143 * Returns the currently active thread-local context
3145 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3147 return altss_get(LocalContext);
3151 /* alcMakeContextCurrent
3153 * Makes the given context the active process-wide context, and removes the
3154 * thread-local context for the calling thread.
3156 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3158 /* context must be valid or NULL */
3159 if(context && !(context=VerifyContext(context)))
3161 alcSetError(NULL, ALC_INVALID_CONTEXT);
3162 return ALC_FALSE;
3164 /* context's reference count is already incremented */
3165 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3166 if(context) ALCcontext_DecRef(context);
3168 if((context=altss_get(LocalContext)) != NULL)
3170 altss_set(LocalContext, NULL);
3171 ALCcontext_DecRef(context);
3174 return ALC_TRUE;
3177 /* alcSetThreadContext
3179 * Makes the given context the active context for the current thread
3181 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3183 ALCcontext *old;
3185 /* context must be valid or NULL */
3186 if(context && !(context=VerifyContext(context)))
3188 alcSetError(NULL, ALC_INVALID_CONTEXT);
3189 return ALC_FALSE;
3191 /* context's reference count is already incremented */
3192 old = altss_get(LocalContext);
3193 altss_set(LocalContext, context);
3194 if(old) ALCcontext_DecRef(old);
3196 return ALC_TRUE;
3200 /* alcGetContextsDevice
3202 * Returns the device that a particular context is attached to
3204 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3206 ALCdevice *Device;
3208 if(!(Context=VerifyContext(Context)))
3210 alcSetError(NULL, ALC_INVALID_CONTEXT);
3211 return NULL;
3213 Device = Context->Device;
3214 ALCcontext_DecRef(Context);
3216 return Device;
3220 /* alcOpenDevice
3222 * Opens the named device.
3224 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3226 const ALCchar *fmt;
3227 ALCdevice *device;
3228 ALCenum err;
3230 DO_INITCONFIG();
3232 if(!PlaybackBackend.name)
3234 alcSetError(NULL, ALC_INVALID_VALUE);
3235 return NULL;
3238 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3239 deviceName = NULL;
3241 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3242 if(!device)
3244 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3245 return NULL;
3248 //Validate device
3249 InitRef(&device->ref, 1);
3250 device->Connected = ALC_TRUE;
3251 device->Type = Playback;
3252 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3254 device->Flags = 0;
3255 device->Bs2b = NULL;
3256 device->Bs2bLevel = 0;
3257 AL_STRING_INIT(device->DeviceName);
3258 device->DryBuffer = NULL;
3260 ATOMIC_INIT(&device->ContextList, NULL);
3262 device->ClockBase = 0;
3263 device->SamplesDone = 0;
3265 device->MaxNoOfSources = 256;
3266 device->AuxiliaryEffectSlotMax = 4;
3267 device->NumAuxSends = MAX_SENDS;
3269 InitUIntMap(&device->BufferMap, ~0);
3270 InitUIntMap(&device->EffectMap, ~0);
3271 InitUIntMap(&device->FilterMap, ~0);
3272 InitUIntMap(&device->SfontMap, ~0);
3273 InitUIntMap(&device->PresetMap, ~0);
3274 InitUIntMap(&device->FontsoundMap, ~0);
3276 //Set output format
3277 device->FmtChans = DevFmtChannelsDefault;
3278 device->FmtType = DevFmtTypeDefault;
3279 device->Frequency = DEFAULT_OUTPUT_RATE;
3280 device->NumUpdates = 4;
3281 device->UpdateSize = 1024;
3283 if(!PlaybackBackend.getFactory)
3284 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3285 ALCbackend_Playback);
3286 else
3288 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3289 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3291 if(!device->Backend)
3293 al_free(device);
3294 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3295 return NULL;
3299 if(ConfigValueStr(NULL, "channels", &fmt))
3301 static const struct {
3302 const char name[16];
3303 enum DevFmtChannels chans;
3304 } chanlist[] = {
3305 { "mono", DevFmtMono },
3306 { "stereo", DevFmtStereo },
3307 { "quad", DevFmtQuad },
3308 { "surround51", DevFmtX51 },
3309 { "surround61", DevFmtX61 },
3310 { "surround71", DevFmtX71 },
3311 { "surround51rear", DevFmtX51Rear },
3313 size_t i;
3315 for(i = 0;i < COUNTOF(chanlist);i++)
3317 if(strcasecmp(chanlist[i].name, fmt) == 0)
3319 device->FmtChans = chanlist[i].chans;
3320 device->Flags |= DEVICE_CHANNELS_REQUEST;
3321 break;
3324 if(i == COUNTOF(chanlist))
3325 ERR("Unsupported channels: %s\n", fmt);
3327 if(ConfigValueStr(NULL, "sample-type", &fmt))
3329 static const struct {
3330 const char name[16];
3331 enum DevFmtType type;
3332 } typelist[] = {
3333 { "int8", DevFmtByte },
3334 { "uint8", DevFmtUByte },
3335 { "int16", DevFmtShort },
3336 { "uint16", DevFmtUShort },
3337 { "int32", DevFmtInt },
3338 { "uint32", DevFmtUInt },
3339 { "float32", DevFmtFloat },
3341 size_t i;
3343 for(i = 0;i < COUNTOF(typelist);i++)
3345 if(strcasecmp(typelist[i].name, fmt) == 0)
3347 device->FmtType = typelist[i].type;
3348 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3349 break;
3352 if(i == COUNTOF(typelist))
3353 ERR("Unsupported sample-type: %s\n", fmt);
3356 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
3358 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3359 if(device->Frequency < MIN_OUTPUT_RATE)
3360 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3361 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3364 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
3365 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3367 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
3368 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3369 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3370 device->UpdateSize = (device->UpdateSize+3)&~3;
3372 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3373 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3375 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3376 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3378 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3379 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3381 ConfigValueInt(NULL, "cf_level", &device->Bs2bLevel);
3383 device->NumStereoSources = 1;
3384 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3386 device->Synth = SynthCreate(device);
3387 if(!device->Synth)
3389 DELETE_OBJ(device->Backend);
3390 al_free(device);
3391 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3392 return NULL;
3395 // Find a playback device to open
3396 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3398 DELETE_OBJ(device->Synth);
3399 DELETE_OBJ(device->Backend);
3400 al_free(device);
3401 alcSetError(NULL, err);
3402 return NULL;
3405 if(DefaultEffect.type != AL_EFFECT_NULL)
3407 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3408 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3410 device->DefaultSlot = NULL;
3411 ERR("Failed to initialize the default effect slot\n");
3413 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3415 ALeffectState *state = device->DefaultSlot->EffectState;
3416 device->DefaultSlot = NULL;
3417 DELETE_OBJ(state);
3418 ERR("Failed to initialize the default effect\n");
3423 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3424 do {
3425 device->next = head;
3426 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3429 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3430 return device;
3433 /* alcCloseDevice
3435 * Closes the given device.
3437 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3439 ALCdevice *list, *origdev, *nextdev;
3440 ALCcontext *ctx;
3442 LockLists();
3443 list = ATOMIC_LOAD(&DeviceList);
3444 do {
3445 if(list == device)
3446 break;
3447 } while((list=list->next) != NULL);
3448 if(!list || list->Type == Capture)
3450 alcSetError(list, ALC_INVALID_DEVICE);
3451 UnlockLists();
3452 return ALC_FALSE;
3455 origdev = device;
3456 nextdev = device->next;
3457 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3459 do {
3460 list = origdev;
3461 origdev = device;
3462 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3464 UnlockLists();
3466 ctx = ATOMIC_LOAD(&device->ContextList);
3467 while(ctx != NULL)
3469 ALCcontext *next = ctx->next;
3470 WARN("Releasing context %p\n", ctx);
3471 ReleaseContext(ctx, device);
3472 ctx = next;
3474 if((device->Flags&DEVICE_RUNNING))
3475 V0(device->Backend,stop)();
3476 device->Flags &= ~DEVICE_RUNNING;
3478 ALCdevice_DecRef(device);
3480 return ALC_TRUE;
3484 /************************************************
3485 * ALC capture functions
3486 ************************************************/
3487 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3489 ALCdevice *device = NULL;
3490 ALCenum err;
3492 DO_INITCONFIG();
3494 if(!CaptureBackend.name)
3496 alcSetError(NULL, ALC_INVALID_VALUE);
3497 return NULL;
3500 if(samples <= 0)
3502 alcSetError(NULL, ALC_INVALID_VALUE);
3503 return NULL;
3506 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3507 deviceName = NULL;
3509 device = al_calloc(16, sizeof(ALCdevice));
3510 if(!device)
3512 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3513 return NULL;
3516 //Validate device
3517 InitRef(&device->ref, 1);
3518 device->Connected = ALC_TRUE;
3519 device->Type = Capture;
3521 AL_STRING_INIT(device->DeviceName);
3522 device->DryBuffer = NULL;
3524 InitUIntMap(&device->BufferMap, ~0);
3525 InitUIntMap(&device->EffectMap, ~0);
3526 InitUIntMap(&device->FilterMap, ~0);
3527 InitUIntMap(&device->SfontMap, ~0);
3528 InitUIntMap(&device->PresetMap, ~0);
3529 InitUIntMap(&device->FontsoundMap, ~0);
3531 if(!CaptureBackend.getFactory)
3532 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3533 ALCbackend_Capture);
3534 else
3536 ALCbackendFactory *factory = CaptureBackend.getFactory();
3537 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3539 if(!device->Backend)
3541 al_free(device);
3542 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3543 return NULL;
3546 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3547 device->Frequency = frequency;
3549 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3550 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3552 al_free(device);
3553 alcSetError(NULL, ALC_INVALID_ENUM);
3554 return NULL;
3557 device->UpdateSize = samples;
3558 device->NumUpdates = 1;
3560 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3562 al_free(device);
3563 alcSetError(NULL, err);
3564 return NULL;
3568 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3569 do {
3570 device->next = head;
3571 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3574 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3575 return device;
3578 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3580 ALCdevice *list, *next, *nextdev;
3582 LockLists();
3583 list = ATOMIC_LOAD(&DeviceList);
3584 do {
3585 if(list == device)
3586 break;
3587 } while((list=list->next) != NULL);
3588 if(!list || list->Type != Capture)
3590 alcSetError(list, ALC_INVALID_DEVICE);
3591 UnlockLists();
3592 return ALC_FALSE;
3595 next = device;
3596 nextdev = device->next;
3597 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3599 do {
3600 list = next;
3601 next = device;
3602 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3604 UnlockLists();
3606 ALCdevice_DecRef(device);
3608 return ALC_TRUE;
3611 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3613 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3614 alcSetError(device, ALC_INVALID_DEVICE);
3615 else
3617 ALCdevice_Lock(device);
3618 if(device->Connected)
3620 if(!(device->Flags&DEVICE_RUNNING))
3621 V0(device->Backend,start)();
3622 device->Flags |= DEVICE_RUNNING;
3624 ALCdevice_Unlock(device);
3627 if(device) ALCdevice_DecRef(device);
3630 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3632 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3633 alcSetError(device, ALC_INVALID_DEVICE);
3634 else
3636 ALCdevice_Lock(device);
3637 if((device->Flags&DEVICE_RUNNING))
3638 V0(device->Backend,stop)();
3639 device->Flags &= ~DEVICE_RUNNING;
3640 ALCdevice_Unlock(device);
3643 if(device) ALCdevice_DecRef(device);
3646 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3648 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3649 alcSetError(device, ALC_INVALID_DEVICE);
3650 else
3652 ALCenum err = ALC_INVALID_VALUE;
3654 ALCdevice_Lock(device);
3655 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3656 err = V(device->Backend,captureSamples)(buffer, samples);
3657 ALCdevice_Unlock(device);
3659 if(err != ALC_NO_ERROR)
3660 alcSetError(device, err);
3662 if(device) ALCdevice_DecRef(device);
3666 /************************************************
3667 * ALC loopback functions
3668 ************************************************/
3670 /* alcLoopbackOpenDeviceSOFT
3672 * Open a loopback device, for manual rendering.
3674 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3676 ALCbackendFactory *factory;
3677 ALCdevice *device;
3679 DO_INITCONFIG();
3681 /* Make sure the device name, if specified, is us. */
3682 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3684 alcSetError(NULL, ALC_INVALID_VALUE);
3685 return NULL;
3688 device = al_calloc(16, sizeof(ALCdevice));
3689 if(!device)
3691 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3692 return NULL;
3695 //Validate device
3696 InitRef(&device->ref, 1);
3697 device->Connected = ALC_TRUE;
3698 device->Type = Loopback;
3699 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3701 device->Flags = 0;
3702 device->Bs2b = NULL;
3703 device->Bs2bLevel = 0;
3704 AL_STRING_INIT(device->DeviceName);
3705 device->DryBuffer = NULL;
3707 ATOMIC_INIT(&device->ContextList, NULL);
3709 device->ClockBase = 0;
3710 device->SamplesDone = 0;
3712 device->MaxNoOfSources = 256;
3713 device->AuxiliaryEffectSlotMax = 4;
3714 device->NumAuxSends = MAX_SENDS;
3716 InitUIntMap(&device->BufferMap, ~0);
3717 InitUIntMap(&device->EffectMap, ~0);
3718 InitUIntMap(&device->FilterMap, ~0);
3719 InitUIntMap(&device->SfontMap, ~0);
3720 InitUIntMap(&device->PresetMap, ~0);
3721 InitUIntMap(&device->FontsoundMap, ~0);
3723 factory = ALCloopbackFactory_getFactory();
3724 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3725 if(!device->Backend)
3727 al_free(device);
3728 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3729 return NULL;
3732 //Set output format
3733 device->NumUpdates = 0;
3734 device->UpdateSize = 0;
3736 device->Frequency = DEFAULT_OUTPUT_RATE;
3737 device->FmtChans = DevFmtChannelsDefault;
3738 device->FmtType = DevFmtTypeDefault;
3740 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3741 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3743 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3744 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3746 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3747 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3749 device->NumStereoSources = 1;
3750 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3752 device->Synth = SynthCreate(device);
3753 if(!device->Synth)
3755 DELETE_OBJ(device->Backend);
3756 al_free(device);
3757 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3758 return NULL;
3761 // Open the "backend"
3762 V(device->Backend,open)("Loopback");
3765 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3766 do {
3767 device->next = head;
3768 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3771 TRACE("Created device %p\n", device);
3772 return device;
3775 /* alcIsRenderFormatSupportedSOFT
3777 * Determines if the loopback device supports the given format for rendering.
3779 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3781 ALCboolean ret = ALC_FALSE;
3783 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3784 alcSetError(device, ALC_INVALID_DEVICE);
3785 else if(freq <= 0)
3786 alcSetError(device, ALC_INVALID_VALUE);
3787 else
3789 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3790 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3791 freq >= MIN_OUTPUT_RATE)
3792 ret = ALC_TRUE;
3794 if(device) ALCdevice_DecRef(device);
3796 return ret;
3799 /* alcRenderSamplesSOFT
3801 * Renders some samples into a buffer, using the format last set by the
3802 * attributes given to alcCreateContext.
3804 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3806 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3807 alcSetError(device, ALC_INVALID_DEVICE);
3808 else if(samples < 0 || (samples > 0 && buffer == NULL))
3809 alcSetError(device, ALC_INVALID_VALUE);
3810 else
3811 aluMixData(device, buffer, samples);
3812 if(device) ALCdevice_DecRef(device);
3816 /************************************************
3817 * ALC DSP pause/resume functions
3818 ************************************************/
3820 /* alcDevicePauseSOFT
3822 * Pause the DSP to stop audio processing.
3824 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3826 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3827 alcSetError(device, ALC_INVALID_DEVICE);
3828 else
3830 LockLists();
3831 if((device->Flags&DEVICE_RUNNING))
3832 V0(device->Backend,stop)();
3833 device->Flags &= ~DEVICE_RUNNING;
3834 device->Flags |= DEVICE_PAUSED;
3835 UnlockLists();
3837 if(device) ALCdevice_DecRef(device);
3840 /* alcDeviceResumeSOFT
3842 * Resume the DSP to restart audio processing.
3844 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3846 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3847 alcSetError(device, ALC_INVALID_DEVICE);
3848 else
3850 LockLists();
3851 if((device->Flags&DEVICE_PAUSED))
3853 device->Flags &= ~DEVICE_PAUSED;
3854 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3856 if(V0(device->Backend,start)() != ALC_FALSE)
3857 device->Flags |= DEVICE_RUNNING;
3858 else
3860 alcSetError(device, ALC_INVALID_DEVICE);
3861 ALCdevice_Lock(device);
3862 aluHandleDisconnect(device);
3863 ALCdevice_Unlock(device);
3867 UnlockLists();
3869 if(device) ALCdevice_DecRef(device);