Replace the cubic resampler with a 4-point sinc/lanczos filter
[openal-soft.git] / Alc / ALc.c
blobfcb6504b2577f083fd1909ac58c69c326486e3dc
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include <ctype.h>
28 #include <signal.h>
30 #include "alMain.h"
31 #include "alSource.h"
32 #include "alListener.h"
33 #include "alThunk.h"
34 #include "alSource.h"
35 #include "alBuffer.h"
36 #include "alAuxEffectSlot.h"
37 #include "alError.h"
38 #include "alMidi.h"
39 #include "bs2b.h"
40 #include "alu.h"
42 #include "compat.h"
43 #include "threads.h"
44 #include "alstring.h"
46 #include "backends/base.h"
47 #include "midi/base.h"
50 /************************************************
51 * Backends
52 ************************************************/
53 struct BackendInfo {
54 const char *name;
55 ALCbackendFactory* (*getFactory)(void);
56 ALCboolean (*Init)(BackendFuncs*);
57 void (*Deinit)(void);
58 void (*Probe)(enum DevProbe);
59 BackendFuncs Funcs;
62 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
63 static struct BackendInfo BackendList[] = {
64 #ifdef HAVE_JACK
65 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
66 #endif
67 #ifdef HAVE_PULSEAUDIO
68 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
69 #endif
70 #ifdef HAVE_ALSA
71 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
72 #endif
73 #ifdef HAVE_COREAUDIO
74 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
75 #endif
76 #ifdef HAVE_OSS
77 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
78 #endif
79 #ifdef HAVE_SOLARIS
80 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
81 #endif
82 #ifdef HAVE_SNDIO
83 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
84 #endif
85 #ifdef HAVE_QSA
86 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
87 #endif
88 #ifdef HAVE_MMDEVAPI
89 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
90 #endif
91 #ifdef HAVE_DSOUND
92 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
93 #endif
94 #ifdef HAVE_WINMM
95 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
96 #endif
97 #ifdef HAVE_PORTAUDIO
98 { "port", NULL, alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs },
99 #endif
100 #ifdef HAVE_OPENSL
101 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
102 #endif
104 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
105 #ifdef HAVE_WAVE
106 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
107 #endif
109 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
111 #undef EmptyFuncs
113 static struct BackendInfo PlaybackBackend;
114 static struct BackendInfo CaptureBackend;
117 /************************************************
118 * Functions, enums, and errors
119 ************************************************/
120 typedef struct ALCfunction {
121 const ALCchar *funcName;
122 ALCvoid *address;
123 } ALCfunction;
125 typedef struct ALCenums {
126 const ALCchar *enumName;
127 ALCenum value;
128 } ALCenums;
130 #define DECL(x) { #x, (ALCvoid*)(x) }
131 static const ALCfunction alcFunctions[] = {
132 DECL(alcCreateContext),
133 DECL(alcMakeContextCurrent),
134 DECL(alcProcessContext),
135 DECL(alcSuspendContext),
136 DECL(alcDestroyContext),
137 DECL(alcGetCurrentContext),
138 DECL(alcGetContextsDevice),
139 DECL(alcOpenDevice),
140 DECL(alcCloseDevice),
141 DECL(alcGetError),
142 DECL(alcIsExtensionPresent),
143 DECL(alcGetProcAddress),
144 DECL(alcGetEnumValue),
145 DECL(alcGetString),
146 DECL(alcGetIntegerv),
147 DECL(alcCaptureOpenDevice),
148 DECL(alcCaptureCloseDevice),
149 DECL(alcCaptureStart),
150 DECL(alcCaptureStop),
151 DECL(alcCaptureSamples),
153 DECL(alcSetThreadContext),
154 DECL(alcGetThreadContext),
156 DECL(alcLoopbackOpenDeviceSOFT),
157 DECL(alcIsRenderFormatSupportedSOFT),
158 DECL(alcRenderSamplesSOFT),
160 DECL(alcDevicePauseSOFT),
161 DECL(alcDeviceResumeSOFT),
163 DECL(alcGetInteger64vSOFT),
165 DECL(alcResetDeviceSOFT),
167 DECL(alEnable),
168 DECL(alDisable),
169 DECL(alIsEnabled),
170 DECL(alGetString),
171 DECL(alGetBooleanv),
172 DECL(alGetIntegerv),
173 DECL(alGetFloatv),
174 DECL(alGetDoublev),
175 DECL(alGetBoolean),
176 DECL(alGetInteger),
177 DECL(alGetFloat),
178 DECL(alGetDouble),
179 DECL(alGetError),
180 DECL(alIsExtensionPresent),
181 DECL(alGetProcAddress),
182 DECL(alGetEnumValue),
183 DECL(alListenerf),
184 DECL(alListener3f),
185 DECL(alListenerfv),
186 DECL(alListeneri),
187 DECL(alListener3i),
188 DECL(alListeneriv),
189 DECL(alGetListenerf),
190 DECL(alGetListener3f),
191 DECL(alGetListenerfv),
192 DECL(alGetListeneri),
193 DECL(alGetListener3i),
194 DECL(alGetListeneriv),
195 DECL(alGenSources),
196 DECL(alDeleteSources),
197 DECL(alIsSource),
198 DECL(alSourcef),
199 DECL(alSource3f),
200 DECL(alSourcefv),
201 DECL(alSourcei),
202 DECL(alSource3i),
203 DECL(alSourceiv),
204 DECL(alGetSourcef),
205 DECL(alGetSource3f),
206 DECL(alGetSourcefv),
207 DECL(alGetSourcei),
208 DECL(alGetSource3i),
209 DECL(alGetSourceiv),
210 DECL(alSourcePlayv),
211 DECL(alSourceStopv),
212 DECL(alSourceRewindv),
213 DECL(alSourcePausev),
214 DECL(alSourcePlay),
215 DECL(alSourceStop),
216 DECL(alSourceRewind),
217 DECL(alSourcePause),
218 DECL(alSourceQueueBuffers),
219 DECL(alSourceUnqueueBuffers),
220 DECL(alGenBuffers),
221 DECL(alDeleteBuffers),
222 DECL(alIsBuffer),
223 DECL(alBufferData),
224 DECL(alBufferf),
225 DECL(alBuffer3f),
226 DECL(alBufferfv),
227 DECL(alBufferi),
228 DECL(alBuffer3i),
229 DECL(alBufferiv),
230 DECL(alGetBufferf),
231 DECL(alGetBuffer3f),
232 DECL(alGetBufferfv),
233 DECL(alGetBufferi),
234 DECL(alGetBuffer3i),
235 DECL(alGetBufferiv),
236 DECL(alDopplerFactor),
237 DECL(alDopplerVelocity),
238 DECL(alSpeedOfSound),
239 DECL(alDistanceModel),
241 DECL(alGenFilters),
242 DECL(alDeleteFilters),
243 DECL(alIsFilter),
244 DECL(alFilteri),
245 DECL(alFilteriv),
246 DECL(alFilterf),
247 DECL(alFilterfv),
248 DECL(alGetFilteri),
249 DECL(alGetFilteriv),
250 DECL(alGetFilterf),
251 DECL(alGetFilterfv),
252 DECL(alGenEffects),
253 DECL(alDeleteEffects),
254 DECL(alIsEffect),
255 DECL(alEffecti),
256 DECL(alEffectiv),
257 DECL(alEffectf),
258 DECL(alEffectfv),
259 DECL(alGetEffecti),
260 DECL(alGetEffectiv),
261 DECL(alGetEffectf),
262 DECL(alGetEffectfv),
263 DECL(alGenAuxiliaryEffectSlots),
264 DECL(alDeleteAuxiliaryEffectSlots),
265 DECL(alIsAuxiliaryEffectSlot),
266 DECL(alAuxiliaryEffectSloti),
267 DECL(alAuxiliaryEffectSlotiv),
268 DECL(alAuxiliaryEffectSlotf),
269 DECL(alAuxiliaryEffectSlotfv),
270 DECL(alGetAuxiliaryEffectSloti),
271 DECL(alGetAuxiliaryEffectSlotiv),
272 DECL(alGetAuxiliaryEffectSlotf),
273 DECL(alGetAuxiliaryEffectSlotfv),
275 DECL(alBufferSubDataSOFT),
277 DECL(alBufferSamplesSOFT),
278 DECL(alBufferSubSamplesSOFT),
279 DECL(alGetBufferSamplesSOFT),
280 DECL(alIsBufferFormatSupportedSOFT),
282 DECL(alDeferUpdatesSOFT),
283 DECL(alProcessUpdatesSOFT),
285 DECL(alSourcedSOFT),
286 DECL(alSource3dSOFT),
287 DECL(alSourcedvSOFT),
288 DECL(alGetSourcedSOFT),
289 DECL(alGetSource3dSOFT),
290 DECL(alGetSourcedvSOFT),
291 DECL(alSourcei64SOFT),
292 DECL(alSource3i64SOFT),
293 DECL(alSourcei64vSOFT),
294 DECL(alGetSourcei64SOFT),
295 DECL(alGetSource3i64SOFT),
296 DECL(alGetSourcei64vSOFT),
298 DECL(alGenSoundfontsSOFT),
299 DECL(alDeleteSoundfontsSOFT),
300 DECL(alIsSoundfontSOFT),
301 DECL(alGetSoundfontivSOFT),
302 DECL(alSoundfontPresetsSOFT),
303 DECL(alGenPresetsSOFT),
304 DECL(alDeletePresetsSOFT),
305 DECL(alIsPresetSOFT),
306 DECL(alPresetiSOFT),
307 DECL(alPresetivSOFT),
308 DECL(alGetPresetivSOFT),
309 DECL(alPresetFontsoundsSOFT),
310 DECL(alGenFontsoundsSOFT),
311 DECL(alDeleteFontsoundsSOFT),
312 DECL(alIsFontsoundSOFT),
313 DECL(alFontsoundiSOFT),
314 DECL(alFontsound2iSOFT),
315 DECL(alFontsoundivSOFT),
316 DECL(alGetFontsoundivSOFT),
317 DECL(alFontsoundModulatoriSOFT),
318 DECL(alGetFontsoundModulatorivSOFT),
319 DECL(alMidiSoundfontSOFT),
320 DECL(alMidiSoundfontvSOFT),
321 DECL(alMidiEventSOFT),
322 DECL(alMidiSysExSOFT),
323 DECL(alMidiPlaySOFT),
324 DECL(alMidiPauseSOFT),
325 DECL(alMidiStopSOFT),
326 DECL(alMidiResetSOFT),
327 DECL(alMidiGainSOFT),
328 DECL(alGetInteger64SOFT),
329 DECL(alGetInteger64vSOFT),
330 DECL(alLoadSoundfontSOFT),
332 { NULL, NULL }
334 #undef DECL
336 #define DECL(x) { #x, (x) }
337 static const ALCenums enumeration[] = {
338 DECL(ALC_INVALID),
339 DECL(ALC_FALSE),
340 DECL(ALC_TRUE),
342 DECL(ALC_MAJOR_VERSION),
343 DECL(ALC_MINOR_VERSION),
344 DECL(ALC_ATTRIBUTES_SIZE),
345 DECL(ALC_ALL_ATTRIBUTES),
346 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
347 DECL(ALC_DEVICE_SPECIFIER),
348 DECL(ALC_ALL_DEVICES_SPECIFIER),
349 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
350 DECL(ALC_EXTENSIONS),
351 DECL(ALC_FREQUENCY),
352 DECL(ALC_REFRESH),
353 DECL(ALC_SYNC),
354 DECL(ALC_MONO_SOURCES),
355 DECL(ALC_STEREO_SOURCES),
356 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
357 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
358 DECL(ALC_CAPTURE_SAMPLES),
359 DECL(ALC_CONNECTED),
361 DECL(ALC_EFX_MAJOR_VERSION),
362 DECL(ALC_EFX_MINOR_VERSION),
363 DECL(ALC_MAX_AUXILIARY_SENDS),
365 DECL(ALC_FORMAT_CHANNELS_SOFT),
366 DECL(ALC_FORMAT_TYPE_SOFT),
368 DECL(ALC_MONO_SOFT),
369 DECL(ALC_STEREO_SOFT),
370 DECL(ALC_QUAD_SOFT),
371 DECL(ALC_5POINT1_SOFT),
372 DECL(ALC_6POINT1_SOFT),
373 DECL(ALC_7POINT1_SOFT),
375 DECL(ALC_BYTE_SOFT),
376 DECL(ALC_UNSIGNED_BYTE_SOFT),
377 DECL(ALC_SHORT_SOFT),
378 DECL(ALC_UNSIGNED_SHORT_SOFT),
379 DECL(ALC_INT_SOFT),
380 DECL(ALC_UNSIGNED_INT_SOFT),
381 DECL(ALC_FLOAT_SOFT),
383 DECL(ALC_HRTF_SOFT),
384 DECL(ALC_DONT_CARE_SOFT),
385 DECL(ALC_HRTF_STATUS_SOFT),
386 DECL(ALC_HRTF_DISABLED_SOFT),
387 DECL(ALC_HRTF_ENABLED_SOFT),
388 DECL(ALC_HRTF_DENIED_SOFT),
389 DECL(ALC_HRTF_REQUIRED_SOFT),
390 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
391 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
393 DECL(ALC_NO_ERROR),
394 DECL(ALC_INVALID_DEVICE),
395 DECL(ALC_INVALID_CONTEXT),
396 DECL(ALC_INVALID_ENUM),
397 DECL(ALC_INVALID_VALUE),
398 DECL(ALC_OUT_OF_MEMORY),
401 DECL(AL_INVALID),
402 DECL(AL_NONE),
403 DECL(AL_FALSE),
404 DECL(AL_TRUE),
406 DECL(AL_SOURCE_RELATIVE),
407 DECL(AL_CONE_INNER_ANGLE),
408 DECL(AL_CONE_OUTER_ANGLE),
409 DECL(AL_PITCH),
410 DECL(AL_POSITION),
411 DECL(AL_DIRECTION),
412 DECL(AL_VELOCITY),
413 DECL(AL_LOOPING),
414 DECL(AL_BUFFER),
415 DECL(AL_GAIN),
416 DECL(AL_MIN_GAIN),
417 DECL(AL_MAX_GAIN),
418 DECL(AL_ORIENTATION),
419 DECL(AL_REFERENCE_DISTANCE),
420 DECL(AL_ROLLOFF_FACTOR),
421 DECL(AL_CONE_OUTER_GAIN),
422 DECL(AL_MAX_DISTANCE),
423 DECL(AL_SEC_OFFSET),
424 DECL(AL_SAMPLE_OFFSET),
425 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
426 DECL(AL_BYTE_OFFSET),
427 DECL(AL_BYTE_RW_OFFSETS_SOFT),
428 DECL(AL_SOURCE_TYPE),
429 DECL(AL_STATIC),
430 DECL(AL_STREAMING),
431 DECL(AL_UNDETERMINED),
432 DECL(AL_METERS_PER_UNIT),
433 DECL(AL_LOOP_POINTS_SOFT),
434 DECL(AL_DIRECT_CHANNELS_SOFT),
436 DECL(AL_DIRECT_FILTER),
437 DECL(AL_AUXILIARY_SEND_FILTER),
438 DECL(AL_AIR_ABSORPTION_FACTOR),
439 DECL(AL_ROOM_ROLLOFF_FACTOR),
440 DECL(AL_CONE_OUTER_GAINHF),
441 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
442 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
443 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
445 DECL(AL_SOURCE_STATE),
446 DECL(AL_INITIAL),
447 DECL(AL_PLAYING),
448 DECL(AL_PAUSED),
449 DECL(AL_STOPPED),
451 DECL(AL_BUFFERS_QUEUED),
452 DECL(AL_BUFFERS_PROCESSED),
454 DECL(AL_FORMAT_MONO8),
455 DECL(AL_FORMAT_MONO16),
456 DECL(AL_FORMAT_MONO_FLOAT32),
457 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
458 DECL(AL_FORMAT_STEREO8),
459 DECL(AL_FORMAT_STEREO16),
460 DECL(AL_FORMAT_STEREO_FLOAT32),
461 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
462 DECL(AL_FORMAT_MONO_IMA4),
463 DECL(AL_FORMAT_STEREO_IMA4),
464 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
465 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
466 DECL(AL_FORMAT_QUAD8_LOKI),
467 DECL(AL_FORMAT_QUAD16_LOKI),
468 DECL(AL_FORMAT_QUAD8),
469 DECL(AL_FORMAT_QUAD16),
470 DECL(AL_FORMAT_QUAD32),
471 DECL(AL_FORMAT_51CHN8),
472 DECL(AL_FORMAT_51CHN16),
473 DECL(AL_FORMAT_51CHN32),
474 DECL(AL_FORMAT_61CHN8),
475 DECL(AL_FORMAT_61CHN16),
476 DECL(AL_FORMAT_61CHN32),
477 DECL(AL_FORMAT_71CHN8),
478 DECL(AL_FORMAT_71CHN16),
479 DECL(AL_FORMAT_71CHN32),
480 DECL(AL_FORMAT_REAR8),
481 DECL(AL_FORMAT_REAR16),
482 DECL(AL_FORMAT_REAR32),
483 DECL(AL_FORMAT_MONO_MULAW),
484 DECL(AL_FORMAT_MONO_MULAW_EXT),
485 DECL(AL_FORMAT_STEREO_MULAW),
486 DECL(AL_FORMAT_STEREO_MULAW_EXT),
487 DECL(AL_FORMAT_QUAD_MULAW),
488 DECL(AL_FORMAT_51CHN_MULAW),
489 DECL(AL_FORMAT_61CHN_MULAW),
490 DECL(AL_FORMAT_71CHN_MULAW),
491 DECL(AL_FORMAT_REAR_MULAW),
492 DECL(AL_FORMAT_MONO_ALAW_EXT),
493 DECL(AL_FORMAT_STEREO_ALAW_EXT),
495 DECL(AL_MONO8_SOFT),
496 DECL(AL_MONO16_SOFT),
497 DECL(AL_MONO32F_SOFT),
498 DECL(AL_STEREO8_SOFT),
499 DECL(AL_STEREO16_SOFT),
500 DECL(AL_STEREO32F_SOFT),
501 DECL(AL_QUAD8_SOFT),
502 DECL(AL_QUAD16_SOFT),
503 DECL(AL_QUAD32F_SOFT),
504 DECL(AL_REAR8_SOFT),
505 DECL(AL_REAR16_SOFT),
506 DECL(AL_REAR32F_SOFT),
507 DECL(AL_5POINT1_8_SOFT),
508 DECL(AL_5POINT1_16_SOFT),
509 DECL(AL_5POINT1_32F_SOFT),
510 DECL(AL_6POINT1_8_SOFT),
511 DECL(AL_6POINT1_16_SOFT),
512 DECL(AL_6POINT1_32F_SOFT),
513 DECL(AL_7POINT1_8_SOFT),
514 DECL(AL_7POINT1_16_SOFT),
515 DECL(AL_7POINT1_32F_SOFT),
516 DECL(AL_FORMAT_BFORMAT2D_8),
517 DECL(AL_FORMAT_BFORMAT2D_16),
518 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
519 DECL(AL_FORMAT_BFORMAT2D_MULAW),
520 DECL(AL_FORMAT_BFORMAT3D_8),
521 DECL(AL_FORMAT_BFORMAT3D_16),
522 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
523 DECL(AL_FORMAT_BFORMAT3D_MULAW),
525 DECL(AL_MONO_SOFT),
526 DECL(AL_STEREO_SOFT),
527 DECL(AL_QUAD_SOFT),
528 DECL(AL_REAR_SOFT),
529 DECL(AL_5POINT1_SOFT),
530 DECL(AL_6POINT1_SOFT),
531 DECL(AL_7POINT1_SOFT),
533 DECL(AL_BYTE_SOFT),
534 DECL(AL_UNSIGNED_BYTE_SOFT),
535 DECL(AL_SHORT_SOFT),
536 DECL(AL_UNSIGNED_SHORT_SOFT),
537 DECL(AL_INT_SOFT),
538 DECL(AL_UNSIGNED_INT_SOFT),
539 DECL(AL_FLOAT_SOFT),
540 DECL(AL_DOUBLE_SOFT),
541 DECL(AL_BYTE3_SOFT),
542 DECL(AL_UNSIGNED_BYTE3_SOFT),
544 DECL(AL_FREQUENCY),
545 DECL(AL_BITS),
546 DECL(AL_CHANNELS),
547 DECL(AL_SIZE),
548 DECL(AL_INTERNAL_FORMAT_SOFT),
549 DECL(AL_BYTE_LENGTH_SOFT),
550 DECL(AL_SAMPLE_LENGTH_SOFT),
551 DECL(AL_SEC_LENGTH_SOFT),
552 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
553 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
555 DECL(AL_UNUSED),
556 DECL(AL_PENDING),
557 DECL(AL_PROCESSED),
559 DECL(AL_NO_ERROR),
560 DECL(AL_INVALID_NAME),
561 DECL(AL_INVALID_ENUM),
562 DECL(AL_INVALID_VALUE),
563 DECL(AL_INVALID_OPERATION),
564 DECL(AL_OUT_OF_MEMORY),
566 DECL(AL_VENDOR),
567 DECL(AL_VERSION),
568 DECL(AL_RENDERER),
569 DECL(AL_EXTENSIONS),
571 DECL(AL_DOPPLER_FACTOR),
572 DECL(AL_DOPPLER_VELOCITY),
573 DECL(AL_DISTANCE_MODEL),
574 DECL(AL_SPEED_OF_SOUND),
575 DECL(AL_SOURCE_DISTANCE_MODEL),
576 DECL(AL_DEFERRED_UPDATES_SOFT),
578 DECL(AL_INVERSE_DISTANCE),
579 DECL(AL_INVERSE_DISTANCE_CLAMPED),
580 DECL(AL_LINEAR_DISTANCE),
581 DECL(AL_LINEAR_DISTANCE_CLAMPED),
582 DECL(AL_EXPONENT_DISTANCE),
583 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
585 DECL(AL_FILTER_TYPE),
586 DECL(AL_FILTER_NULL),
587 DECL(AL_FILTER_LOWPASS),
588 DECL(AL_FILTER_HIGHPASS),
589 DECL(AL_FILTER_BANDPASS),
591 DECL(AL_LOWPASS_GAIN),
592 DECL(AL_LOWPASS_GAINHF),
594 DECL(AL_HIGHPASS_GAIN),
595 DECL(AL_HIGHPASS_GAINLF),
597 DECL(AL_BANDPASS_GAIN),
598 DECL(AL_BANDPASS_GAINHF),
599 DECL(AL_BANDPASS_GAINLF),
601 DECL(AL_EFFECT_TYPE),
602 DECL(AL_EFFECT_NULL),
603 DECL(AL_EFFECT_REVERB),
604 DECL(AL_EFFECT_EAXREVERB),
605 DECL(AL_EFFECT_CHORUS),
606 DECL(AL_EFFECT_DISTORTION),
607 DECL(AL_EFFECT_ECHO),
608 DECL(AL_EFFECT_FLANGER),
609 #if 0
610 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
611 DECL(AL_EFFECT_VOCAL_MORPHER),
612 DECL(AL_EFFECT_PITCH_SHIFTER),
613 #endif
614 DECL(AL_EFFECT_RING_MODULATOR),
615 #if 0
616 DECL(AL_EFFECT_AUTOWAH),
617 #endif
618 DECL(AL_EFFECT_COMPRESSOR),
619 DECL(AL_EFFECT_EQUALIZER),
620 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
621 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
623 DECL(AL_EAXREVERB_DENSITY),
624 DECL(AL_EAXREVERB_DIFFUSION),
625 DECL(AL_EAXREVERB_GAIN),
626 DECL(AL_EAXREVERB_GAINHF),
627 DECL(AL_EAXREVERB_GAINLF),
628 DECL(AL_EAXREVERB_DECAY_TIME),
629 DECL(AL_EAXREVERB_DECAY_HFRATIO),
630 DECL(AL_EAXREVERB_DECAY_LFRATIO),
631 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
632 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
633 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
634 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
635 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
636 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
637 DECL(AL_EAXREVERB_ECHO_TIME),
638 DECL(AL_EAXREVERB_ECHO_DEPTH),
639 DECL(AL_EAXREVERB_MODULATION_TIME),
640 DECL(AL_EAXREVERB_MODULATION_DEPTH),
641 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
642 DECL(AL_EAXREVERB_HFREFERENCE),
643 DECL(AL_EAXREVERB_LFREFERENCE),
644 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
645 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
647 DECL(AL_REVERB_DENSITY),
648 DECL(AL_REVERB_DIFFUSION),
649 DECL(AL_REVERB_GAIN),
650 DECL(AL_REVERB_GAINHF),
651 DECL(AL_REVERB_DECAY_TIME),
652 DECL(AL_REVERB_DECAY_HFRATIO),
653 DECL(AL_REVERB_REFLECTIONS_GAIN),
654 DECL(AL_REVERB_REFLECTIONS_DELAY),
655 DECL(AL_REVERB_LATE_REVERB_GAIN),
656 DECL(AL_REVERB_LATE_REVERB_DELAY),
657 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
658 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
659 DECL(AL_REVERB_DECAY_HFLIMIT),
661 DECL(AL_CHORUS_WAVEFORM),
662 DECL(AL_CHORUS_PHASE),
663 DECL(AL_CHORUS_RATE),
664 DECL(AL_CHORUS_DEPTH),
665 DECL(AL_CHORUS_FEEDBACK),
666 DECL(AL_CHORUS_DELAY),
668 DECL(AL_DISTORTION_EDGE),
669 DECL(AL_DISTORTION_GAIN),
670 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
671 DECL(AL_DISTORTION_EQCENTER),
672 DECL(AL_DISTORTION_EQBANDWIDTH),
674 DECL(AL_ECHO_DELAY),
675 DECL(AL_ECHO_LRDELAY),
676 DECL(AL_ECHO_DAMPING),
677 DECL(AL_ECHO_FEEDBACK),
678 DECL(AL_ECHO_SPREAD),
680 DECL(AL_FLANGER_WAVEFORM),
681 DECL(AL_FLANGER_PHASE),
682 DECL(AL_FLANGER_RATE),
683 DECL(AL_FLANGER_DEPTH),
684 DECL(AL_FLANGER_FEEDBACK),
685 DECL(AL_FLANGER_DELAY),
687 DECL(AL_RING_MODULATOR_FREQUENCY),
688 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
689 DECL(AL_RING_MODULATOR_WAVEFORM),
691 #if 0
692 DECL(AL_AUTOWAH_ATTACK_TIME),
693 DECL(AL_AUTOWAH_PEAK_GAIN),
694 DECL(AL_AUTOWAH_RELEASE_TIME),
695 DECL(AL_AUTOWAH_RESONANCE),
696 #endif
698 DECL(AL_COMPRESSOR_ONOFF),
700 DECL(AL_EQUALIZER_LOW_GAIN),
701 DECL(AL_EQUALIZER_LOW_CUTOFF),
702 DECL(AL_EQUALIZER_MID1_GAIN),
703 DECL(AL_EQUALIZER_MID1_CENTER),
704 DECL(AL_EQUALIZER_MID1_WIDTH),
705 DECL(AL_EQUALIZER_MID2_GAIN),
706 DECL(AL_EQUALIZER_MID2_CENTER),
707 DECL(AL_EQUALIZER_MID2_WIDTH),
708 DECL(AL_EQUALIZER_HIGH_GAIN),
709 DECL(AL_EQUALIZER_HIGH_CUTOFF),
711 DECL(AL_DEDICATED_GAIN),
713 { NULL, (ALCenum)0 }
715 #undef DECL
717 static const ALCchar alcNoError[] = "No Error";
718 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
719 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
720 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
721 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
722 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
725 /************************************************
726 * Global variables
727 ************************************************/
729 /* Enumerated device names */
730 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
732 static al_string alcAllDevicesList;
733 static al_string alcCaptureDeviceList;
735 /* Default is always the first in the list */
736 static ALCchar *alcDefaultAllDevicesSpecifier;
737 static ALCchar *alcCaptureDefaultDeviceSpecifier;
739 /* Default context extensions */
740 static const ALchar alExtList[] =
741 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
742 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
743 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
744 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
745 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
746 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
747 "AL_SOFT_source_latency AL_SOFT_source_length";
749 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
751 /* Thread-local current context */
752 static altss_t LocalContext;
753 /* Process-wide current context */
754 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
756 /* Mixing thread piority level */
757 ALint RTPrioLevel;
759 FILE *LogFile;
760 #ifdef _DEBUG
761 enum LogLevel LogLevel = LogWarning;
762 #else
763 enum LogLevel LogLevel = LogError;
764 #endif
766 /* Flag to trap ALC device errors */
767 static ALCboolean TrapALCError = ALC_FALSE;
769 /* One-time configuration init control */
770 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
772 /* Default effect that applies to sources that don't have an effect on send 0 */
773 static ALeffect DefaultEffect;
775 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
776 * updates.
778 static ALCboolean SuspendDefers = ALC_TRUE;
781 /************************************************
782 * ALC information
783 ************************************************/
784 static const ALCchar alcNoDeviceExtList[] =
785 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
786 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
787 static const ALCchar alcExtensionList[] =
788 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
789 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
790 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
791 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
792 static const ALCint alcMajorVersion = 1;
793 static const ALCint alcMinorVersion = 1;
795 static const ALCint alcEFXMajorVersion = 1;
796 static const ALCint alcEFXMinorVersion = 0;
799 /************************************************
800 * Device lists
801 ************************************************/
802 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
804 static almtx_t ListLock;
805 static inline void LockLists(void)
807 int lockret = almtx_lock(&ListLock);
808 assert(lockret == althrd_success);
810 static inline void UnlockLists(void)
812 int unlockret = almtx_unlock(&ListLock);
813 assert(unlockret == althrd_success);
816 /************************************************
817 * Library initialization
818 ************************************************/
819 #if defined(_WIN32)
820 static void alc_init(void);
821 static void alc_deinit(void);
822 static void alc_deinit_safe(void);
824 #ifndef AL_LIBTYPE_STATIC
825 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
827 switch(reason)
829 case DLL_PROCESS_ATTACH:
830 /* Pin the DLL so we won't get unloaded until the process terminates */
831 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
832 (WCHAR*)hModule, &hModule);
833 alc_init();
834 break;
836 case DLL_THREAD_DETACH:
837 break;
839 case DLL_PROCESS_DETACH:
840 if(!lpReserved)
841 alc_deinit();
842 else
843 alc_deinit_safe();
844 break;
846 return TRUE;
848 #elif defined(_MSC_VER)
849 #pragma section(".CRT$XCU",read)
850 static void alc_constructor(void);
851 static void alc_destructor(void);
852 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
854 static void alc_constructor(void)
856 atexit(alc_destructor);
857 alc_init();
860 static void alc_destructor(void)
862 alc_deinit();
864 #elif defined(HAVE_GCC_DESTRUCTOR)
865 static void alc_init(void) __attribute__((constructor));
866 static void alc_deinit(void) __attribute__((destructor));
867 #else
868 #error "No static initialization available on this platform!"
869 #endif
871 #elif defined(HAVE_GCC_DESTRUCTOR)
873 static void alc_init(void) __attribute__((constructor));
874 static void alc_deinit(void) __attribute__((destructor));
876 #else
877 #error "No global initialization available on this platform!"
878 #endif
880 static void ReleaseThreadCtx(void *ptr);
881 static void alc_init(void)
883 const char *str;
884 int ret;
886 LogFile = stderr;
888 AL_STRING_INIT(alcAllDevicesList);
889 AL_STRING_INIT(alcCaptureDeviceList);
891 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
892 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
893 ConeScale *= 0.5f;
895 str = getenv("__ALSOFT_REVERSE_Z");
896 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
897 ZScale *= -1.0f;
899 ret = altss_create(&LocalContext, ReleaseThreadCtx);
900 assert(ret == althrd_success);
902 ret = almtx_init(&ListLock, almtx_recursive);
903 assert(ret == althrd_success);
905 ThunkInit();
908 static void alc_initconfig(void)
910 const char *devs, *str;
911 ALuint capfilter;
912 float valf;
913 int i, n;
915 str = getenv("ALSOFT_LOGLEVEL");
916 if(str)
918 long lvl = strtol(str, NULL, 0);
919 if(lvl >= NoLog && lvl <= LogRef)
920 LogLevel = lvl;
923 str = getenv("ALSOFT_LOGFILE");
924 if(str && str[0])
926 FILE *logfile = al_fopen(str, "wt");
927 if(logfile) LogFile = logfile;
928 else ERR("Failed to open log file '%s'\n", str);
932 char buf[1024] = "";
933 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
934 for(i = 1;BackendList[i].name;i++)
935 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
936 TRACE("Supported backends: %s\n", buf);
938 ReadALConfig();
940 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
941 if(str && *str)
943 if(strcasecmp(str, "ignore") == 0)
945 SuspendDefers = ALC_FALSE;
946 TRACE("Selected context suspend behavior, \"ignore\"\n");
948 else
949 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
952 capfilter = 0;
953 #if defined(HAVE_SSE4_1)
954 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE4_1;
955 #elif defined(HAVE_SSE2)
956 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
957 #elif defined(HAVE_SSE)
958 capfilter |= CPU_CAP_SSE;
959 #endif
960 #ifdef HAVE_NEON
961 capfilter |= CPU_CAP_NEON;
962 #endif
963 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
965 if(strcasecmp(str, "all") == 0)
966 capfilter = 0;
967 else
969 size_t len;
970 const char *next = str;
972 do {
973 str = next;
974 while(isspace(str[0]))
975 str++;
976 next = strchr(str, ',');
978 if(!str[0] || str[0] == ',')
979 continue;
981 len = (next ? ((size_t)(next-str)) : strlen(str));
982 while(len > 0 && isspace(str[len-1]))
983 len--;
984 if(len == 3 && strncasecmp(str, "sse", len) == 0)
985 capfilter &= ~CPU_CAP_SSE;
986 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
987 capfilter &= ~CPU_CAP_SSE2;
988 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
989 capfilter &= ~CPU_CAP_SSE4_1;
990 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
991 capfilter &= ~CPU_CAP_NEON;
992 else
993 WARN("Invalid CPU extension \"%s\"\n", str);
994 } while(next++);
997 FillCPUCaps(capfilter);
999 #ifdef _WIN32
1000 RTPrioLevel = 1;
1001 #else
1002 RTPrioLevel = 0;
1003 #endif
1004 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
1006 if(ConfigValueStr(NULL, NULL, "resampler", &str))
1008 if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
1009 DefaultResampler = PointResampler;
1010 else if(strcasecmp(str, "linear") == 0)
1011 DefaultResampler = LinearResampler;
1012 else if(strcasecmp(str, "sinc4") == 0)
1013 DefaultResampler = FIR4Resampler;
1014 else if(strcasecmp(str, "cubic") == 0)
1016 ERR("Resampler option \"cubic\" is deprecated, using sinc4\n");
1017 DefaultResampler = FIR4Resampler;
1019 else
1021 char *end;
1022 n = strtol(str, &end, 0);
1023 if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == FIR4Resampler))
1024 DefaultResampler = n;
1025 else
1026 WARN("Invalid resampler: %s\n", str);
1029 aluInitMixer();
1031 str = getenv("ALSOFT_TRAP_ERROR");
1032 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1034 TrapALError = AL_TRUE;
1035 TrapALCError = AL_TRUE;
1037 else
1039 str = getenv("ALSOFT_TRAP_AL_ERROR");
1040 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1041 TrapALError = AL_TRUE;
1042 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1044 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1045 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1046 TrapALCError = ALC_TRUE;
1047 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1050 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1051 ReverbBoost *= powf(10.0f, valf / 20.0f);
1053 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1055 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1056 ConfigValueStr(NULL, NULL, "drivers", &devs))
1058 int n;
1059 size_t len;
1060 const char *next = devs;
1061 int endlist, delitem;
1063 i = 0;
1064 do {
1065 devs = next;
1066 while(isspace(devs[0]))
1067 devs++;
1068 next = strchr(devs, ',');
1070 delitem = (devs[0] == '-');
1071 if(devs[0] == '-') devs++;
1073 if(!devs[0] || devs[0] == ',')
1075 endlist = 0;
1076 continue;
1078 endlist = 1;
1080 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1081 while(len > 0 && isspace(devs[len-1]))
1082 len--;
1083 for(n = i;BackendList[n].name;n++)
1085 if(len == strlen(BackendList[n].name) &&
1086 strncmp(BackendList[n].name, devs, len) == 0)
1088 if(delitem)
1090 do {
1091 BackendList[n] = BackendList[n+1];
1092 ++n;
1093 } while(BackendList[n].name);
1095 else
1097 struct BackendInfo Bkp = BackendList[n];
1098 while(n > i)
1100 BackendList[n] = BackendList[n-1];
1101 --n;
1103 BackendList[n] = Bkp;
1105 i++;
1107 break;
1110 } while(next++);
1112 if(endlist)
1114 BackendList[i].name = NULL;
1115 BackendList[i].getFactory = NULL;
1116 BackendList[i].Init = NULL;
1117 BackendList[i].Deinit = NULL;
1118 BackendList[i].Probe = NULL;
1122 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1124 if(BackendList[i].getFactory)
1126 ALCbackendFactory *factory = BackendList[i].getFactory();
1127 if(!V0(factory,init)())
1129 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1130 continue;
1133 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1134 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1136 PlaybackBackend = BackendList[i];
1137 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1139 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1141 CaptureBackend = BackendList[i];
1142 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1145 continue;
1148 if(!BackendList[i].Init(&BackendList[i].Funcs))
1150 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1151 continue;
1154 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1155 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1157 PlaybackBackend = BackendList[i];
1158 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1160 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1162 CaptureBackend = BackendList[i];
1163 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1167 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1168 V0(factory,init)();
1171 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1173 size_t len;
1174 const char *next = str;
1176 do {
1177 str = next;
1178 next = strchr(str, ',');
1180 if(!str[0] || next == str)
1181 continue;
1183 len = (next ? ((size_t)(next-str)) : strlen(str));
1184 for(n = 0;EffectList[n].name;n++)
1186 if(len == strlen(EffectList[n].name) &&
1187 strncmp(EffectList[n].name, str, len) == 0)
1188 DisabledEffects[EffectList[n].type] = AL_TRUE;
1190 } while(next++);
1193 InitEffectFactoryMap();
1195 InitEffect(&DefaultEffect);
1196 str = getenv("ALSOFT_DEFAULT_REVERB");
1197 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1198 LoadReverbPreset(str, &DefaultEffect);
1200 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1203 /************************************************
1204 * Library deinitialization
1205 ************************************************/
1206 static void alc_cleanup(void)
1208 ALCdevice *dev;
1210 AL_STRING_DEINIT(alcAllDevicesList);
1211 AL_STRING_DEINIT(alcCaptureDeviceList);
1213 free(alcDefaultAllDevicesSpecifier);
1214 alcDefaultAllDevicesSpecifier = NULL;
1215 free(alcCaptureDefaultDeviceSpecifier);
1216 alcCaptureDefaultDeviceSpecifier = NULL;
1218 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1220 ALCuint num = 0;
1221 do {
1222 num++;
1223 } while((dev=dev->next) != NULL);
1224 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1227 DeinitEffectFactoryMap();
1230 static void alc_deinit_safe(void)
1232 alc_cleanup();
1234 FreeHrtfs();
1235 FreeALConfig();
1237 ThunkExit();
1238 almtx_destroy(&ListLock);
1239 altss_delete(LocalContext);
1241 if(LogFile != stderr)
1242 fclose(LogFile);
1243 LogFile = NULL;
1246 static void alc_deinit(void)
1248 int i;
1250 alc_cleanup();
1252 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1253 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1255 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1257 if(!BackendList[i].getFactory)
1258 BackendList[i].Deinit();
1259 else
1261 ALCbackendFactory *factory = BackendList[i].getFactory();
1262 V0(factory,deinit)();
1266 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1267 V0(factory,deinit)();
1270 alc_deinit_safe();
1274 /************************************************
1275 * Device enumeration
1276 ************************************************/
1277 static void ProbeDevices(al_string *list, enum DevProbe type)
1279 DO_INITCONFIG();
1281 LockLists();
1282 al_string_clear(list);
1284 if(type == ALL_DEVICE_PROBE && (PlaybackBackend.Probe || PlaybackBackend.getFactory))
1286 if(!PlaybackBackend.getFactory)
1287 PlaybackBackend.Probe(type);
1288 else
1290 ALCbackendFactory *factory = PlaybackBackend.getFactory();
1291 V(factory,probe)(type);
1294 else if(type == CAPTURE_DEVICE_PROBE && (CaptureBackend.Probe || CaptureBackend.getFactory))
1296 if(!CaptureBackend.getFactory)
1297 CaptureBackend.Probe(type);
1298 else
1300 ALCbackendFactory *factory = CaptureBackend.getFactory();
1301 V(factory,probe)(type);
1304 UnlockLists();
1306 static void ProbeAllDevicesList(void)
1307 { ProbeDevices(&alcAllDevicesList, ALL_DEVICE_PROBE); }
1308 static void ProbeCaptureDeviceList(void)
1309 { ProbeDevices(&alcCaptureDeviceList, CAPTURE_DEVICE_PROBE); }
1311 static void AppendDevice(const ALCchar *name, al_string *devnames)
1313 size_t len = strlen(name);
1314 if(len > 0)
1315 al_string_append_range(devnames, name, name+len+1);
1317 void AppendAllDevicesList(const ALCchar *name)
1318 { AppendDevice(name, &alcAllDevicesList); }
1319 void AppendCaptureDeviceList(const ALCchar *name)
1320 { AppendDevice(name, &alcCaptureDeviceList); }
1323 /************************************************
1324 * Device format information
1325 ************************************************/
1326 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1328 switch(type)
1330 case DevFmtByte: return "Signed Byte";
1331 case DevFmtUByte: return "Unsigned Byte";
1332 case DevFmtShort: return "Signed Short";
1333 case DevFmtUShort: return "Unsigned Short";
1334 case DevFmtInt: return "Signed Int";
1335 case DevFmtUInt: return "Unsigned Int";
1336 case DevFmtFloat: return "Float";
1338 return "(unknown type)";
1340 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1342 switch(chans)
1344 case DevFmtMono: return "Mono";
1345 case DevFmtStereo: return "Stereo";
1346 case DevFmtQuad: return "Quadraphonic";
1347 case DevFmtX51: return "5.1 Surround";
1348 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1349 case DevFmtX61: return "6.1 Surround";
1350 case DevFmtX71: return "7.1 Surround";
1351 case DevFmtBFormat3D: return "B-Format 3D";
1353 return "(unknown channels)";
1356 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1357 ALuint BytesFromDevFmt(enum DevFmtType type)
1359 switch(type)
1361 case DevFmtByte: return sizeof(ALbyte);
1362 case DevFmtUByte: return sizeof(ALubyte);
1363 case DevFmtShort: return sizeof(ALshort);
1364 case DevFmtUShort: return sizeof(ALushort);
1365 case DevFmtInt: return sizeof(ALint);
1366 case DevFmtUInt: return sizeof(ALuint);
1367 case DevFmtFloat: return sizeof(ALfloat);
1369 return 0;
1371 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1373 switch(chans)
1375 case DevFmtMono: return 1;
1376 case DevFmtStereo: return 2;
1377 case DevFmtQuad: return 4;
1378 case DevFmtX51: return 6;
1379 case DevFmtX51Rear: return 6;
1380 case DevFmtX61: return 7;
1381 case DevFmtX71: return 8;
1382 case DevFmtBFormat3D: return 4;
1384 return 0;
1387 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1388 enum DevFmtChannels *chans, enum DevFmtType *type)
1390 static const struct {
1391 ALenum format;
1392 enum DevFmtChannels channels;
1393 enum DevFmtType type;
1394 } list[] = {
1395 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1396 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1397 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1399 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1400 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1401 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1403 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1404 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1405 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1407 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1408 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1409 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1411 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1412 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1413 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1415 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1416 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1417 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1419 ALuint i;
1421 for(i = 0;i < COUNTOF(list);i++)
1423 if(list[i].format == format)
1425 *chans = list[i].channels;
1426 *type = list[i].type;
1427 return AL_TRUE;
1431 return AL_FALSE;
1434 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1436 switch(type)
1438 case ALC_BYTE_SOFT:
1439 case ALC_UNSIGNED_BYTE_SOFT:
1440 case ALC_SHORT_SOFT:
1441 case ALC_UNSIGNED_SHORT_SOFT:
1442 case ALC_INT_SOFT:
1443 case ALC_UNSIGNED_INT_SOFT:
1444 case ALC_FLOAT_SOFT:
1445 return ALC_TRUE;
1447 return ALC_FALSE;
1450 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1452 switch(channels)
1454 case ALC_MONO_SOFT:
1455 case ALC_STEREO_SOFT:
1456 case ALC_QUAD_SOFT:
1457 case ALC_5POINT1_SOFT:
1458 case ALC_6POINT1_SOFT:
1459 case ALC_7POINT1_SOFT:
1460 return ALC_TRUE;
1462 return ALC_FALSE;
1466 /************************************************
1467 * Miscellaneous ALC helpers
1468 ************************************************/
1469 enum HrtfRequestMode {
1470 Hrtf_Default = 0,
1471 Hrtf_Enable = 1,
1472 Hrtf_Disable = 2,
1475 extern inline void LockContext(ALCcontext *context);
1476 extern inline void UnlockContext(ALCcontext *context);
1478 void ALCdevice_Lock(ALCdevice *device)
1480 V0(device->Backend,lock)();
1483 void ALCdevice_Unlock(ALCdevice *device)
1485 V0(device->Backend,unlock)();
1489 /* SetDefaultWFXChannelOrder
1491 * Sets the default channel order used by WaveFormatEx.
1493 void SetDefaultWFXChannelOrder(ALCdevice *device)
1495 ALuint i;
1497 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1498 device->ChannelName[i] = InvalidChannel;
1500 switch(device->FmtChans)
1502 case DevFmtMono:
1503 device->ChannelName[0] = FrontCenter;
1504 break;
1505 case DevFmtStereo:
1506 device->ChannelName[0] = FrontLeft;
1507 device->ChannelName[1] = FrontRight;
1508 break;
1509 case DevFmtQuad:
1510 device->ChannelName[0] = FrontLeft;
1511 device->ChannelName[1] = FrontRight;
1512 device->ChannelName[2] = BackLeft;
1513 device->ChannelName[3] = BackRight;
1514 break;
1515 case DevFmtX51:
1516 device->ChannelName[0] = FrontLeft;
1517 device->ChannelName[1] = FrontRight;
1518 device->ChannelName[2] = FrontCenter;
1519 device->ChannelName[3] = LFE;
1520 device->ChannelName[4] = SideLeft;
1521 device->ChannelName[5] = SideRight;
1522 break;
1523 case DevFmtX51Rear:
1524 device->ChannelName[0] = FrontLeft;
1525 device->ChannelName[1] = FrontRight;
1526 device->ChannelName[2] = FrontCenter;
1527 device->ChannelName[3] = LFE;
1528 device->ChannelName[4] = BackLeft;
1529 device->ChannelName[5] = BackRight;
1530 break;
1531 case DevFmtX61:
1532 device->ChannelName[0] = FrontLeft;
1533 device->ChannelName[1] = FrontRight;
1534 device->ChannelName[2] = FrontCenter;
1535 device->ChannelName[3] = LFE;
1536 device->ChannelName[4] = BackCenter;
1537 device->ChannelName[5] = SideLeft;
1538 device->ChannelName[6] = SideRight;
1539 break;
1540 case DevFmtX71:
1541 device->ChannelName[0] = FrontLeft;
1542 device->ChannelName[1] = FrontRight;
1543 device->ChannelName[2] = FrontCenter;
1544 device->ChannelName[3] = LFE;
1545 device->ChannelName[4] = BackLeft;
1546 device->ChannelName[5] = BackRight;
1547 device->ChannelName[6] = SideLeft;
1548 device->ChannelName[7] = SideRight;
1549 break;
1550 case DevFmtBFormat3D:
1551 device->ChannelName[0] = BFormatW;
1552 device->ChannelName[1] = BFormatX;
1553 device->ChannelName[2] = BFormatY;
1554 device->ChannelName[3] = BFormatZ;
1555 break;
1559 /* SetDefaultChannelOrder
1561 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1563 void SetDefaultChannelOrder(ALCdevice *device)
1565 ALuint i;
1567 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1568 device->ChannelName[i] = InvalidChannel;
1570 switch(device->FmtChans)
1572 case DevFmtX51Rear:
1573 device->ChannelName[0] = FrontLeft;
1574 device->ChannelName[1] = FrontRight;
1575 device->ChannelName[2] = BackLeft;
1576 device->ChannelName[3] = BackRight;
1577 device->ChannelName[4] = FrontCenter;
1578 device->ChannelName[5] = LFE;
1579 return;
1580 case DevFmtX71:
1581 device->ChannelName[0] = FrontLeft;
1582 device->ChannelName[1] = FrontRight;
1583 device->ChannelName[2] = BackLeft;
1584 device->ChannelName[3] = BackRight;
1585 device->ChannelName[4] = FrontCenter;
1586 device->ChannelName[5] = LFE;
1587 device->ChannelName[6] = SideLeft;
1588 device->ChannelName[7] = SideRight;
1589 return;
1591 /* Same as WFX order */
1592 case DevFmtMono:
1593 case DevFmtStereo:
1594 case DevFmtQuad:
1595 case DevFmtX51:
1596 case DevFmtX61:
1597 case DevFmtBFormat3D:
1598 SetDefaultWFXChannelOrder(device);
1599 break;
1603 extern inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan);
1606 /* ALCcontext_DeferUpdates
1608 * Defers/suspends updates for the given context's listener and sources. This
1609 * does *NOT* stop mixing, but rather prevents certain property changes from
1610 * taking effect.
1612 void ALCcontext_DeferUpdates(ALCcontext *context)
1614 ALCdevice *device = context->Device;
1615 FPUCtl oldMode;
1617 SetMixerFPUMode(&oldMode);
1619 V0(device->Backend,lock)();
1620 if(!context->DeferUpdates)
1622 context->DeferUpdates = AL_TRUE;
1624 /* Make sure all pending updates are performed */
1625 UpdateContextSources(context);
1626 #define UPDATE_SLOT(iter) do { \
1627 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1628 V((*iter)->EffectState,update)(device, *iter); \
1629 } while(0)
1630 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1631 #undef UPDATE_SLOT
1633 V0(device->Backend,unlock)();
1635 RestoreFPUMode(&oldMode);
1638 /* ALCcontext_ProcessUpdates
1640 * Resumes update processing after being deferred.
1642 void ALCcontext_ProcessUpdates(ALCcontext *context)
1644 ALCdevice *device = context->Device;
1646 V0(device->Backend,lock)();
1647 if(context->DeferUpdates)
1649 ALsizei pos;
1651 context->DeferUpdates = AL_FALSE;
1653 LockUIntMapRead(&context->SourceMap);
1654 for(pos = 0;pos < context->SourceMap.size;pos++)
1656 ALsource *Source = context->SourceMap.array[pos].value;
1657 ALenum new_state;
1659 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1660 Source->Offset >= 0.0)
1662 ReadLock(&Source->queue_lock);
1663 ApplyOffset(Source);
1664 ReadUnlock(&Source->queue_lock);
1667 new_state = Source->new_state;
1668 Source->new_state = AL_NONE;
1669 if(new_state)
1670 SetSourceState(Source, context, new_state);
1672 UnlockUIntMapRead(&context->SourceMap);
1674 V0(device->Backend,unlock)();
1678 /* alcSetError
1680 * Stores the latest ALC device error
1682 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1684 if(TrapALCError)
1686 #ifdef _WIN32
1687 /* DebugBreak() will cause an exception if there is no debugger */
1688 if(IsDebuggerPresent())
1689 DebugBreak();
1690 #elif defined(SIGTRAP)
1691 raise(SIGTRAP);
1692 #endif
1695 if(device)
1696 ATOMIC_STORE(&device->LastError, errorCode);
1697 else
1698 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1702 /* UpdateClockBase
1704 * Updates the device's base clock time with however many samples have been
1705 * done. This is used so frequency changes on the device don't cause the time
1706 * to jump forward or back.
1708 static inline void UpdateClockBase(ALCdevice *device)
1710 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1711 device->SamplesDone = 0;
1714 /* UpdateDeviceParams
1716 * Updates device parameters according to the attribute list (caller is
1717 * responsible for holding the list lock).
1719 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1721 ALCcontext *context;
1722 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1723 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1724 enum DevFmtChannels oldChans;
1725 enum DevFmtType oldType;
1726 ALCuint oldFreq;
1727 FPUCtl oldMode;
1728 size_t size;
1730 // Check for attributes
1731 if(device->Type == Loopback)
1733 enum {
1734 GotFreq = 1<<0,
1735 GotChans = 1<<1,
1736 GotType = 1<<2,
1737 GotAll = GotFreq|GotChans|GotType
1739 ALCuint freq, numMono, numStereo, numSends;
1740 enum DevFmtChannels schans;
1741 enum DevFmtType stype;
1742 ALCuint attrIdx = 0;
1743 ALCint gotFmt = 0;
1745 if(!attrList)
1747 WARN("Missing attributes for loopback device\n");
1748 return ALC_INVALID_VALUE;
1751 numMono = device->NumMonoSources;
1752 numStereo = device->NumStereoSources;
1753 numSends = device->NumAuxSends;
1754 schans = device->FmtChans;
1755 stype = device->FmtType;
1756 freq = device->Frequency;
1758 while(attrList[attrIdx])
1760 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1762 ALCint val = attrList[attrIdx + 1];
1763 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1764 return ALC_INVALID_VALUE;
1765 schans = val;
1766 gotFmt |= GotChans;
1769 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1771 ALCint val = attrList[attrIdx + 1];
1772 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1773 return ALC_INVALID_VALUE;
1774 stype = val;
1775 gotFmt |= GotType;
1778 if(attrList[attrIdx] == ALC_FREQUENCY)
1780 freq = attrList[attrIdx + 1];
1781 if(freq < MIN_OUTPUT_RATE)
1782 return ALC_INVALID_VALUE;
1783 gotFmt |= GotFreq;
1786 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1788 numStereo = attrList[attrIdx + 1];
1789 if(numStereo > device->MaxNoOfSources)
1790 numStereo = device->MaxNoOfSources;
1792 numMono = device->MaxNoOfSources - numStereo;
1795 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1796 numSends = attrList[attrIdx + 1];
1798 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1800 if(attrList[attrIdx + 1] == ALC_FALSE)
1801 hrtf_appreq = Hrtf_Disable;
1802 else if(attrList[attrIdx + 1] == ALC_TRUE)
1803 hrtf_appreq = Hrtf_Enable;
1804 else
1805 hrtf_appreq = Hrtf_Default;
1808 attrIdx += 2;
1811 if(gotFmt != GotAll)
1813 WARN("Missing format for loopback device\n");
1814 return ALC_INVALID_VALUE;
1817 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1818 numSends = minu(MAX_SENDS, numSends);
1820 if((device->Flags&DEVICE_RUNNING))
1821 V0(device->Backend,stop)();
1822 device->Flags &= ~DEVICE_RUNNING;
1824 UpdateClockBase(device);
1826 device->Frequency = freq;
1827 device->FmtChans = schans;
1828 device->FmtType = stype;
1829 device->NumMonoSources = numMono;
1830 device->NumStereoSources = numStereo;
1831 device->NumAuxSends = numSends;
1833 else if(attrList && attrList[0])
1835 ALCuint freq, numMono, numStereo, numSends;
1836 ALCuint attrIdx = 0;
1838 /* If a context is already running on the device, stop playback so the
1839 * device attributes can be updated. */
1840 if((device->Flags&DEVICE_RUNNING))
1841 V0(device->Backend,stop)();
1842 device->Flags &= ~DEVICE_RUNNING;
1844 freq = device->Frequency;
1845 numMono = device->NumMonoSources;
1846 numStereo = device->NumStereoSources;
1847 numSends = device->NumAuxSends;
1849 while(attrList[attrIdx])
1851 if(attrList[attrIdx] == ALC_FREQUENCY)
1853 freq = attrList[attrIdx + 1];
1854 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1857 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1859 numStereo = attrList[attrIdx + 1];
1860 if(numStereo > device->MaxNoOfSources)
1861 numStereo = device->MaxNoOfSources;
1863 numMono = device->MaxNoOfSources - numStereo;
1866 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1867 numSends = attrList[attrIdx + 1];
1869 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1871 if(attrList[attrIdx + 1] == ALC_FALSE)
1872 hrtf_appreq = Hrtf_Disable;
1873 else if(attrList[attrIdx + 1] == ALC_TRUE)
1874 hrtf_appreq = Hrtf_Enable;
1875 else
1876 hrtf_appreq = Hrtf_Default;
1879 attrIdx += 2;
1882 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1883 freq = maxu(freq, MIN_OUTPUT_RATE);
1885 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1886 numSends = minu(MAX_SENDS, numSends);
1888 UpdateClockBase(device);
1890 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1891 device->Frequency;
1892 /* SSE and Neon do best with the update size being a multiple of 4 */
1893 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1894 device->UpdateSize = (device->UpdateSize+3)&~3;
1896 device->Frequency = freq;
1897 device->NumMonoSources = numMono;
1898 device->NumStereoSources = numStereo;
1899 device->NumAuxSends = numSends;
1902 if((device->Flags&DEVICE_RUNNING))
1903 return ALC_NO_ERROR;
1905 al_free(device->DryBuffer);
1906 device->DryBuffer = NULL;
1908 UpdateClockBase(device);
1910 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1911 if(device->Type != Loopback)
1913 const char *hrtf;
1914 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1916 if(strcasecmp(hrtf, "true") == 0)
1917 hrtf_userreq = Hrtf_Enable;
1918 else if(strcasecmp(hrtf, "false") == 0)
1919 hrtf_userreq = Hrtf_Disable;
1920 else if(strcasecmp(hrtf, "auto") != 0)
1921 ERR("Unexpected hrtf value: %s\n", hrtf);
1924 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1926 if(FindHrtfFormat(device->DeviceName, &device->FmtChans, &device->Frequency))
1927 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1928 else
1930 hrtf_userreq = hrtf_appreq = Hrtf_Default;
1931 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1935 else if(hrtf_appreq == Hrtf_Enable)
1937 enum DevFmtChannels chans = device->FmtChans;
1938 ALCuint freq = device->Frequency;
1939 if(!FindHrtfFormat(device->DeviceName, &chans, &freq) ||
1940 chans != device->FmtChans || freq != device->Frequency)
1942 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1943 DevFmtChannelsString(device->FmtChans), device->Frequency);
1944 hrtf_appreq = Hrtf_Default;
1945 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1949 oldFreq = device->Frequency;
1950 oldChans = device->FmtChans;
1951 oldType = device->FmtType;
1953 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1954 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1955 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1956 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1957 device->UpdateSize, device->NumUpdates
1960 if(V0(device->Backend,reset)() == ALC_FALSE)
1961 return ALC_INVALID_DEVICE;
1963 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1965 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1966 DevFmtChannelsString(device->FmtChans));
1967 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1969 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1971 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1972 DevFmtTypeString(device->FmtType));
1973 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1975 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1977 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1978 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1981 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1982 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1983 device->Frequency, device->UpdateSize, device->NumUpdates
1986 if((device->UpdateSize&3) != 0)
1988 if((CPUCapFlags&CPU_CAP_SSE))
1989 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1990 if((CPUCapFlags&CPU_CAP_NEON))
1991 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1994 device->Hrtf = NULL;
1995 device->Hrtf_Mode = DisabledHrtf;
1996 if(device->FmtChans != DevFmtStereo)
1998 if(hrtf_appreq == Hrtf_Enable)
1999 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2001 free(device->Bs2b);
2002 device->Bs2b = NULL;
2004 else
2006 bool headphones = device->IsHeadphones;
2007 enum HrtfMode hrtf_mode = FullHrtf;
2008 ALCenum hrtf_status = device->Hrtf_Status;
2009 const char *mode;
2010 int bs2blevel;
2011 int usehrtf;
2013 if(device->Type != Loopback)
2015 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
2017 if(strcasecmp(mode, "headphones") == 0)
2018 headphones = true;
2019 else if(strcasecmp(mode, "speakers") == 0)
2020 headphones = false;
2021 else if(strcasecmp(mode, "auto") != 0)
2022 ERR("Unexpected stereo-mode: %s\n", mode);
2025 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
2027 if(strcasecmp(mode, "full") == 0)
2028 hrtf_mode = FullHrtf;
2029 else if(strcasecmp(mode, "basic") == 0)
2030 hrtf_mode = BasicHrtf;
2031 else
2032 ERR("Unexpected hrtf-mode: %s\n", mode);
2037 if(hrtf_userreq == Hrtf_Default)
2039 usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
2040 (hrtf_appreq == Hrtf_Enable);
2041 if(headphones && hrtf_appreq != Hrtf_Disable)
2042 hrtf_status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
2043 else if(usehrtf)
2044 hrtf_status = ALC_HRTF_ENABLED_SOFT;
2046 else
2048 usehrtf = (hrtf_userreq == Hrtf_Enable);
2049 if(!usehrtf)
2050 hrtf_status = ALC_HRTF_DENIED_SOFT;
2051 else
2052 hrtf_status = ALC_HRTF_REQUIRED_SOFT;
2055 if(!usehrtf)
2056 device->Hrtf_Status = hrtf_status;
2057 else
2059 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2060 device->Hrtf = GetHrtf(device->DeviceName, device->FmtChans, device->Frequency);
2062 if(device->Hrtf)
2064 device->Hrtf_Mode = hrtf_mode;
2065 device->Hrtf_Status = hrtf_status;
2066 TRACE("HRTF enabled\n");
2067 free(device->Bs2b);
2068 device->Bs2b = NULL;
2070 else
2072 TRACE("HRTF disabled\n");
2074 bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
2075 (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
2076 if(device->Type != Loopback)
2077 ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
2078 if(bs2blevel > 0 && bs2blevel <= 6)
2080 if(!device->Bs2b)
2082 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
2083 bs2b_clear(device->Bs2b);
2085 bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
2086 TRACE("BS2B enabled\n");
2088 else
2090 free(device->Bs2b);
2091 device->Bs2b = NULL;
2092 TRACE("BS2B disabled\n");
2097 aluInitPanning(device);
2099 /* With HRTF, allocate two extra channels for the post-filter output. */
2100 size = sizeof(device->DryBuffer[0]) * (device->NumChannels + (device->Hrtf ? 2 : 0));
2101 device->DryBuffer = al_calloc(16, size);
2102 if(!device->DryBuffer)
2104 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2105 return ALC_INVALID_DEVICE;
2108 V(device->Synth,update)(device);
2110 SetMixerFPUMode(&oldMode);
2111 V0(device->Backend,lock)();
2112 context = ATOMIC_LOAD(&device->ContextList);
2113 while(context)
2115 ALsizei pos;
2117 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2118 LockUIntMapRead(&context->EffectSlotMap);
2119 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2121 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2123 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2125 UnlockUIntMapRead(&context->EffectSlotMap);
2126 V0(device->Backend,unlock)();
2127 RestoreFPUMode(&oldMode);
2128 return ALC_INVALID_DEVICE;
2130 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2131 V(slot->EffectState,update)(device, slot);
2133 UnlockUIntMapRead(&context->EffectSlotMap);
2135 LockUIntMapRead(&context->SourceMap);
2136 for(pos = 0;pos < context->SourceMap.size;pos++)
2138 ALsource *source = context->SourceMap.array[pos].value;
2139 ALuint s = device->NumAuxSends;
2140 while(s < MAX_SENDS)
2142 if(source->Send[s].Slot)
2143 DecrementRef(&source->Send[s].Slot->ref);
2144 source->Send[s].Slot = NULL;
2145 source->Send[s].Gain = 1.0f;
2146 source->Send[s].GainHF = 1.0f;
2147 s++;
2149 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2151 UnlockUIntMapRead(&context->SourceMap);
2153 for(pos = 0;pos < context->VoiceCount;pos++)
2155 ALvoice *voice = &context->Voices[pos];
2156 ALsource *source = voice->Source;
2157 ALuint s = device->NumAuxSends;
2159 while(s < MAX_SENDS)
2161 voice->Send[s].Moving = AL_FALSE;
2162 voice->Send[s].Counter = 0;
2163 s++;
2166 if(source)
2168 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2169 voice->Update(voice, source, context);
2173 context = context->next;
2175 if(device->DefaultSlot)
2177 ALeffectslot *slot = device->DefaultSlot;
2179 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2181 V0(device->Backend,unlock)();
2182 RestoreFPUMode(&oldMode);
2183 return ALC_INVALID_DEVICE;
2185 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2186 V(slot->EffectState,update)(device, slot);
2188 V0(device->Backend,unlock)();
2189 RestoreFPUMode(&oldMode);
2191 if(!(device->Flags&DEVICE_PAUSED))
2193 if(V0(device->Backend,start)() == ALC_FALSE)
2194 return ALC_INVALID_DEVICE;
2195 device->Flags |= DEVICE_RUNNING;
2198 return ALC_NO_ERROR;
2201 /* FreeDevice
2203 * Frees the device structure, and destroys any objects the app failed to
2204 * delete. Called once there's no more references on the device.
2206 static ALCvoid FreeDevice(ALCdevice *device)
2208 TRACE("%p\n", device);
2210 V0(device->Backend,close)();
2211 DELETE_OBJ(device->Backend);
2212 device->Backend = NULL;
2214 DELETE_OBJ(device->Synth);
2215 device->Synth = NULL;
2217 if(device->DefaultSlot)
2219 ALeffectState *state = device->DefaultSlot->EffectState;
2220 device->DefaultSlot = NULL;
2221 DELETE_OBJ(state);
2224 if(device->DefaultSfont)
2225 ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
2226 device->DefaultSfont = NULL;
2228 if(device->BufferMap.size > 0)
2230 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2231 ReleaseALBuffers(device);
2233 ResetUIntMap(&device->BufferMap);
2235 if(device->EffectMap.size > 0)
2237 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2238 ReleaseALEffects(device);
2240 ResetUIntMap(&device->EffectMap);
2242 if(device->FilterMap.size > 0)
2244 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2245 ReleaseALFilters(device);
2247 ResetUIntMap(&device->FilterMap);
2249 if(device->SfontMap.size > 0)
2251 WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size);
2252 ReleaseALSoundfonts(device);
2254 ResetUIntMap(&device->SfontMap);
2256 if(device->PresetMap.size > 0)
2258 WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size);
2259 ReleaseALPresets(device);
2261 ResetUIntMap(&device->PresetMap);
2263 if(device->FontsoundMap.size > 0)
2265 WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size);
2266 ReleaseALFontsounds(device);
2268 ResetUIntMap(&device->FontsoundMap);
2270 free(device->Bs2b);
2271 device->Bs2b = NULL;
2273 AL_STRING_DEINIT(device->DeviceName);
2275 al_free(device->DryBuffer);
2276 device->DryBuffer = NULL;
2278 al_free(device);
2282 void ALCdevice_IncRef(ALCdevice *device)
2284 uint ref;
2285 ref = IncrementRef(&device->ref);
2286 TRACEREF("%p increasing refcount to %u\n", device, ref);
2289 void ALCdevice_DecRef(ALCdevice *device)
2291 uint ref;
2292 ref = DecrementRef(&device->ref);
2293 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2294 if(ref == 0) FreeDevice(device);
2297 /* VerifyDevice
2299 * Checks if the device handle is valid, and increments its ref count if so.
2301 static ALCdevice *VerifyDevice(ALCdevice *device)
2303 ALCdevice *tmpDevice;
2305 if(!device)
2306 return NULL;
2308 LockLists();
2309 tmpDevice = ATOMIC_LOAD(&DeviceList);
2310 while(tmpDevice && tmpDevice != device)
2311 tmpDevice = tmpDevice->next;
2313 if(tmpDevice)
2314 ALCdevice_IncRef(tmpDevice);
2315 UnlockLists();
2316 return tmpDevice;
2320 /* InitContext
2322 * Initializes context fields
2324 static ALvoid InitContext(ALCcontext *Context)
2326 ALlistener *listener = Context->Listener;
2327 //Initialise listener
2328 listener->Gain = 1.0f;
2329 listener->MetersPerUnit = 1.0f;
2330 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2331 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2332 listener->Forward[0] = 0.0f;
2333 listener->Forward[1] = 0.0f;
2334 listener->Forward[2] = -1.0f;
2335 listener->Up[0] = 0.0f;
2336 listener->Up[1] = 1.0f;
2337 listener->Up[2] = 0.0f;
2338 aluMatrixSet(&listener->Params.Matrix,
2339 1.0f, 0.0f, 0.0f, 0.0f,
2340 0.0f, 1.0f, 0.0f, 0.0f,
2341 0.0f, 0.0f, 1.0f, 0.0f,
2342 0.0f, 0.0f, 0.0f, 1.0f
2344 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2346 //Validate Context
2347 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2348 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2349 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2350 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2352 //Set globals
2353 Context->DistanceModel = DefaultDistanceModel;
2354 Context->SourceDistanceModel = AL_FALSE;
2355 Context->DopplerFactor = 1.0f;
2356 Context->DopplerVelocity = 1.0f;
2357 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2358 Context->DeferUpdates = AL_FALSE;
2360 Context->ExtensionList = alExtList;
2364 /* FreeContext
2366 * Cleans up the context, and destroys any remaining objects the app failed to
2367 * delete. Called once there's no more references on the context.
2369 static void FreeContext(ALCcontext *context)
2371 TRACE("%p\n", context);
2373 if(context->SourceMap.size > 0)
2375 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2376 ReleaseALSources(context);
2378 ResetUIntMap(&context->SourceMap);
2380 if(context->EffectSlotMap.size > 0)
2382 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2383 ReleaseALAuxiliaryEffectSlots(context);
2385 ResetUIntMap(&context->EffectSlotMap);
2387 al_free(context->Voices);
2388 context->Voices = NULL;
2389 context->VoiceCount = 0;
2390 context->MaxVoices = 0;
2392 VECTOR_DEINIT(context->ActiveAuxSlots);
2394 ALCdevice_DecRef(context->Device);
2395 context->Device = NULL;
2397 //Invalidate context
2398 memset(context, 0, sizeof(ALCcontext));
2399 al_free(context);
2402 /* ReleaseContext
2404 * Removes the context reference from the given device and removes it from
2405 * being current on the running thread or globally.
2407 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2409 ALCcontext *nextctx;
2410 ALCcontext *origctx;
2412 if(altss_get(LocalContext) == context)
2414 WARN("%p released while current on thread\n", context);
2415 altss_set(LocalContext, NULL);
2416 ALCcontext_DecRef(context);
2419 origctx = context;
2420 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2421 ALCcontext_DecRef(context);
2423 ALCdevice_Lock(device);
2424 origctx = context;
2425 nextctx = context->next;
2426 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2428 ALCcontext *list;
2429 do {
2430 list = origctx;
2431 origctx = context;
2432 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2434 ALCdevice_Unlock(device);
2436 ALCcontext_DecRef(context);
2439 void ALCcontext_IncRef(ALCcontext *context)
2441 uint ref;
2442 ref = IncrementRef(&context->ref);
2443 TRACEREF("%p increasing refcount to %u\n", context, ref);
2446 void ALCcontext_DecRef(ALCcontext *context)
2448 uint ref;
2449 ref = DecrementRef(&context->ref);
2450 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2451 if(ref == 0) FreeContext(context);
2454 static void ReleaseThreadCtx(void *ptr)
2456 WARN("%p current for thread being destroyed\n", ptr);
2457 ALCcontext_DecRef(ptr);
2460 /* VerifyContext
2462 * Checks that the given context is valid, and increments its reference count.
2464 static ALCcontext *VerifyContext(ALCcontext *context)
2466 ALCdevice *dev;
2468 LockLists();
2469 dev = ATOMIC_LOAD(&DeviceList);
2470 while(dev)
2472 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2473 while(ctx)
2475 if(ctx == context)
2477 ALCcontext_IncRef(ctx);
2478 UnlockLists();
2479 return ctx;
2481 ctx = ctx->next;
2483 dev = dev->next;
2485 UnlockLists();
2487 return NULL;
2491 /* GetContextRef
2493 * Returns the currently active context for this thread, and adds a reference
2494 * without locking it.
2496 ALCcontext *GetContextRef(void)
2498 ALCcontext *context;
2500 context = altss_get(LocalContext);
2501 if(context)
2502 ALCcontext_IncRef(context);
2503 else
2505 LockLists();
2506 context = ATOMIC_LOAD(&GlobalContext);
2507 if(context)
2508 ALCcontext_IncRef(context);
2509 UnlockLists();
2512 return context;
2516 /************************************************
2517 * Standard ALC functions
2518 ************************************************/
2520 /* alcGetError
2522 * Return last ALC generated error code for the given device
2524 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2526 ALCenum errorCode;
2528 if(VerifyDevice(device))
2530 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2531 ALCdevice_DecRef(device);
2533 else
2534 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2536 return errorCode;
2540 /* alcSuspendContext
2542 * Suspends updates for the given context
2544 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2546 if(!SuspendDefers)
2547 return;
2549 context = VerifyContext(context);
2550 if(!context)
2551 alcSetError(NULL, ALC_INVALID_CONTEXT);
2552 else
2554 ALCcontext_DeferUpdates(context);
2555 ALCcontext_DecRef(context);
2559 /* alcProcessContext
2561 * Resumes processing updates for the given context
2563 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2565 if(!SuspendDefers)
2566 return;
2568 context = VerifyContext(context);
2569 if(!context)
2570 alcSetError(NULL, ALC_INVALID_CONTEXT);
2571 else
2573 ALCcontext_ProcessUpdates(context);
2574 ALCcontext_DecRef(context);
2579 /* alcGetString
2581 * Returns information about the device, and error strings
2583 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2585 const ALCchar *value = NULL;
2587 switch(param)
2589 case ALC_NO_ERROR:
2590 value = alcNoError;
2591 break;
2593 case ALC_INVALID_ENUM:
2594 value = alcErrInvalidEnum;
2595 break;
2597 case ALC_INVALID_VALUE:
2598 value = alcErrInvalidValue;
2599 break;
2601 case ALC_INVALID_DEVICE:
2602 value = alcErrInvalidDevice;
2603 break;
2605 case ALC_INVALID_CONTEXT:
2606 value = alcErrInvalidContext;
2607 break;
2609 case ALC_OUT_OF_MEMORY:
2610 value = alcErrOutOfMemory;
2611 break;
2613 case ALC_DEVICE_SPECIFIER:
2614 value = alcDefaultName;
2615 break;
2617 case ALC_ALL_DEVICES_SPECIFIER:
2618 if(VerifyDevice(Device))
2620 value = al_string_get_cstr(Device->DeviceName);
2621 ALCdevice_DecRef(Device);
2623 else
2625 ProbeAllDevicesList();
2626 value = al_string_get_cstr(alcAllDevicesList);
2628 break;
2630 case ALC_CAPTURE_DEVICE_SPECIFIER:
2631 if(VerifyDevice(Device))
2633 value = al_string_get_cstr(Device->DeviceName);
2634 ALCdevice_DecRef(Device);
2636 else
2638 ProbeCaptureDeviceList();
2639 value = al_string_get_cstr(alcCaptureDeviceList);
2641 break;
2643 /* Default devices are always first in the list */
2644 case ALC_DEFAULT_DEVICE_SPECIFIER:
2645 value = alcDefaultName;
2646 break;
2648 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2649 if(al_string_empty(alcAllDevicesList))
2650 ProbeAllDevicesList();
2652 Device = VerifyDevice(Device);
2654 free(alcDefaultAllDevicesSpecifier);
2655 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2656 if(!alcDefaultAllDevicesSpecifier)
2657 alcSetError(Device, ALC_OUT_OF_MEMORY);
2659 value = alcDefaultAllDevicesSpecifier;
2660 if(Device) ALCdevice_DecRef(Device);
2661 break;
2663 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2664 if(al_string_empty(alcCaptureDeviceList))
2665 ProbeCaptureDeviceList();
2667 Device = VerifyDevice(Device);
2669 free(alcCaptureDefaultDeviceSpecifier);
2670 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2671 if(!alcCaptureDefaultDeviceSpecifier)
2672 alcSetError(Device, ALC_OUT_OF_MEMORY);
2674 value = alcCaptureDefaultDeviceSpecifier;
2675 if(Device) ALCdevice_DecRef(Device);
2676 break;
2678 case ALC_EXTENSIONS:
2679 if(!VerifyDevice(Device))
2680 value = alcNoDeviceExtList;
2681 else
2683 value = alcExtensionList;
2684 ALCdevice_DecRef(Device);
2686 break;
2688 default:
2689 Device = VerifyDevice(Device);
2690 alcSetError(Device, ALC_INVALID_ENUM);
2691 if(Device) ALCdevice_DecRef(Device);
2692 break;
2695 return value;
2699 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2701 ALCsizei i;
2703 if(size <= 0 || values == NULL)
2705 alcSetError(device, ALC_INVALID_VALUE);
2706 return 0;
2709 if(!device)
2711 switch(param)
2713 case ALC_MAJOR_VERSION:
2714 values[0] = alcMajorVersion;
2715 return 1;
2716 case ALC_MINOR_VERSION:
2717 values[0] = alcMinorVersion;
2718 return 1;
2720 case ALC_ATTRIBUTES_SIZE:
2721 case ALC_ALL_ATTRIBUTES:
2722 case ALC_FREQUENCY:
2723 case ALC_REFRESH:
2724 case ALC_SYNC:
2725 case ALC_MONO_SOURCES:
2726 case ALC_STEREO_SOURCES:
2727 case ALC_CAPTURE_SAMPLES:
2728 case ALC_FORMAT_CHANNELS_SOFT:
2729 case ALC_FORMAT_TYPE_SOFT:
2730 alcSetError(NULL, ALC_INVALID_DEVICE);
2731 return 0;
2733 default:
2734 alcSetError(NULL, ALC_INVALID_ENUM);
2735 return 0;
2737 return 0;
2740 if(device->Type == Capture)
2742 switch(param)
2744 case ALC_CAPTURE_SAMPLES:
2745 V0(device->Backend,lock)();
2746 values[0] = V0(device->Backend,availableSamples)();
2747 V0(device->Backend,unlock)();
2748 return 1;
2750 case ALC_CONNECTED:
2751 values[0] = device->Connected;
2752 return 1;
2754 default:
2755 alcSetError(device, ALC_INVALID_ENUM);
2756 return 0;
2758 return 0;
2761 /* render device */
2762 switch(param)
2764 case ALC_MAJOR_VERSION:
2765 values[0] = alcMajorVersion;
2766 return 1;
2768 case ALC_MINOR_VERSION:
2769 values[0] = alcMinorVersion;
2770 return 1;
2772 case ALC_EFX_MAJOR_VERSION:
2773 values[0] = alcEFXMajorVersion;
2774 return 1;
2776 case ALC_EFX_MINOR_VERSION:
2777 values[0] = alcEFXMinorVersion;
2778 return 1;
2780 case ALC_ATTRIBUTES_SIZE:
2781 values[0] = 17;
2782 return 1;
2784 case ALC_ALL_ATTRIBUTES:
2785 if(size < 17)
2787 alcSetError(device, ALC_INVALID_VALUE);
2788 return 0;
2791 i = 0;
2792 values[i++] = ALC_FREQUENCY;
2793 values[i++] = device->Frequency;
2795 if(device->Type != Loopback)
2797 values[i++] = ALC_REFRESH;
2798 values[i++] = device->Frequency / device->UpdateSize;
2800 values[i++] = ALC_SYNC;
2801 values[i++] = ALC_FALSE;
2803 else
2805 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2806 values[i++] = device->FmtChans;
2808 values[i++] = ALC_FORMAT_TYPE_SOFT;
2809 values[i++] = device->FmtType;
2812 values[i++] = ALC_MONO_SOURCES;
2813 values[i++] = device->NumMonoSources;
2815 values[i++] = ALC_STEREO_SOURCES;
2816 values[i++] = device->NumStereoSources;
2818 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2819 values[i++] = device->NumAuxSends;
2821 values[i++] = ALC_HRTF_SOFT;
2822 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2824 values[i++] = ALC_HRTF_STATUS_SOFT;
2825 values[i++] = device->Hrtf_Status;
2827 values[i++] = 0;
2828 return i;
2830 case ALC_FREQUENCY:
2831 values[0] = device->Frequency;
2832 return 1;
2834 case ALC_REFRESH:
2835 if(device->Type == Loopback)
2837 alcSetError(device, ALC_INVALID_DEVICE);
2838 return 0;
2840 values[0] = device->Frequency / device->UpdateSize;
2841 return 1;
2843 case ALC_SYNC:
2844 if(device->Type == Loopback)
2846 alcSetError(device, ALC_INVALID_DEVICE);
2847 return 0;
2849 values[0] = ALC_FALSE;
2850 return 1;
2852 case ALC_FORMAT_CHANNELS_SOFT:
2853 if(device->Type != Loopback)
2855 alcSetError(device, ALC_INVALID_DEVICE);
2856 return 0;
2858 values[0] = device->FmtChans;
2859 return 1;
2861 case ALC_FORMAT_TYPE_SOFT:
2862 if(device->Type != Loopback)
2864 alcSetError(device, ALC_INVALID_DEVICE);
2865 return 0;
2867 values[0] = device->FmtType;
2868 return 1;
2870 case ALC_MONO_SOURCES:
2871 values[0] = device->NumMonoSources;
2872 return 1;
2874 case ALC_STEREO_SOURCES:
2875 values[0] = device->NumStereoSources;
2876 return 1;
2878 case ALC_MAX_AUXILIARY_SENDS:
2879 values[0] = device->NumAuxSends;
2880 return 1;
2882 case ALC_CONNECTED:
2883 values[0] = device->Connected;
2884 return 1;
2886 case ALC_HRTF_SOFT:
2887 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2888 return 1;
2890 case ALC_HRTF_STATUS_SOFT:
2891 values[0] = device->Hrtf_Status;
2892 return 1;
2894 default:
2895 alcSetError(device, ALC_INVALID_ENUM);
2896 return 0;
2898 return 0;
2901 /* alcGetIntegerv
2903 * Returns information about the device and the version of OpenAL
2905 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2907 device = VerifyDevice(device);
2908 if(size <= 0 || values == NULL)
2909 alcSetError(device, ALC_INVALID_VALUE);
2910 else
2911 GetIntegerv(device, param, size, values);
2912 if(device) ALCdevice_DecRef(device);
2915 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2917 ALCint *ivals;
2918 ALsizei i;
2920 device = VerifyDevice(device);
2921 if(size <= 0 || values == NULL)
2922 alcSetError(device, ALC_INVALID_VALUE);
2923 else if(!device || device->Type == Capture)
2925 ivals = malloc(size * sizeof(ALCint));
2926 size = GetIntegerv(device, pname, size, ivals);
2927 for(i = 0;i < size;i++)
2928 values[i] = ivals[i];
2929 free(ivals);
2931 else /* render device */
2933 switch(pname)
2935 case ALC_ATTRIBUTES_SIZE:
2936 *values = 19;
2937 break;
2939 case ALC_ALL_ATTRIBUTES:
2940 if(size < 19)
2941 alcSetError(device, ALC_INVALID_VALUE);
2942 else
2944 int i = 0;
2946 V0(device->Backend,lock)();
2947 values[i++] = ALC_FREQUENCY;
2948 values[i++] = device->Frequency;
2950 if(device->Type != Loopback)
2952 values[i++] = ALC_REFRESH;
2953 values[i++] = device->Frequency / device->UpdateSize;
2955 values[i++] = ALC_SYNC;
2956 values[i++] = ALC_FALSE;
2958 else
2960 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2961 values[i++] = device->FmtChans;
2963 values[i++] = ALC_FORMAT_TYPE_SOFT;
2964 values[i++] = device->FmtType;
2967 values[i++] = ALC_MONO_SOURCES;
2968 values[i++] = device->NumMonoSources;
2970 values[i++] = ALC_STEREO_SOURCES;
2971 values[i++] = device->NumStereoSources;
2973 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2974 values[i++] = device->NumAuxSends;
2976 values[i++] = ALC_HRTF_SOFT;
2977 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2979 values[i++] = ALC_HRTF_STATUS_SOFT;
2980 values[i++] = device->Hrtf_Status;
2982 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2983 values[i++] = device->ClockBase +
2984 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2986 values[i++] = 0;
2987 V0(device->Backend,unlock)();
2989 break;
2991 case ALC_DEVICE_CLOCK_SOFT:
2992 V0(device->Backend,lock)();
2993 *values = device->ClockBase +
2994 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2995 V0(device->Backend,unlock)();
2996 break;
2998 default:
2999 ivals = malloc(size * sizeof(ALCint));
3000 size = GetIntegerv(device, pname, size, ivals);
3001 for(i = 0;i < size;i++)
3002 values[i] = ivals[i];
3003 free(ivals);
3004 break;
3007 if(device)
3008 ALCdevice_DecRef(device);
3012 /* alcIsExtensionPresent
3014 * Determines if there is support for a particular extension
3016 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3018 ALCboolean bResult = ALC_FALSE;
3020 device = VerifyDevice(device);
3022 if(!extName)
3023 alcSetError(device, ALC_INVALID_VALUE);
3024 else
3026 size_t len = strlen(extName);
3027 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3028 while(ptr && *ptr)
3030 if(strncasecmp(ptr, extName, len) == 0 &&
3031 (ptr[len] == '\0' || isspace(ptr[len])))
3033 bResult = ALC_TRUE;
3034 break;
3036 if((ptr=strchr(ptr, ' ')) != NULL)
3038 do {
3039 ++ptr;
3040 } while(isspace(*ptr));
3044 if(device)
3045 ALCdevice_DecRef(device);
3046 return bResult;
3050 /* alcGetProcAddress
3052 * Retrieves the function address for a particular extension function
3054 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3056 ALCvoid *ptr = NULL;
3058 if(!funcName)
3060 device = VerifyDevice(device);
3061 alcSetError(device, ALC_INVALID_VALUE);
3062 if(device) ALCdevice_DecRef(device);
3064 else
3066 ALsizei i = 0;
3067 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3068 i++;
3069 ptr = alcFunctions[i].address;
3072 return ptr;
3076 /* alcGetEnumValue
3078 * Get the value for a particular ALC enumeration name
3080 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3082 ALCenum val = 0;
3084 if(!enumName)
3086 device = VerifyDevice(device);
3087 alcSetError(device, ALC_INVALID_VALUE);
3088 if(device) ALCdevice_DecRef(device);
3090 else
3092 ALsizei i = 0;
3093 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3094 i++;
3095 val = enumeration[i].value;
3098 return val;
3102 /* alcCreateContext
3104 * Create and attach a context to the given device.
3106 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3108 ALCcontext *ALContext;
3109 ALCenum err;
3111 LockLists();
3112 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
3114 UnlockLists();
3115 alcSetError(device, ALC_INVALID_DEVICE);
3116 if(device) ALCdevice_DecRef(device);
3117 return NULL;
3120 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3122 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3124 UnlockLists();
3125 alcSetError(device, err);
3126 if(err == ALC_INVALID_DEVICE)
3128 V0(device->Backend,lock)();
3129 aluHandleDisconnect(device);
3130 V0(device->Backend,unlock)();
3132 ALCdevice_DecRef(device);
3133 return NULL;
3136 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3137 if(ALContext)
3139 InitRef(&ALContext->ref, 1);
3140 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3142 VECTOR_INIT(ALContext->ActiveAuxSlots);
3144 ALContext->VoiceCount = 0;
3145 ALContext->MaxVoices = 256;
3146 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3148 if(!ALContext || !ALContext->Voices)
3150 if(!ATOMIC_LOAD(&device->ContextList))
3152 V0(device->Backend,stop)();
3153 device->Flags &= ~DEVICE_RUNNING;
3155 UnlockLists();
3157 if(ALContext)
3159 al_free(ALContext->Voices);
3160 ALContext->Voices = NULL;
3162 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3164 al_free(ALContext);
3165 ALContext = NULL;
3168 alcSetError(device, ALC_OUT_OF_MEMORY);
3169 ALCdevice_DecRef(device);
3170 return NULL;
3173 ALContext->Device = device;
3174 ALCdevice_IncRef(device);
3175 InitContext(ALContext);
3178 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3179 do {
3180 ALContext->next = head;
3181 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3183 UnlockLists();
3185 ALCdevice_DecRef(device);
3187 TRACE("Created context %p\n", ALContext);
3188 return ALContext;
3191 /* alcDestroyContext
3193 * Remove a context from its device
3195 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3197 ALCdevice *Device;
3199 LockLists();
3200 /* alcGetContextsDevice sets an error for invalid contexts */
3201 Device = alcGetContextsDevice(context);
3202 if(Device)
3204 ReleaseContext(context, Device);
3205 if(!ATOMIC_LOAD(&Device->ContextList))
3207 V0(Device->Backend,stop)();
3208 Device->Flags &= ~DEVICE_RUNNING;
3211 UnlockLists();
3215 /* alcGetCurrentContext
3217 * Returns the currently active context on the calling thread
3219 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3221 ALCcontext *Context = altss_get(LocalContext);
3222 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3223 return Context;
3226 /* alcGetThreadContext
3228 * Returns the currently active thread-local context
3230 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3232 return altss_get(LocalContext);
3236 /* alcMakeContextCurrent
3238 * Makes the given context the active process-wide context, and removes the
3239 * thread-local context for the calling thread.
3241 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3243 /* context must be valid or NULL */
3244 if(context && !(context=VerifyContext(context)))
3246 alcSetError(NULL, ALC_INVALID_CONTEXT);
3247 return ALC_FALSE;
3249 /* context's reference count is already incremented */
3250 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3251 if(context) ALCcontext_DecRef(context);
3253 if((context=altss_get(LocalContext)) != NULL)
3255 altss_set(LocalContext, NULL);
3256 ALCcontext_DecRef(context);
3259 return ALC_TRUE;
3262 /* alcSetThreadContext
3264 * Makes the given context the active context for the current thread
3266 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3268 ALCcontext *old;
3270 /* context must be valid or NULL */
3271 if(context && !(context=VerifyContext(context)))
3273 alcSetError(NULL, ALC_INVALID_CONTEXT);
3274 return ALC_FALSE;
3276 /* context's reference count is already incremented */
3277 old = altss_get(LocalContext);
3278 altss_set(LocalContext, context);
3279 if(old) ALCcontext_DecRef(old);
3281 return ALC_TRUE;
3285 /* alcGetContextsDevice
3287 * Returns the device that a particular context is attached to
3289 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3291 ALCdevice *Device;
3293 if(!(Context=VerifyContext(Context)))
3295 alcSetError(NULL, ALC_INVALID_CONTEXT);
3296 return NULL;
3298 Device = Context->Device;
3299 ALCcontext_DecRef(Context);
3301 return Device;
3305 /* alcResetDeviceSOFT
3307 * Resets the given device output, using the specified attribute list.
3309 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
3311 ALCenum err;
3313 LockLists();
3314 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
3316 UnlockLists();
3317 alcSetError(device, ALC_INVALID_DEVICE);
3318 if(device) ALCdevice_DecRef(device);
3319 return ALC_FALSE;
3322 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
3324 UnlockLists();
3325 alcSetError(device, err);
3326 if(err == ALC_INVALID_DEVICE)
3328 V0(device->Backend,lock)();
3329 aluHandleDisconnect(device);
3330 V0(device->Backend,unlock)();
3332 ALCdevice_DecRef(device);
3333 return ALC_FALSE;
3335 UnlockLists();
3336 ALCdevice_DecRef(device);
3338 return ALC_TRUE;
3341 /* alcOpenDevice
3343 * Opens the named device.
3345 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3347 const ALCchar *fmt;
3348 ALCdevice *device;
3349 ALCenum err;
3351 DO_INITCONFIG();
3353 if(!PlaybackBackend.name)
3355 alcSetError(NULL, ALC_INVALID_VALUE);
3356 return NULL;
3359 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3360 #ifdef _WIN32
3361 /* Some old Windows apps hardcode these expecting OpenAL to use a
3362 * specific audio API, even when they're not enumerated. Creative's
3363 * router effectively ignores them too.
3365 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3366 || strcasecmp(deviceName, "MMSYSTEM") == 0
3367 #endif
3369 deviceName = NULL;
3371 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3372 if(!device)
3374 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3375 return NULL;
3378 //Validate device
3379 InitRef(&device->ref, 1);
3380 device->Connected = ALC_TRUE;
3381 device->Type = Playback;
3382 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3384 device->Flags = 0;
3385 device->Bs2b = NULL;
3386 device->Hrtf_Mode = DisabledHrtf;
3387 AL_STRING_INIT(device->DeviceName);
3388 device->DryBuffer = NULL;
3390 ATOMIC_INIT(&device->ContextList, NULL);
3392 device->ClockBase = 0;
3393 device->SamplesDone = 0;
3395 device->MaxNoOfSources = 256;
3396 device->AuxiliaryEffectSlotMax = 4;
3397 device->NumAuxSends = MAX_SENDS;
3399 InitUIntMap(&device->BufferMap, ~0);
3400 InitUIntMap(&device->EffectMap, ~0);
3401 InitUIntMap(&device->FilterMap, ~0);
3402 InitUIntMap(&device->SfontMap, ~0);
3403 InitUIntMap(&device->PresetMap, ~0);
3404 InitUIntMap(&device->FontsoundMap, ~0);
3406 //Set output format
3407 device->FmtChans = DevFmtChannelsDefault;
3408 device->FmtType = DevFmtTypeDefault;
3409 device->Frequency = DEFAULT_OUTPUT_RATE;
3410 device->IsHeadphones = AL_FALSE;
3411 device->NumUpdates = 4;
3412 device->UpdateSize = 1024;
3414 if(!PlaybackBackend.getFactory)
3415 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3416 ALCbackend_Playback);
3417 else
3419 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3420 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3422 if(!device->Backend)
3424 al_free(device);
3425 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3426 return NULL;
3430 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3432 static const struct {
3433 const char name[16];
3434 enum DevFmtChannels chans;
3435 } chanlist[] = {
3436 { "mono", DevFmtMono },
3437 { "stereo", DevFmtStereo },
3438 { "quad", DevFmtQuad },
3439 { "surround51", DevFmtX51 },
3440 { "surround61", DevFmtX61 },
3441 { "surround71", DevFmtX71 },
3442 { "surround51rear", DevFmtX51Rear },
3444 size_t i;
3446 for(i = 0;i < COUNTOF(chanlist);i++)
3448 if(strcasecmp(chanlist[i].name, fmt) == 0)
3450 device->FmtChans = chanlist[i].chans;
3451 device->Flags |= DEVICE_CHANNELS_REQUEST;
3452 break;
3455 if(i == COUNTOF(chanlist))
3456 ERR("Unsupported channels: %s\n", fmt);
3458 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3460 static const struct {
3461 const char name[16];
3462 enum DevFmtType type;
3463 } typelist[] = {
3464 { "int8", DevFmtByte },
3465 { "uint8", DevFmtUByte },
3466 { "int16", DevFmtShort },
3467 { "uint16", DevFmtUShort },
3468 { "int32", DevFmtInt },
3469 { "uint32", DevFmtUInt },
3470 { "float32", DevFmtFloat },
3472 size_t i;
3474 for(i = 0;i < COUNTOF(typelist);i++)
3476 if(strcasecmp(typelist[i].name, fmt) == 0)
3478 device->FmtType = typelist[i].type;
3479 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3480 break;
3483 if(i == COUNTOF(typelist))
3484 ERR("Unsupported sample-type: %s\n", fmt);
3487 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3489 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3490 if(device->Frequency < MIN_OUTPUT_RATE)
3491 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3492 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3495 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3496 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3498 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3499 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3500 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3501 device->UpdateSize = (device->UpdateSize+3)&~3;
3503 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3504 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3506 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3507 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3509 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3510 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3512 device->NumStereoSources = 1;
3513 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3515 device->Synth = SynthCreate(device);
3516 if(!device->Synth)
3518 DELETE_OBJ(device->Backend);
3519 al_free(device);
3520 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3521 return NULL;
3524 // Find a playback device to open
3525 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3527 DELETE_OBJ(device->Synth);
3528 DELETE_OBJ(device->Backend);
3529 al_free(device);
3530 alcSetError(NULL, err);
3531 return NULL;
3534 if(DefaultEffect.type != AL_EFFECT_NULL)
3536 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3537 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3539 device->DefaultSlot = NULL;
3540 ERR("Failed to initialize the default effect slot\n");
3542 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3544 ALeffectState *state = device->DefaultSlot->EffectState;
3545 device->DefaultSlot = NULL;
3546 DELETE_OBJ(state);
3547 ERR("Failed to initialize the default effect\n");
3552 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3553 do {
3554 device->next = head;
3555 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3558 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3559 return device;
3562 /* alcCloseDevice
3564 * Closes the given device.
3566 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3568 ALCdevice *list, *origdev, *nextdev;
3569 ALCcontext *ctx;
3571 LockLists();
3572 list = ATOMIC_LOAD(&DeviceList);
3573 do {
3574 if(list == device)
3575 break;
3576 } while((list=list->next) != NULL);
3577 if(!list || list->Type == Capture)
3579 alcSetError(list, ALC_INVALID_DEVICE);
3580 UnlockLists();
3581 return ALC_FALSE;
3584 origdev = device;
3585 nextdev = device->next;
3586 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3588 do {
3589 list = origdev;
3590 origdev = device;
3591 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3593 UnlockLists();
3595 ctx = ATOMIC_LOAD(&device->ContextList);
3596 while(ctx != NULL)
3598 ALCcontext *next = ctx->next;
3599 WARN("Releasing context %p\n", ctx);
3600 ReleaseContext(ctx, device);
3601 ctx = next;
3603 if((device->Flags&DEVICE_RUNNING))
3604 V0(device->Backend,stop)();
3605 device->Flags &= ~DEVICE_RUNNING;
3607 ALCdevice_DecRef(device);
3609 return ALC_TRUE;
3613 /************************************************
3614 * ALC capture functions
3615 ************************************************/
3616 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3618 ALCdevice *device = NULL;
3619 ALCenum err;
3621 DO_INITCONFIG();
3623 if(!CaptureBackend.name)
3625 alcSetError(NULL, ALC_INVALID_VALUE);
3626 return NULL;
3629 if(samples <= 0)
3631 alcSetError(NULL, ALC_INVALID_VALUE);
3632 return NULL;
3635 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3636 deviceName = NULL;
3638 device = al_calloc(16, sizeof(ALCdevice));
3639 if(!device)
3641 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3642 return NULL;
3645 //Validate device
3646 InitRef(&device->ref, 1);
3647 device->Connected = ALC_TRUE;
3648 device->Type = Capture;
3650 AL_STRING_INIT(device->DeviceName);
3651 device->DryBuffer = NULL;
3653 InitUIntMap(&device->BufferMap, ~0);
3654 InitUIntMap(&device->EffectMap, ~0);
3655 InitUIntMap(&device->FilterMap, ~0);
3656 InitUIntMap(&device->SfontMap, ~0);
3657 InitUIntMap(&device->PresetMap, ~0);
3658 InitUIntMap(&device->FontsoundMap, ~0);
3660 if(!CaptureBackend.getFactory)
3661 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3662 ALCbackend_Capture);
3663 else
3665 ALCbackendFactory *factory = CaptureBackend.getFactory();
3666 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3668 if(!device->Backend)
3670 al_free(device);
3671 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3672 return NULL;
3675 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3676 device->Frequency = frequency;
3678 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3679 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3681 al_free(device);
3682 alcSetError(NULL, ALC_INVALID_ENUM);
3683 return NULL;
3685 device->IsHeadphones = AL_FALSE;
3687 device->UpdateSize = samples;
3688 device->NumUpdates = 1;
3690 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3692 al_free(device);
3693 alcSetError(NULL, err);
3694 return NULL;
3698 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3699 do {
3700 device->next = head;
3701 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3704 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3705 return device;
3708 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3710 ALCdevice *list, *next, *nextdev;
3712 LockLists();
3713 list = ATOMIC_LOAD(&DeviceList);
3714 do {
3715 if(list == device)
3716 break;
3717 } while((list=list->next) != NULL);
3718 if(!list || list->Type != Capture)
3720 alcSetError(list, ALC_INVALID_DEVICE);
3721 UnlockLists();
3722 return ALC_FALSE;
3725 next = device;
3726 nextdev = device->next;
3727 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3729 do {
3730 list = next;
3731 next = device;
3732 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3734 UnlockLists();
3736 ALCdevice_DecRef(device);
3738 return ALC_TRUE;
3741 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3743 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3744 alcSetError(device, ALC_INVALID_DEVICE);
3745 else
3747 V0(device->Backend,lock)();
3748 if(!device->Connected)
3749 alcSetError(device, ALC_INVALID_DEVICE);
3750 else if(!(device->Flags&DEVICE_RUNNING))
3752 if(V0(device->Backend,start)())
3753 device->Flags |= DEVICE_RUNNING;
3754 else
3756 aluHandleDisconnect(device);
3757 alcSetError(device, ALC_INVALID_DEVICE);
3760 V0(device->Backend,unlock)();
3763 if(device) ALCdevice_DecRef(device);
3766 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3768 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3769 alcSetError(device, ALC_INVALID_DEVICE);
3770 else
3772 V0(device->Backend,lock)();
3773 if((device->Flags&DEVICE_RUNNING))
3774 V0(device->Backend,stop)();
3775 device->Flags &= ~DEVICE_RUNNING;
3776 V0(device->Backend,unlock)();
3779 if(device) ALCdevice_DecRef(device);
3782 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3784 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3785 alcSetError(device, ALC_INVALID_DEVICE);
3786 else
3788 ALCenum err = ALC_INVALID_VALUE;
3790 V0(device->Backend,lock)();
3791 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3792 err = V(device->Backend,captureSamples)(buffer, samples);
3793 V0(device->Backend,unlock)();
3795 if(err != ALC_NO_ERROR)
3796 alcSetError(device, err);
3798 if(device) ALCdevice_DecRef(device);
3802 /************************************************
3803 * ALC loopback functions
3804 ************************************************/
3806 /* alcLoopbackOpenDeviceSOFT
3808 * Open a loopback device, for manual rendering.
3810 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3812 ALCbackendFactory *factory;
3813 ALCdevice *device;
3815 DO_INITCONFIG();
3817 /* Make sure the device name, if specified, is us. */
3818 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3820 alcSetError(NULL, ALC_INVALID_VALUE);
3821 return NULL;
3824 device = al_calloc(16, sizeof(ALCdevice));
3825 if(!device)
3827 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3828 return NULL;
3831 //Validate device
3832 InitRef(&device->ref, 1);
3833 device->Connected = ALC_TRUE;
3834 device->Type = Loopback;
3835 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3837 device->Flags = 0;
3838 device->Bs2b = NULL;
3839 device->Hrtf_Mode = DisabledHrtf;
3840 AL_STRING_INIT(device->DeviceName);
3841 device->DryBuffer = NULL;
3843 ATOMIC_INIT(&device->ContextList, NULL);
3845 device->ClockBase = 0;
3846 device->SamplesDone = 0;
3848 device->MaxNoOfSources = 256;
3849 device->AuxiliaryEffectSlotMax = 4;
3850 device->NumAuxSends = MAX_SENDS;
3852 InitUIntMap(&device->BufferMap, ~0);
3853 InitUIntMap(&device->EffectMap, ~0);
3854 InitUIntMap(&device->FilterMap, ~0);
3855 InitUIntMap(&device->SfontMap, ~0);
3856 InitUIntMap(&device->PresetMap, ~0);
3857 InitUIntMap(&device->FontsoundMap, ~0);
3859 factory = ALCloopbackFactory_getFactory();
3860 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3861 if(!device->Backend)
3863 al_free(device);
3864 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3865 return NULL;
3868 //Set output format
3869 device->NumUpdates = 0;
3870 device->UpdateSize = 0;
3872 device->Frequency = DEFAULT_OUTPUT_RATE;
3873 device->FmtChans = DevFmtChannelsDefault;
3874 device->FmtType = DevFmtTypeDefault;
3875 device->IsHeadphones = AL_FALSE;
3877 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3878 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3880 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3881 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3883 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3884 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3886 device->NumStereoSources = 1;
3887 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3889 device->Synth = SynthCreate(device);
3890 if(!device->Synth)
3892 DELETE_OBJ(device->Backend);
3893 al_free(device);
3894 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3895 return NULL;
3898 // Open the "backend"
3899 V(device->Backend,open)("Loopback");
3902 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3903 do {
3904 device->next = head;
3905 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3908 TRACE("Created device %p\n", device);
3909 return device;
3912 /* alcIsRenderFormatSupportedSOFT
3914 * Determines if the loopback device supports the given format for rendering.
3916 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3918 ALCboolean ret = ALC_FALSE;
3920 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3921 alcSetError(device, ALC_INVALID_DEVICE);
3922 else if(freq <= 0)
3923 alcSetError(device, ALC_INVALID_VALUE);
3924 else
3926 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3927 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3928 freq >= MIN_OUTPUT_RATE)
3929 ret = ALC_TRUE;
3931 if(device) ALCdevice_DecRef(device);
3933 return ret;
3936 /* alcRenderSamplesSOFT
3938 * Renders some samples into a buffer, using the format last set by the
3939 * attributes given to alcCreateContext.
3941 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3943 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3944 alcSetError(device, ALC_INVALID_DEVICE);
3945 else if(samples < 0 || (samples > 0 && buffer == NULL))
3946 alcSetError(device, ALC_INVALID_VALUE);
3947 else
3948 aluMixData(device, buffer, samples);
3949 if(device) ALCdevice_DecRef(device);
3953 /************************************************
3954 * ALC DSP pause/resume functions
3955 ************************************************/
3957 /* alcDevicePauseSOFT
3959 * Pause the DSP to stop audio processing.
3961 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3963 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3964 alcSetError(device, ALC_INVALID_DEVICE);
3965 else
3967 LockLists();
3968 if((device->Flags&DEVICE_RUNNING))
3969 V0(device->Backend,stop)();
3970 device->Flags &= ~DEVICE_RUNNING;
3971 device->Flags |= DEVICE_PAUSED;
3972 UnlockLists();
3974 if(device) ALCdevice_DecRef(device);
3977 /* alcDeviceResumeSOFT
3979 * Resume the DSP to restart audio processing.
3981 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3983 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3984 alcSetError(device, ALC_INVALID_DEVICE);
3985 else
3987 LockLists();
3988 if((device->Flags&DEVICE_PAUSED))
3990 device->Flags &= ~DEVICE_PAUSED;
3991 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3993 if(V0(device->Backend,start)() != ALC_FALSE)
3994 device->Flags |= DEVICE_RUNNING;
3995 else
3997 alcSetError(device, ALC_INVALID_DEVICE);
3998 V0(device->Backend,lock)();
3999 aluHandleDisconnect(device);
4000 V0(device->Backend,unlock)();
4004 UnlockLists();
4006 if(device) ALCdevice_DecRef(device);