Make the modulator effect multichannel
[openal-soft.git] / Alc / ALc.c
blobf69f6eccc9c31b4b979143a018470f10759d72db
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 "bs2b.h"
39 #include "alu.h"
41 #include "compat.h"
42 #include "threads.h"
43 #include "alstring.h"
45 #include "backends/base.h"
48 /************************************************
49 * Backends
50 ************************************************/
51 struct BackendInfo {
52 const char *name;
53 ALCbackendFactory* (*getFactory)(void);
54 ALCboolean (*Init)(BackendFuncs*);
55 void (*Deinit)(void);
56 void (*Probe)(enum DevProbe);
57 BackendFuncs Funcs;
60 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
61 static struct BackendInfo BackendList[] = {
62 #ifdef HAVE_JACK
63 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
64 #endif
65 #ifdef HAVE_PULSEAUDIO
66 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
67 #endif
68 #ifdef HAVE_ALSA
69 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
70 #endif
71 #ifdef HAVE_COREAUDIO
72 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
73 #endif
74 #ifdef HAVE_OSS
75 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
76 #endif
77 #ifdef HAVE_SOLARIS
78 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
79 #endif
80 #ifdef HAVE_SNDIO
81 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
82 #endif
83 #ifdef HAVE_QSA
84 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
85 #endif
86 #ifdef HAVE_MMDEVAPI
87 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
88 #endif
89 #ifdef HAVE_DSOUND
90 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
91 #endif
92 #ifdef HAVE_WINMM
93 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
94 #endif
95 #ifdef HAVE_PORTAUDIO
96 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
97 #endif
98 #ifdef HAVE_OPENSL
99 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
100 #endif
102 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
103 #ifdef HAVE_WAVE
104 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
105 #endif
107 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
109 #undef EmptyFuncs
111 static struct BackendInfo PlaybackBackend;
112 static struct BackendInfo CaptureBackend;
115 /************************************************
116 * Functions, enums, and errors
117 ************************************************/
118 typedef struct ALCfunction {
119 const ALCchar *funcName;
120 ALCvoid *address;
121 } ALCfunction;
123 typedef struct ALCenums {
124 const ALCchar *enumName;
125 ALCenum value;
126 } ALCenums;
128 #define DECL(x) { #x, (ALCvoid*)(x) }
129 static const ALCfunction alcFunctions[] = {
130 DECL(alcCreateContext),
131 DECL(alcMakeContextCurrent),
132 DECL(alcProcessContext),
133 DECL(alcSuspendContext),
134 DECL(alcDestroyContext),
135 DECL(alcGetCurrentContext),
136 DECL(alcGetContextsDevice),
137 DECL(alcOpenDevice),
138 DECL(alcCloseDevice),
139 DECL(alcGetError),
140 DECL(alcIsExtensionPresent),
141 DECL(alcGetProcAddress),
142 DECL(alcGetEnumValue),
143 DECL(alcGetString),
144 DECL(alcGetIntegerv),
145 DECL(alcCaptureOpenDevice),
146 DECL(alcCaptureCloseDevice),
147 DECL(alcCaptureStart),
148 DECL(alcCaptureStop),
149 DECL(alcCaptureSamples),
151 DECL(alcSetThreadContext),
152 DECL(alcGetThreadContext),
154 DECL(alcLoopbackOpenDeviceSOFT),
155 DECL(alcIsRenderFormatSupportedSOFT),
156 DECL(alcRenderSamplesSOFT),
158 DECL(alcDevicePauseSOFT),
159 DECL(alcDeviceResumeSOFT),
161 DECL(alcGetStringiSOFT),
162 DECL(alcResetDeviceSOFT),
164 DECL(alcGetInteger64vSOFT),
166 DECL(alEnable),
167 DECL(alDisable),
168 DECL(alIsEnabled),
169 DECL(alGetString),
170 DECL(alGetBooleanv),
171 DECL(alGetIntegerv),
172 DECL(alGetFloatv),
173 DECL(alGetDoublev),
174 DECL(alGetBoolean),
175 DECL(alGetInteger),
176 DECL(alGetFloat),
177 DECL(alGetDouble),
178 DECL(alGetError),
179 DECL(alIsExtensionPresent),
180 DECL(alGetProcAddress),
181 DECL(alGetEnumValue),
182 DECL(alListenerf),
183 DECL(alListener3f),
184 DECL(alListenerfv),
185 DECL(alListeneri),
186 DECL(alListener3i),
187 DECL(alListeneriv),
188 DECL(alGetListenerf),
189 DECL(alGetListener3f),
190 DECL(alGetListenerfv),
191 DECL(alGetListeneri),
192 DECL(alGetListener3i),
193 DECL(alGetListeneriv),
194 DECL(alGenSources),
195 DECL(alDeleteSources),
196 DECL(alIsSource),
197 DECL(alSourcef),
198 DECL(alSource3f),
199 DECL(alSourcefv),
200 DECL(alSourcei),
201 DECL(alSource3i),
202 DECL(alSourceiv),
203 DECL(alGetSourcef),
204 DECL(alGetSource3f),
205 DECL(alGetSourcefv),
206 DECL(alGetSourcei),
207 DECL(alGetSource3i),
208 DECL(alGetSourceiv),
209 DECL(alSourcePlayv),
210 DECL(alSourceStopv),
211 DECL(alSourceRewindv),
212 DECL(alSourcePausev),
213 DECL(alSourcePlay),
214 DECL(alSourceStop),
215 DECL(alSourceRewind),
216 DECL(alSourcePause),
217 DECL(alSourceQueueBuffers),
218 DECL(alSourceUnqueueBuffers),
219 DECL(alGenBuffers),
220 DECL(alDeleteBuffers),
221 DECL(alIsBuffer),
222 DECL(alBufferData),
223 DECL(alBufferf),
224 DECL(alBuffer3f),
225 DECL(alBufferfv),
226 DECL(alBufferi),
227 DECL(alBuffer3i),
228 DECL(alBufferiv),
229 DECL(alGetBufferf),
230 DECL(alGetBuffer3f),
231 DECL(alGetBufferfv),
232 DECL(alGetBufferi),
233 DECL(alGetBuffer3i),
234 DECL(alGetBufferiv),
235 DECL(alDopplerFactor),
236 DECL(alDopplerVelocity),
237 DECL(alSpeedOfSound),
238 DECL(alDistanceModel),
240 DECL(alGenFilters),
241 DECL(alDeleteFilters),
242 DECL(alIsFilter),
243 DECL(alFilteri),
244 DECL(alFilteriv),
245 DECL(alFilterf),
246 DECL(alFilterfv),
247 DECL(alGetFilteri),
248 DECL(alGetFilteriv),
249 DECL(alGetFilterf),
250 DECL(alGetFilterfv),
251 DECL(alGenEffects),
252 DECL(alDeleteEffects),
253 DECL(alIsEffect),
254 DECL(alEffecti),
255 DECL(alEffectiv),
256 DECL(alEffectf),
257 DECL(alEffectfv),
258 DECL(alGetEffecti),
259 DECL(alGetEffectiv),
260 DECL(alGetEffectf),
261 DECL(alGetEffectfv),
262 DECL(alGenAuxiliaryEffectSlots),
263 DECL(alDeleteAuxiliaryEffectSlots),
264 DECL(alIsAuxiliaryEffectSlot),
265 DECL(alAuxiliaryEffectSloti),
266 DECL(alAuxiliaryEffectSlotiv),
267 DECL(alAuxiliaryEffectSlotf),
268 DECL(alAuxiliaryEffectSlotfv),
269 DECL(alGetAuxiliaryEffectSloti),
270 DECL(alGetAuxiliaryEffectSlotiv),
271 DECL(alGetAuxiliaryEffectSlotf),
272 DECL(alGetAuxiliaryEffectSlotfv),
274 DECL(alBufferSubDataSOFT),
276 DECL(alBufferSamplesSOFT),
277 DECL(alBufferSubSamplesSOFT),
278 DECL(alGetBufferSamplesSOFT),
279 DECL(alIsBufferFormatSupportedSOFT),
281 DECL(alDeferUpdatesSOFT),
282 DECL(alProcessUpdatesSOFT),
284 DECL(alSourcedSOFT),
285 DECL(alSource3dSOFT),
286 DECL(alSourcedvSOFT),
287 DECL(alGetSourcedSOFT),
288 DECL(alGetSource3dSOFT),
289 DECL(alGetSourcedvSOFT),
290 DECL(alSourcei64SOFT),
291 DECL(alSource3i64SOFT),
292 DECL(alSourcei64vSOFT),
293 DECL(alGetSourcei64SOFT),
294 DECL(alGetSource3i64SOFT),
295 DECL(alGetSourcei64vSOFT),
297 { NULL, NULL }
299 #undef DECL
301 #define DECL(x) { #x, (x) }
302 static const ALCenums enumeration[] = {
303 DECL(ALC_INVALID),
304 DECL(ALC_FALSE),
305 DECL(ALC_TRUE),
307 DECL(ALC_MAJOR_VERSION),
308 DECL(ALC_MINOR_VERSION),
309 DECL(ALC_ATTRIBUTES_SIZE),
310 DECL(ALC_ALL_ATTRIBUTES),
311 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
312 DECL(ALC_DEVICE_SPECIFIER),
313 DECL(ALC_ALL_DEVICES_SPECIFIER),
314 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
315 DECL(ALC_EXTENSIONS),
316 DECL(ALC_FREQUENCY),
317 DECL(ALC_REFRESH),
318 DECL(ALC_SYNC),
319 DECL(ALC_MONO_SOURCES),
320 DECL(ALC_STEREO_SOURCES),
321 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
322 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
323 DECL(ALC_CAPTURE_SAMPLES),
324 DECL(ALC_CONNECTED),
326 DECL(ALC_EFX_MAJOR_VERSION),
327 DECL(ALC_EFX_MINOR_VERSION),
328 DECL(ALC_MAX_AUXILIARY_SENDS),
330 DECL(ALC_FORMAT_CHANNELS_SOFT),
331 DECL(ALC_FORMAT_TYPE_SOFT),
333 DECL(ALC_MONO_SOFT),
334 DECL(ALC_STEREO_SOFT),
335 DECL(ALC_QUAD_SOFT),
336 DECL(ALC_5POINT1_SOFT),
337 DECL(ALC_6POINT1_SOFT),
338 DECL(ALC_7POINT1_SOFT),
340 DECL(ALC_BYTE_SOFT),
341 DECL(ALC_UNSIGNED_BYTE_SOFT),
342 DECL(ALC_SHORT_SOFT),
343 DECL(ALC_UNSIGNED_SHORT_SOFT),
344 DECL(ALC_INT_SOFT),
345 DECL(ALC_UNSIGNED_INT_SOFT),
346 DECL(ALC_FLOAT_SOFT),
348 DECL(ALC_HRTF_SOFT),
349 DECL(ALC_DONT_CARE_SOFT),
350 DECL(ALC_HRTF_STATUS_SOFT),
351 DECL(ALC_HRTF_DISABLED_SOFT),
352 DECL(ALC_HRTF_ENABLED_SOFT),
353 DECL(ALC_HRTF_DENIED_SOFT),
354 DECL(ALC_HRTF_REQUIRED_SOFT),
355 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
356 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
357 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
358 DECL(ALC_HRTF_SPECIFIER_SOFT),
359 DECL(ALC_HRTF_ID_SOFT),
361 DECL(ALC_NO_ERROR),
362 DECL(ALC_INVALID_DEVICE),
363 DECL(ALC_INVALID_CONTEXT),
364 DECL(ALC_INVALID_ENUM),
365 DECL(ALC_INVALID_VALUE),
366 DECL(ALC_OUT_OF_MEMORY),
369 DECL(AL_INVALID),
370 DECL(AL_NONE),
371 DECL(AL_FALSE),
372 DECL(AL_TRUE),
374 DECL(AL_SOURCE_RELATIVE),
375 DECL(AL_CONE_INNER_ANGLE),
376 DECL(AL_CONE_OUTER_ANGLE),
377 DECL(AL_PITCH),
378 DECL(AL_POSITION),
379 DECL(AL_DIRECTION),
380 DECL(AL_VELOCITY),
381 DECL(AL_LOOPING),
382 DECL(AL_BUFFER),
383 DECL(AL_GAIN),
384 DECL(AL_MIN_GAIN),
385 DECL(AL_MAX_GAIN),
386 DECL(AL_ORIENTATION),
387 DECL(AL_REFERENCE_DISTANCE),
388 DECL(AL_ROLLOFF_FACTOR),
389 DECL(AL_CONE_OUTER_GAIN),
390 DECL(AL_MAX_DISTANCE),
391 DECL(AL_SEC_OFFSET),
392 DECL(AL_SAMPLE_OFFSET),
393 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
394 DECL(AL_BYTE_OFFSET),
395 DECL(AL_BYTE_RW_OFFSETS_SOFT),
396 DECL(AL_SOURCE_TYPE),
397 DECL(AL_STATIC),
398 DECL(AL_STREAMING),
399 DECL(AL_UNDETERMINED),
400 DECL(AL_METERS_PER_UNIT),
401 DECL(AL_LOOP_POINTS_SOFT),
402 DECL(AL_DIRECT_CHANNELS_SOFT),
404 DECL(AL_DIRECT_FILTER),
405 DECL(AL_AUXILIARY_SEND_FILTER),
406 DECL(AL_AIR_ABSORPTION_FACTOR),
407 DECL(AL_ROOM_ROLLOFF_FACTOR),
408 DECL(AL_CONE_OUTER_GAINHF),
409 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
410 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
413 DECL(AL_SOURCE_STATE),
414 DECL(AL_INITIAL),
415 DECL(AL_PLAYING),
416 DECL(AL_PAUSED),
417 DECL(AL_STOPPED),
419 DECL(AL_BUFFERS_QUEUED),
420 DECL(AL_BUFFERS_PROCESSED),
422 DECL(AL_FORMAT_MONO8),
423 DECL(AL_FORMAT_MONO16),
424 DECL(AL_FORMAT_MONO_FLOAT32),
425 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
426 DECL(AL_FORMAT_STEREO8),
427 DECL(AL_FORMAT_STEREO16),
428 DECL(AL_FORMAT_STEREO_FLOAT32),
429 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
430 DECL(AL_FORMAT_MONO_IMA4),
431 DECL(AL_FORMAT_STEREO_IMA4),
432 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
433 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
434 DECL(AL_FORMAT_QUAD8_LOKI),
435 DECL(AL_FORMAT_QUAD16_LOKI),
436 DECL(AL_FORMAT_QUAD8),
437 DECL(AL_FORMAT_QUAD16),
438 DECL(AL_FORMAT_QUAD32),
439 DECL(AL_FORMAT_51CHN8),
440 DECL(AL_FORMAT_51CHN16),
441 DECL(AL_FORMAT_51CHN32),
442 DECL(AL_FORMAT_61CHN8),
443 DECL(AL_FORMAT_61CHN16),
444 DECL(AL_FORMAT_61CHN32),
445 DECL(AL_FORMAT_71CHN8),
446 DECL(AL_FORMAT_71CHN16),
447 DECL(AL_FORMAT_71CHN32),
448 DECL(AL_FORMAT_REAR8),
449 DECL(AL_FORMAT_REAR16),
450 DECL(AL_FORMAT_REAR32),
451 DECL(AL_FORMAT_MONO_MULAW),
452 DECL(AL_FORMAT_MONO_MULAW_EXT),
453 DECL(AL_FORMAT_STEREO_MULAW),
454 DECL(AL_FORMAT_STEREO_MULAW_EXT),
455 DECL(AL_FORMAT_QUAD_MULAW),
456 DECL(AL_FORMAT_51CHN_MULAW),
457 DECL(AL_FORMAT_61CHN_MULAW),
458 DECL(AL_FORMAT_71CHN_MULAW),
459 DECL(AL_FORMAT_REAR_MULAW),
460 DECL(AL_FORMAT_MONO_ALAW_EXT),
461 DECL(AL_FORMAT_STEREO_ALAW_EXT),
463 DECL(AL_MONO8_SOFT),
464 DECL(AL_MONO16_SOFT),
465 DECL(AL_MONO32F_SOFT),
466 DECL(AL_STEREO8_SOFT),
467 DECL(AL_STEREO16_SOFT),
468 DECL(AL_STEREO32F_SOFT),
469 DECL(AL_QUAD8_SOFT),
470 DECL(AL_QUAD16_SOFT),
471 DECL(AL_QUAD32F_SOFT),
472 DECL(AL_REAR8_SOFT),
473 DECL(AL_REAR16_SOFT),
474 DECL(AL_REAR32F_SOFT),
475 DECL(AL_5POINT1_8_SOFT),
476 DECL(AL_5POINT1_16_SOFT),
477 DECL(AL_5POINT1_32F_SOFT),
478 DECL(AL_6POINT1_8_SOFT),
479 DECL(AL_6POINT1_16_SOFT),
480 DECL(AL_6POINT1_32F_SOFT),
481 DECL(AL_7POINT1_8_SOFT),
482 DECL(AL_7POINT1_16_SOFT),
483 DECL(AL_7POINT1_32F_SOFT),
484 DECL(AL_FORMAT_BFORMAT2D_8),
485 DECL(AL_FORMAT_BFORMAT2D_16),
486 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
487 DECL(AL_FORMAT_BFORMAT2D_MULAW),
488 DECL(AL_FORMAT_BFORMAT3D_8),
489 DECL(AL_FORMAT_BFORMAT3D_16),
490 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
491 DECL(AL_FORMAT_BFORMAT3D_MULAW),
493 DECL(AL_MONO_SOFT),
494 DECL(AL_STEREO_SOFT),
495 DECL(AL_QUAD_SOFT),
496 DECL(AL_REAR_SOFT),
497 DECL(AL_5POINT1_SOFT),
498 DECL(AL_6POINT1_SOFT),
499 DECL(AL_7POINT1_SOFT),
501 DECL(AL_BYTE_SOFT),
502 DECL(AL_UNSIGNED_BYTE_SOFT),
503 DECL(AL_SHORT_SOFT),
504 DECL(AL_UNSIGNED_SHORT_SOFT),
505 DECL(AL_INT_SOFT),
506 DECL(AL_UNSIGNED_INT_SOFT),
507 DECL(AL_FLOAT_SOFT),
508 DECL(AL_DOUBLE_SOFT),
509 DECL(AL_BYTE3_SOFT),
510 DECL(AL_UNSIGNED_BYTE3_SOFT),
512 DECL(AL_FREQUENCY),
513 DECL(AL_BITS),
514 DECL(AL_CHANNELS),
515 DECL(AL_SIZE),
516 DECL(AL_INTERNAL_FORMAT_SOFT),
517 DECL(AL_BYTE_LENGTH_SOFT),
518 DECL(AL_SAMPLE_LENGTH_SOFT),
519 DECL(AL_SEC_LENGTH_SOFT),
520 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
521 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
523 DECL(AL_UNUSED),
524 DECL(AL_PENDING),
525 DECL(AL_PROCESSED),
527 DECL(AL_NO_ERROR),
528 DECL(AL_INVALID_NAME),
529 DECL(AL_INVALID_ENUM),
530 DECL(AL_INVALID_VALUE),
531 DECL(AL_INVALID_OPERATION),
532 DECL(AL_OUT_OF_MEMORY),
534 DECL(AL_VENDOR),
535 DECL(AL_VERSION),
536 DECL(AL_RENDERER),
537 DECL(AL_EXTENSIONS),
539 DECL(AL_DOPPLER_FACTOR),
540 DECL(AL_DOPPLER_VELOCITY),
541 DECL(AL_DISTANCE_MODEL),
542 DECL(AL_SPEED_OF_SOUND),
543 DECL(AL_SOURCE_DISTANCE_MODEL),
544 DECL(AL_DEFERRED_UPDATES_SOFT),
546 DECL(AL_INVERSE_DISTANCE),
547 DECL(AL_INVERSE_DISTANCE_CLAMPED),
548 DECL(AL_LINEAR_DISTANCE),
549 DECL(AL_LINEAR_DISTANCE_CLAMPED),
550 DECL(AL_EXPONENT_DISTANCE),
551 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
553 DECL(AL_FILTER_TYPE),
554 DECL(AL_FILTER_NULL),
555 DECL(AL_FILTER_LOWPASS),
556 DECL(AL_FILTER_HIGHPASS),
557 DECL(AL_FILTER_BANDPASS),
559 DECL(AL_LOWPASS_GAIN),
560 DECL(AL_LOWPASS_GAINHF),
562 DECL(AL_HIGHPASS_GAIN),
563 DECL(AL_HIGHPASS_GAINLF),
565 DECL(AL_BANDPASS_GAIN),
566 DECL(AL_BANDPASS_GAINHF),
567 DECL(AL_BANDPASS_GAINLF),
569 DECL(AL_EFFECT_TYPE),
570 DECL(AL_EFFECT_NULL),
571 DECL(AL_EFFECT_REVERB),
572 DECL(AL_EFFECT_EAXREVERB),
573 DECL(AL_EFFECT_CHORUS),
574 DECL(AL_EFFECT_DISTORTION),
575 DECL(AL_EFFECT_ECHO),
576 DECL(AL_EFFECT_FLANGER),
577 #if 0
578 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
579 DECL(AL_EFFECT_VOCAL_MORPHER),
580 DECL(AL_EFFECT_PITCH_SHIFTER),
581 #endif
582 DECL(AL_EFFECT_RING_MODULATOR),
583 #if 0
584 DECL(AL_EFFECT_AUTOWAH),
585 #endif
586 DECL(AL_EFFECT_COMPRESSOR),
587 DECL(AL_EFFECT_EQUALIZER),
588 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
589 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
591 DECL(AL_EAXREVERB_DENSITY),
592 DECL(AL_EAXREVERB_DIFFUSION),
593 DECL(AL_EAXREVERB_GAIN),
594 DECL(AL_EAXREVERB_GAINHF),
595 DECL(AL_EAXREVERB_GAINLF),
596 DECL(AL_EAXREVERB_DECAY_TIME),
597 DECL(AL_EAXREVERB_DECAY_HFRATIO),
598 DECL(AL_EAXREVERB_DECAY_LFRATIO),
599 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
600 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
601 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
602 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
603 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
604 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
605 DECL(AL_EAXREVERB_ECHO_TIME),
606 DECL(AL_EAXREVERB_ECHO_DEPTH),
607 DECL(AL_EAXREVERB_MODULATION_TIME),
608 DECL(AL_EAXREVERB_MODULATION_DEPTH),
609 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
610 DECL(AL_EAXREVERB_HFREFERENCE),
611 DECL(AL_EAXREVERB_LFREFERENCE),
612 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
613 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
615 DECL(AL_REVERB_DENSITY),
616 DECL(AL_REVERB_DIFFUSION),
617 DECL(AL_REVERB_GAIN),
618 DECL(AL_REVERB_GAINHF),
619 DECL(AL_REVERB_DECAY_TIME),
620 DECL(AL_REVERB_DECAY_HFRATIO),
621 DECL(AL_REVERB_REFLECTIONS_GAIN),
622 DECL(AL_REVERB_REFLECTIONS_DELAY),
623 DECL(AL_REVERB_LATE_REVERB_GAIN),
624 DECL(AL_REVERB_LATE_REVERB_DELAY),
625 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
626 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
627 DECL(AL_REVERB_DECAY_HFLIMIT),
629 DECL(AL_CHORUS_WAVEFORM),
630 DECL(AL_CHORUS_PHASE),
631 DECL(AL_CHORUS_RATE),
632 DECL(AL_CHORUS_DEPTH),
633 DECL(AL_CHORUS_FEEDBACK),
634 DECL(AL_CHORUS_DELAY),
636 DECL(AL_DISTORTION_EDGE),
637 DECL(AL_DISTORTION_GAIN),
638 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
639 DECL(AL_DISTORTION_EQCENTER),
640 DECL(AL_DISTORTION_EQBANDWIDTH),
642 DECL(AL_ECHO_DELAY),
643 DECL(AL_ECHO_LRDELAY),
644 DECL(AL_ECHO_DAMPING),
645 DECL(AL_ECHO_FEEDBACK),
646 DECL(AL_ECHO_SPREAD),
648 DECL(AL_FLANGER_WAVEFORM),
649 DECL(AL_FLANGER_PHASE),
650 DECL(AL_FLANGER_RATE),
651 DECL(AL_FLANGER_DEPTH),
652 DECL(AL_FLANGER_FEEDBACK),
653 DECL(AL_FLANGER_DELAY),
655 DECL(AL_RING_MODULATOR_FREQUENCY),
656 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
657 DECL(AL_RING_MODULATOR_WAVEFORM),
659 #if 0
660 DECL(AL_AUTOWAH_ATTACK_TIME),
661 DECL(AL_AUTOWAH_PEAK_GAIN),
662 DECL(AL_AUTOWAH_RELEASE_TIME),
663 DECL(AL_AUTOWAH_RESONANCE),
664 #endif
666 DECL(AL_COMPRESSOR_ONOFF),
668 DECL(AL_EQUALIZER_LOW_GAIN),
669 DECL(AL_EQUALIZER_LOW_CUTOFF),
670 DECL(AL_EQUALIZER_MID1_GAIN),
671 DECL(AL_EQUALIZER_MID1_CENTER),
672 DECL(AL_EQUALIZER_MID1_WIDTH),
673 DECL(AL_EQUALIZER_MID2_GAIN),
674 DECL(AL_EQUALIZER_MID2_CENTER),
675 DECL(AL_EQUALIZER_MID2_WIDTH),
676 DECL(AL_EQUALIZER_HIGH_GAIN),
677 DECL(AL_EQUALIZER_HIGH_CUTOFF),
679 DECL(AL_DEDICATED_GAIN),
681 { NULL, (ALCenum)0 }
683 #undef DECL
685 static const ALCchar alcNoError[] = "No Error";
686 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
687 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
688 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
689 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
690 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
693 /************************************************
694 * Global variables
695 ************************************************/
697 /* Enumerated device names */
698 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
700 static al_string alcAllDevicesList;
701 static al_string alcCaptureDeviceList;
703 /* Default is always the first in the list */
704 static ALCchar *alcDefaultAllDevicesSpecifier;
705 static ALCchar *alcCaptureDefaultDeviceSpecifier;
707 /* Default context extensions */
708 static const ALchar alExtList[] =
709 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
710 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
711 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
712 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
713 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
714 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
715 "AL_SOFT_source_latency AL_SOFT_source_length";
717 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
719 /* Thread-local current context */
720 static altss_t LocalContext;
721 /* Process-wide current context */
722 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
724 /* Mixing thread piority level */
725 ALint RTPrioLevel;
727 FILE *LogFile;
728 #ifdef _DEBUG
729 enum LogLevel LogLevel = LogWarning;
730 #else
731 enum LogLevel LogLevel = LogError;
732 #endif
734 /* Flag to trap ALC device errors */
735 static ALCboolean TrapALCError = ALC_FALSE;
737 /* One-time configuration init control */
738 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
740 /* Default effect that applies to sources that don't have an effect on send 0 */
741 static ALeffect DefaultEffect;
743 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
744 * updates.
746 static ALCboolean SuspendDefers = ALC_TRUE;
749 /************************************************
750 * ALC information
751 ************************************************/
752 static const ALCchar alcNoDeviceExtList[] =
753 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
754 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
755 static const ALCchar alcExtensionList[] =
756 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
757 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
758 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
759 "ALC_SOFT_loopback ALC_SOFT_pause_device";
760 static const ALCint alcMajorVersion = 1;
761 static const ALCint alcMinorVersion = 1;
763 static const ALCint alcEFXMajorVersion = 1;
764 static const ALCint alcEFXMinorVersion = 0;
767 /************************************************
768 * Device lists
769 ************************************************/
770 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
772 static almtx_t ListLock;
773 static inline void LockLists(void)
775 int lockret = almtx_lock(&ListLock);
776 assert(lockret == althrd_success);
778 static inline void UnlockLists(void)
780 int unlockret = almtx_unlock(&ListLock);
781 assert(unlockret == althrd_success);
784 /************************************************
785 * Library initialization
786 ************************************************/
787 #if defined(_WIN32)
788 static void alc_init(void);
789 static void alc_deinit(void);
790 static void alc_deinit_safe(void);
792 #ifndef AL_LIBTYPE_STATIC
793 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
795 switch(reason)
797 case DLL_PROCESS_ATTACH:
798 /* Pin the DLL so we won't get unloaded until the process terminates */
799 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
800 (WCHAR*)hModule, &hModule);
801 alc_init();
802 break;
804 case DLL_THREAD_DETACH:
805 break;
807 case DLL_PROCESS_DETACH:
808 if(!lpReserved)
809 alc_deinit();
810 else
811 alc_deinit_safe();
812 break;
814 return TRUE;
816 #elif defined(_MSC_VER)
817 #pragma section(".CRT$XCU",read)
818 static void alc_constructor(void);
819 static void alc_destructor(void);
820 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
822 static void alc_constructor(void)
824 atexit(alc_destructor);
825 alc_init();
828 static void alc_destructor(void)
830 alc_deinit();
832 #elif defined(HAVE_GCC_DESTRUCTOR)
833 static void alc_init(void) __attribute__((constructor));
834 static void alc_deinit(void) __attribute__((destructor));
835 #else
836 #error "No static initialization available on this platform!"
837 #endif
839 #elif defined(HAVE_GCC_DESTRUCTOR)
841 static void alc_init(void) __attribute__((constructor));
842 static void alc_deinit(void) __attribute__((destructor));
844 #else
845 #error "No global initialization available on this platform!"
846 #endif
848 static void ReleaseThreadCtx(void *ptr);
849 static void alc_init(void)
851 const char *str;
852 int ret;
854 LogFile = stderr;
856 AL_STRING_INIT(alcAllDevicesList);
857 AL_STRING_INIT(alcCaptureDeviceList);
859 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
860 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
861 ConeScale *= 0.5f;
863 str = getenv("__ALSOFT_REVERSE_Z");
864 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
865 ZScale *= -1.0f;
867 ret = altss_create(&LocalContext, ReleaseThreadCtx);
868 assert(ret == althrd_success);
870 ret = almtx_init(&ListLock, almtx_recursive);
871 assert(ret == althrd_success);
873 ThunkInit();
876 static void alc_initconfig(void)
878 const char *devs, *str;
879 ALuint capfilter;
880 float valf;
881 int i, n;
883 str = getenv("ALSOFT_LOGLEVEL");
884 if(str)
886 long lvl = strtol(str, NULL, 0);
887 if(lvl >= NoLog && lvl <= LogRef)
888 LogLevel = lvl;
891 str = getenv("ALSOFT_LOGFILE");
892 if(str && str[0])
894 FILE *logfile = al_fopen(str, "wt");
895 if(logfile) LogFile = logfile;
896 else ERR("Failed to open log file '%s'\n", str);
900 char buf[1024] = "";
901 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
902 for(i = 1;BackendList[i].name;i++)
903 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
904 TRACE("Supported backends: %s\n", buf);
906 ReadALConfig();
908 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
909 if(str && *str)
911 if(strcasecmp(str, "ignore") == 0)
913 SuspendDefers = ALC_FALSE;
914 TRACE("Selected context suspend behavior, \"ignore\"\n");
916 else
917 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
920 capfilter = 0;
921 #if defined(HAVE_SSE4_1)
922 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
923 #elif defined(HAVE_SSE3)
924 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
925 #elif defined(HAVE_SSE2)
926 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
927 #elif defined(HAVE_SSE)
928 capfilter |= CPU_CAP_SSE;
929 #endif
930 #ifdef HAVE_NEON
931 capfilter |= CPU_CAP_NEON;
932 #endif
933 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
935 if(strcasecmp(str, "all") == 0)
936 capfilter = 0;
937 else
939 size_t len;
940 const char *next = str;
942 do {
943 str = next;
944 while(isspace(str[0]))
945 str++;
946 next = strchr(str, ',');
948 if(!str[0] || str[0] == ',')
949 continue;
951 len = (next ? ((size_t)(next-str)) : strlen(str));
952 while(len > 0 && isspace(str[len-1]))
953 len--;
954 if(len == 3 && strncasecmp(str, "sse", len) == 0)
955 capfilter &= ~CPU_CAP_SSE;
956 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
957 capfilter &= ~CPU_CAP_SSE2;
958 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
959 capfilter &= ~CPU_CAP_SSE3;
960 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
961 capfilter &= ~CPU_CAP_SSE4_1;
962 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
963 capfilter &= ~CPU_CAP_NEON;
964 else
965 WARN("Invalid CPU extension \"%s\"\n", str);
966 } while(next++);
969 FillCPUCaps(capfilter);
971 #ifdef _WIN32
972 RTPrioLevel = 1;
973 #else
974 RTPrioLevel = 0;
975 #endif
976 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
978 aluInitMixer();
980 str = getenv("ALSOFT_TRAP_ERROR");
981 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
983 TrapALError = AL_TRUE;
984 TrapALCError = AL_TRUE;
986 else
988 str = getenv("ALSOFT_TRAP_AL_ERROR");
989 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
990 TrapALError = AL_TRUE;
991 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
993 str = getenv("ALSOFT_TRAP_ALC_ERROR");
994 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
995 TrapALCError = ALC_TRUE;
996 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
999 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1000 ReverbBoost *= powf(10.0f, valf / 20.0f);
1002 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1004 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1005 ConfigValueStr(NULL, NULL, "drivers", &devs))
1007 int n;
1008 size_t len;
1009 const char *next = devs;
1010 int endlist, delitem;
1012 i = 0;
1013 do {
1014 devs = next;
1015 while(isspace(devs[0]))
1016 devs++;
1017 next = strchr(devs, ',');
1019 delitem = (devs[0] == '-');
1020 if(devs[0] == '-') devs++;
1022 if(!devs[0] || devs[0] == ',')
1024 endlist = 0;
1025 continue;
1027 endlist = 1;
1029 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1030 while(len > 0 && isspace(devs[len-1]))
1031 len--;
1032 for(n = i;BackendList[n].name;n++)
1034 if(len == strlen(BackendList[n].name) &&
1035 strncmp(BackendList[n].name, devs, len) == 0)
1037 if(delitem)
1039 do {
1040 BackendList[n] = BackendList[n+1];
1041 ++n;
1042 } while(BackendList[n].name);
1044 else
1046 struct BackendInfo Bkp = BackendList[n];
1047 while(n > i)
1049 BackendList[n] = BackendList[n-1];
1050 --n;
1052 BackendList[n] = Bkp;
1054 i++;
1056 break;
1059 } while(next++);
1061 if(endlist)
1063 BackendList[i].name = NULL;
1064 BackendList[i].getFactory = NULL;
1065 BackendList[i].Init = NULL;
1066 BackendList[i].Deinit = NULL;
1067 BackendList[i].Probe = NULL;
1071 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1073 if(BackendList[i].getFactory)
1075 ALCbackendFactory *factory = BackendList[i].getFactory();
1076 if(!V0(factory,init)())
1078 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1079 continue;
1082 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1083 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1085 PlaybackBackend = BackendList[i];
1086 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1088 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1090 CaptureBackend = BackendList[i];
1091 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1094 continue;
1097 if(!BackendList[i].Init(&BackendList[i].Funcs))
1099 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1100 continue;
1103 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1104 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1106 PlaybackBackend = BackendList[i];
1107 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1109 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1111 CaptureBackend = BackendList[i];
1112 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1116 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1117 V0(factory,init)();
1120 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1122 size_t len;
1123 const char *next = str;
1125 do {
1126 str = next;
1127 next = strchr(str, ',');
1129 if(!str[0] || next == str)
1130 continue;
1132 len = (next ? ((size_t)(next-str)) : strlen(str));
1133 for(n = 0;EffectList[n].name;n++)
1135 if(len == strlen(EffectList[n].name) &&
1136 strncmp(EffectList[n].name, str, len) == 0)
1137 DisabledEffects[EffectList[n].type] = AL_TRUE;
1139 } while(next++);
1142 InitEffectFactoryMap();
1144 InitEffect(&DefaultEffect);
1145 str = getenv("ALSOFT_DEFAULT_REVERB");
1146 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1147 LoadReverbPreset(str, &DefaultEffect);
1149 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1152 /************************************************
1153 * Library deinitialization
1154 ************************************************/
1155 static void alc_cleanup(void)
1157 ALCdevice *dev;
1159 AL_STRING_DEINIT(alcAllDevicesList);
1160 AL_STRING_DEINIT(alcCaptureDeviceList);
1162 free(alcDefaultAllDevicesSpecifier);
1163 alcDefaultAllDevicesSpecifier = NULL;
1164 free(alcCaptureDefaultDeviceSpecifier);
1165 alcCaptureDefaultDeviceSpecifier = NULL;
1167 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1169 ALCuint num = 0;
1170 do {
1171 num++;
1172 } while((dev=dev->next) != NULL);
1173 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1176 DeinitEffectFactoryMap();
1179 static void alc_deinit_safe(void)
1181 alc_cleanup();
1183 FreeHrtfs();
1184 FreeALConfig();
1186 ThunkExit();
1187 almtx_destroy(&ListLock);
1188 altss_delete(LocalContext);
1190 if(LogFile != stderr)
1191 fclose(LogFile);
1192 LogFile = NULL;
1195 static void alc_deinit(void)
1197 int i;
1199 alc_cleanup();
1201 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1202 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1204 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1206 if(!BackendList[i].getFactory)
1207 BackendList[i].Deinit();
1208 else
1210 ALCbackendFactory *factory = BackendList[i].getFactory();
1211 V0(factory,deinit)();
1215 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1216 V0(factory,deinit)();
1219 alc_deinit_safe();
1223 /************************************************
1224 * Device enumeration
1225 ************************************************/
1226 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1228 DO_INITCONFIG();
1230 LockLists();
1231 al_string_clear(list);
1233 if(!backendinfo->getFactory)
1234 backendinfo->Probe(type);
1235 else
1237 ALCbackendFactory *factory = backendinfo->getFactory();
1238 V(factory,probe)(type);
1241 UnlockLists();
1243 static void ProbeAllDevicesList(void)
1244 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1245 static void ProbeCaptureDeviceList(void)
1246 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1248 static void AppendDevice(const ALCchar *name, al_string *devnames)
1250 size_t len = strlen(name);
1251 if(len > 0)
1252 al_string_append_range(devnames, name, name+len+1);
1254 void AppendAllDevicesList(const ALCchar *name)
1255 { AppendDevice(name, &alcAllDevicesList); }
1256 void AppendCaptureDeviceList(const ALCchar *name)
1257 { AppendDevice(name, &alcCaptureDeviceList); }
1260 /************************************************
1261 * Device format information
1262 ************************************************/
1263 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1265 switch(type)
1267 case DevFmtByte: return "Signed Byte";
1268 case DevFmtUByte: return "Unsigned Byte";
1269 case DevFmtShort: return "Signed Short";
1270 case DevFmtUShort: return "Unsigned Short";
1271 case DevFmtInt: return "Signed Int";
1272 case DevFmtUInt: return "Unsigned Int";
1273 case DevFmtFloat: return "Float";
1275 return "(unknown type)";
1277 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1279 switch(chans)
1281 case DevFmtMono: return "Mono";
1282 case DevFmtStereo: return "Stereo";
1283 case DevFmtQuad: return "Quadraphonic";
1284 case DevFmtX51: return "5.1 Surround";
1285 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1286 case DevFmtX61: return "6.1 Surround";
1287 case DevFmtX71: return "7.1 Surround";
1288 case DevFmtBFormat3D: return "B-Format 3D";
1290 return "(unknown channels)";
1293 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1294 ALuint BytesFromDevFmt(enum DevFmtType type)
1296 switch(type)
1298 case DevFmtByte: return sizeof(ALbyte);
1299 case DevFmtUByte: return sizeof(ALubyte);
1300 case DevFmtShort: return sizeof(ALshort);
1301 case DevFmtUShort: return sizeof(ALushort);
1302 case DevFmtInt: return sizeof(ALint);
1303 case DevFmtUInt: return sizeof(ALuint);
1304 case DevFmtFloat: return sizeof(ALfloat);
1306 return 0;
1308 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1310 switch(chans)
1312 case DevFmtMono: return 1;
1313 case DevFmtStereo: return 2;
1314 case DevFmtQuad: return 4;
1315 case DevFmtX51: return 6;
1316 case DevFmtX51Rear: return 6;
1317 case DevFmtX61: return 7;
1318 case DevFmtX71: return 8;
1319 case DevFmtBFormat3D: return 4;
1321 return 0;
1324 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1325 enum DevFmtChannels *chans, enum DevFmtType *type)
1327 static const struct {
1328 ALenum format;
1329 enum DevFmtChannels channels;
1330 enum DevFmtType type;
1331 } list[] = {
1332 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1333 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1334 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1336 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1337 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1338 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1340 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1341 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1342 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1344 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1345 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1346 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1348 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1349 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1350 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1352 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1353 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1354 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1356 ALuint i;
1358 for(i = 0;i < COUNTOF(list);i++)
1360 if(list[i].format == format)
1362 *chans = list[i].channels;
1363 *type = list[i].type;
1364 return AL_TRUE;
1368 return AL_FALSE;
1371 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1373 switch(type)
1375 case ALC_BYTE_SOFT:
1376 case ALC_UNSIGNED_BYTE_SOFT:
1377 case ALC_SHORT_SOFT:
1378 case ALC_UNSIGNED_SHORT_SOFT:
1379 case ALC_INT_SOFT:
1380 case ALC_UNSIGNED_INT_SOFT:
1381 case ALC_FLOAT_SOFT:
1382 return ALC_TRUE;
1384 return ALC_FALSE;
1387 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1389 switch(channels)
1391 case ALC_MONO_SOFT:
1392 case ALC_STEREO_SOFT:
1393 case ALC_QUAD_SOFT:
1394 case ALC_5POINT1_SOFT:
1395 case ALC_6POINT1_SOFT:
1396 case ALC_7POINT1_SOFT:
1397 return ALC_TRUE;
1399 return ALC_FALSE;
1403 /************************************************
1404 * Miscellaneous ALC helpers
1405 ************************************************/
1406 enum HrtfRequestMode {
1407 Hrtf_Default = 0,
1408 Hrtf_Enable = 1,
1409 Hrtf_Disable = 2,
1412 extern inline void LockContext(ALCcontext *context);
1413 extern inline void UnlockContext(ALCcontext *context);
1415 void ALCdevice_Lock(ALCdevice *device)
1417 V0(device->Backend,lock)();
1420 void ALCdevice_Unlock(ALCdevice *device)
1422 V0(device->Backend,unlock)();
1426 /* SetDefaultWFXChannelOrder
1428 * Sets the default channel order used by WaveFormatEx.
1430 void SetDefaultWFXChannelOrder(ALCdevice *device)
1432 ALuint i;
1434 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1435 device->ChannelName[i] = InvalidChannel;
1437 switch(device->FmtChans)
1439 case DevFmtMono:
1440 device->ChannelName[0] = FrontCenter;
1441 break;
1442 case DevFmtStereo:
1443 device->ChannelName[0] = FrontLeft;
1444 device->ChannelName[1] = FrontRight;
1445 break;
1446 case DevFmtQuad:
1447 device->ChannelName[0] = FrontLeft;
1448 device->ChannelName[1] = FrontRight;
1449 device->ChannelName[2] = BackLeft;
1450 device->ChannelName[3] = BackRight;
1451 break;
1452 case DevFmtX51:
1453 device->ChannelName[0] = FrontLeft;
1454 device->ChannelName[1] = FrontRight;
1455 device->ChannelName[2] = FrontCenter;
1456 device->ChannelName[3] = LFE;
1457 device->ChannelName[4] = SideLeft;
1458 device->ChannelName[5] = SideRight;
1459 break;
1460 case DevFmtX51Rear:
1461 device->ChannelName[0] = FrontLeft;
1462 device->ChannelName[1] = FrontRight;
1463 device->ChannelName[2] = FrontCenter;
1464 device->ChannelName[3] = LFE;
1465 device->ChannelName[4] = BackLeft;
1466 device->ChannelName[5] = BackRight;
1467 break;
1468 case DevFmtX61:
1469 device->ChannelName[0] = FrontLeft;
1470 device->ChannelName[1] = FrontRight;
1471 device->ChannelName[2] = FrontCenter;
1472 device->ChannelName[3] = LFE;
1473 device->ChannelName[4] = BackCenter;
1474 device->ChannelName[5] = SideLeft;
1475 device->ChannelName[6] = SideRight;
1476 break;
1477 case DevFmtX71:
1478 device->ChannelName[0] = FrontLeft;
1479 device->ChannelName[1] = FrontRight;
1480 device->ChannelName[2] = FrontCenter;
1481 device->ChannelName[3] = LFE;
1482 device->ChannelName[4] = BackLeft;
1483 device->ChannelName[5] = BackRight;
1484 device->ChannelName[6] = SideLeft;
1485 device->ChannelName[7] = SideRight;
1486 break;
1487 case DevFmtBFormat3D:
1488 device->ChannelName[0] = BFormatW;
1489 device->ChannelName[1] = BFormatX;
1490 device->ChannelName[2] = BFormatY;
1491 device->ChannelName[3] = BFormatZ;
1492 break;
1496 /* SetDefaultChannelOrder
1498 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1500 void SetDefaultChannelOrder(ALCdevice *device)
1502 ALuint i;
1504 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1505 device->ChannelName[i] = InvalidChannel;
1507 switch(device->FmtChans)
1509 case DevFmtX51Rear:
1510 device->ChannelName[0] = FrontLeft;
1511 device->ChannelName[1] = FrontRight;
1512 device->ChannelName[2] = BackLeft;
1513 device->ChannelName[3] = BackRight;
1514 device->ChannelName[4] = FrontCenter;
1515 device->ChannelName[5] = LFE;
1516 return;
1517 case DevFmtX71:
1518 device->ChannelName[0] = FrontLeft;
1519 device->ChannelName[1] = FrontRight;
1520 device->ChannelName[2] = BackLeft;
1521 device->ChannelName[3] = BackRight;
1522 device->ChannelName[4] = FrontCenter;
1523 device->ChannelName[5] = LFE;
1524 device->ChannelName[6] = SideLeft;
1525 device->ChannelName[7] = SideRight;
1526 return;
1528 /* Same as WFX order */
1529 case DevFmtMono:
1530 case DevFmtStereo:
1531 case DevFmtQuad:
1532 case DevFmtX51:
1533 case DevFmtX61:
1534 case DevFmtBFormat3D:
1535 SetDefaultWFXChannelOrder(device);
1536 break;
1540 extern inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan);
1543 /* ALCcontext_DeferUpdates
1545 * Defers/suspends updates for the given context's listener and sources. This
1546 * does *NOT* stop mixing, but rather prevents certain property changes from
1547 * taking effect.
1549 void ALCcontext_DeferUpdates(ALCcontext *context)
1551 ALCdevice *device = context->Device;
1552 FPUCtl oldMode;
1554 SetMixerFPUMode(&oldMode);
1556 V0(device->Backend,lock)();
1557 if(!context->DeferUpdates)
1559 context->DeferUpdates = AL_TRUE;
1561 /* Make sure all pending updates are performed */
1562 UpdateContextSources(context);
1563 #define UPDATE_SLOT(iter) do { \
1564 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1565 V((*iter)->EffectState,update)(device, *iter); \
1566 } while(0)
1567 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1568 #undef UPDATE_SLOT
1570 V0(device->Backend,unlock)();
1572 RestoreFPUMode(&oldMode);
1575 /* ALCcontext_ProcessUpdates
1577 * Resumes update processing after being deferred.
1579 void ALCcontext_ProcessUpdates(ALCcontext *context)
1581 ALCdevice *device = context->Device;
1583 V0(device->Backend,lock)();
1584 if(context->DeferUpdates)
1586 ALsizei pos;
1588 context->DeferUpdates = AL_FALSE;
1590 LockUIntMapRead(&context->SourceMap);
1591 for(pos = 0;pos < context->SourceMap.size;pos++)
1593 ALsource *Source = context->SourceMap.array[pos].value;
1594 ALenum new_state;
1596 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1597 Source->Offset >= 0.0)
1599 WriteLock(&Source->queue_lock);
1600 ApplyOffset(Source);
1601 WriteUnlock(&Source->queue_lock);
1604 new_state = Source->new_state;
1605 Source->new_state = AL_NONE;
1606 if(new_state)
1607 SetSourceState(Source, context, new_state);
1609 UnlockUIntMapRead(&context->SourceMap);
1611 V0(device->Backend,unlock)();
1615 /* alcSetError
1617 * Stores the latest ALC device error
1619 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1621 if(TrapALCError)
1623 #ifdef _WIN32
1624 /* DebugBreak() will cause an exception if there is no debugger */
1625 if(IsDebuggerPresent())
1626 DebugBreak();
1627 #elif defined(SIGTRAP)
1628 raise(SIGTRAP);
1629 #endif
1632 if(device)
1633 ATOMIC_STORE(&device->LastError, errorCode);
1634 else
1635 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1639 /* UpdateClockBase
1641 * Updates the device's base clock time with however many samples have been
1642 * done. This is used so frequency changes on the device don't cause the time
1643 * to jump forward or back.
1645 static inline void UpdateClockBase(ALCdevice *device)
1647 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1648 device->SamplesDone = 0;
1651 /* UpdateDeviceParams
1653 * Updates device parameters according to the attribute list (caller is
1654 * responsible for holding the list lock).
1656 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1658 ALCcontext *context;
1659 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1660 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1661 enum DevFmtChannels oldChans;
1662 enum DevFmtType oldType;
1663 ALCuint oldFreq;
1664 FPUCtl oldMode;
1665 ALCsizei hrtf_id = -1;
1666 size_t size;
1668 // Check for attributes
1669 if(device->Type == Loopback)
1671 enum {
1672 GotFreq = 1<<0,
1673 GotChans = 1<<1,
1674 GotType = 1<<2,
1675 GotAll = GotFreq|GotChans|GotType
1677 ALCuint freq, numMono, numStereo, numSends;
1678 enum DevFmtChannels schans;
1679 enum DevFmtType stype;
1680 ALCuint attrIdx = 0;
1681 ALCint gotFmt = 0;
1683 if(!attrList)
1685 WARN("Missing attributes for loopback device\n");
1686 return ALC_INVALID_VALUE;
1689 numMono = device->NumMonoSources;
1690 numStereo = device->NumStereoSources;
1691 numSends = device->NumAuxSends;
1692 schans = device->FmtChans;
1693 stype = device->FmtType;
1694 freq = device->Frequency;
1696 while(attrList[attrIdx])
1698 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1700 ALCint val = attrList[attrIdx + 1];
1701 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1702 return ALC_INVALID_VALUE;
1703 schans = val;
1704 gotFmt |= GotChans;
1707 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1709 ALCint val = attrList[attrIdx + 1];
1710 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1711 return ALC_INVALID_VALUE;
1712 stype = val;
1713 gotFmt |= GotType;
1716 if(attrList[attrIdx] == ALC_FREQUENCY)
1718 freq = attrList[attrIdx + 1];
1719 if(freq < MIN_OUTPUT_RATE)
1720 return ALC_INVALID_VALUE;
1721 gotFmt |= GotFreq;
1724 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1726 numStereo = attrList[attrIdx + 1];
1727 if(numStereo > device->MaxNoOfSources)
1728 numStereo = device->MaxNoOfSources;
1730 numMono = device->MaxNoOfSources - numStereo;
1733 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1734 numSends = attrList[attrIdx + 1];
1736 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1738 if(attrList[attrIdx + 1] == ALC_FALSE)
1739 hrtf_appreq = Hrtf_Disable;
1740 else if(attrList[attrIdx + 1] == ALC_TRUE)
1741 hrtf_appreq = Hrtf_Enable;
1742 else
1743 hrtf_appreq = Hrtf_Default;
1746 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1747 hrtf_id = attrList[attrIdx + 1];
1749 attrIdx += 2;
1752 if(gotFmt != GotAll)
1754 WARN("Missing format for loopback device\n");
1755 return ALC_INVALID_VALUE;
1758 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1759 numSends = minu(MAX_SENDS, numSends);
1761 if((device->Flags&DEVICE_RUNNING))
1762 V0(device->Backend,stop)();
1763 device->Flags &= ~DEVICE_RUNNING;
1765 UpdateClockBase(device);
1767 device->Frequency = freq;
1768 device->FmtChans = schans;
1769 device->FmtType = stype;
1770 device->NumMonoSources = numMono;
1771 device->NumStereoSources = numStereo;
1772 device->NumAuxSends = numSends;
1774 else if(attrList && attrList[0])
1776 ALCuint freq, numMono, numStereo, numSends;
1777 ALCuint attrIdx = 0;
1779 /* If a context is already running on the device, stop playback so the
1780 * device attributes can be updated. */
1781 if((device->Flags&DEVICE_RUNNING))
1782 V0(device->Backend,stop)();
1783 device->Flags &= ~DEVICE_RUNNING;
1785 freq = device->Frequency;
1786 numMono = device->NumMonoSources;
1787 numStereo = device->NumStereoSources;
1788 numSends = device->NumAuxSends;
1790 while(attrList[attrIdx])
1792 if(attrList[attrIdx] == ALC_FREQUENCY)
1794 freq = attrList[attrIdx + 1];
1795 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1798 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1800 numStereo = attrList[attrIdx + 1];
1801 if(numStereo > device->MaxNoOfSources)
1802 numStereo = device->MaxNoOfSources;
1804 numMono = device->MaxNoOfSources - numStereo;
1807 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1808 numSends = attrList[attrIdx + 1];
1810 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1812 if(attrList[attrIdx + 1] == ALC_FALSE)
1813 hrtf_appreq = Hrtf_Disable;
1814 else if(attrList[attrIdx + 1] == ALC_TRUE)
1815 hrtf_appreq = Hrtf_Enable;
1816 else
1817 hrtf_appreq = Hrtf_Default;
1820 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1821 hrtf_id = attrList[attrIdx + 1];
1823 attrIdx += 2;
1826 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1827 freq = maxu(freq, MIN_OUTPUT_RATE);
1829 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1830 numSends = minu(MAX_SENDS, numSends);
1832 UpdateClockBase(device);
1834 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1835 device->Frequency;
1836 /* SSE and Neon do best with the update size being a multiple of 4 */
1837 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1838 device->UpdateSize = (device->UpdateSize+3)&~3;
1840 device->Frequency = freq;
1841 device->NumMonoSources = numMono;
1842 device->NumStereoSources = numStereo;
1843 device->NumAuxSends = numSends;
1846 if((device->Flags&DEVICE_RUNNING))
1847 return ALC_NO_ERROR;
1849 al_free(device->DryBuffer);
1850 device->DryBuffer = NULL;
1852 UpdateClockBase(device);
1854 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1855 if(device->Type != Loopback)
1857 const char *hrtf;
1858 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1860 if(strcasecmp(hrtf, "true") == 0)
1861 hrtf_userreq = Hrtf_Enable;
1862 else if(strcasecmp(hrtf, "false") == 0)
1863 hrtf_userreq = Hrtf_Disable;
1864 else if(strcasecmp(hrtf, "auto") != 0)
1865 ERR("Unexpected hrtf value: %s\n", hrtf);
1868 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1870 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1872 VECTOR_DEINIT(device->Hrtf_List);
1873 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1875 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1877 device->FmtChans = DevFmtStereo;
1878 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1879 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1880 else
1881 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1882 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1884 else
1886 hrtf_userreq = hrtf_appreq = Hrtf_Default;
1887 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1891 else if(hrtf_appreq == Hrtf_Enable)
1893 size_t i;
1894 /* Loopback device. We don't need to match to a specific HRTF entry
1895 * here. If the requested ID matches, we'll pick that later, if not,
1896 * we'll try to auto-select one anyway. */
1897 if(device->FmtChans != DevFmtStereo)
1898 i = VECTOR_SIZE(device->Hrtf_List);
1899 else
1901 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1903 VECTOR_DEINIT(device->Hrtf_List);
1904 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1906 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1908 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1909 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1910 break;
1913 if(i == VECTOR_SIZE(device->Hrtf_List))
1915 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1916 DevFmtChannelsString(device->FmtChans), device->Frequency);
1917 hrtf_appreq = Hrtf_Default;
1918 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1922 oldFreq = device->Frequency;
1923 oldChans = device->FmtChans;
1924 oldType = device->FmtType;
1926 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1927 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1928 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1929 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1930 device->UpdateSize, device->NumUpdates
1933 if(V0(device->Backend,reset)() == ALC_FALSE)
1934 return ALC_INVALID_DEVICE;
1936 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1938 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1939 DevFmtChannelsString(device->FmtChans));
1940 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1942 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1944 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1945 DevFmtTypeString(device->FmtType));
1946 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1948 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1950 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1951 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1954 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1955 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1956 device->Frequency, device->UpdateSize, device->NumUpdates
1959 if((device->UpdateSize&3) != 0)
1961 if((CPUCapFlags&CPU_CAP_SSE))
1962 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1963 if((CPUCapFlags&CPU_CAP_NEON))
1964 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1967 device->Hrtf = NULL;
1968 device->Hrtf_Mode = DisabledHrtf;
1969 al_string_clear(&device->Hrtf_Name);
1970 if(device->FmtChans != DevFmtStereo)
1972 if(hrtf_appreq == Hrtf_Enable)
1973 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1975 free(device->Bs2b);
1976 device->Bs2b = NULL;
1978 else
1980 bool headphones = device->IsHeadphones;
1981 enum HrtfMode hrtf_mode = FullHrtf;
1982 ALCenum hrtf_status = device->Hrtf_Status;
1983 const char *mode;
1984 int bs2blevel;
1985 int usehrtf;
1987 if(device->Type != Loopback)
1989 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
1991 if(strcasecmp(mode, "headphones") == 0)
1992 headphones = true;
1993 else if(strcasecmp(mode, "speakers") == 0)
1994 headphones = false;
1995 else if(strcasecmp(mode, "auto") != 0)
1996 ERR("Unexpected stereo-mode: %s\n", mode);
1999 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
2001 if(strcasecmp(mode, "full") == 0)
2002 hrtf_mode = FullHrtf;
2003 else if(strcasecmp(mode, "basic") == 0)
2004 hrtf_mode = BasicHrtf;
2005 else
2006 ERR("Unexpected hrtf-mode: %s\n", mode);
2011 if(hrtf_userreq == Hrtf_Default)
2013 usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
2014 (hrtf_appreq == Hrtf_Enable);
2015 if(headphones && hrtf_appreq != Hrtf_Disable)
2016 hrtf_status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
2017 else if(usehrtf)
2018 hrtf_status = ALC_HRTF_ENABLED_SOFT;
2020 else
2022 usehrtf = (hrtf_userreq == Hrtf_Enable);
2023 if(!usehrtf)
2024 hrtf_status = ALC_HRTF_DENIED_SOFT;
2025 else
2026 hrtf_status = ALC_HRTF_REQUIRED_SOFT;
2029 if(!usehrtf)
2030 device->Hrtf_Status = hrtf_status;
2031 else
2033 size_t i;
2035 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2036 if(VECTOR_SIZE(device->Hrtf_List) == 0)
2038 VECTOR_DEINIT(device->Hrtf_List);
2039 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2042 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
2044 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, hrtf_id);
2045 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2047 device->Hrtf = entry->hrtf;
2048 al_string_copy(&device->Hrtf_Name, entry->name);
2051 if(!device->Hrtf)
2053 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
2055 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
2056 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2058 device->Hrtf = entry->hrtf;
2059 al_string_copy(&device->Hrtf_Name, entry->name);
2060 break;
2065 if(device->Hrtf)
2067 device->Hrtf_Mode = hrtf_mode;
2068 device->Hrtf_Status = hrtf_status;
2069 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
2070 free(device->Bs2b);
2071 device->Bs2b = NULL;
2073 else
2075 TRACE("HRTF disabled\n");
2077 bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
2078 (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
2079 if(device->Type != Loopback)
2080 ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
2081 if(bs2blevel > 0 && bs2blevel <= 6)
2083 if(!device->Bs2b)
2085 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
2086 bs2b_clear(device->Bs2b);
2088 bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
2089 TRACE("BS2B enabled\n");
2091 else
2093 free(device->Bs2b);
2094 device->Bs2b = NULL;
2095 TRACE("BS2B disabled\n");
2100 aluInitPanning(device);
2102 /* With HRTF, allocate two extra channels for the post-filter output. */
2103 size = sizeof(device->DryBuffer[0]) * (device->NumChannels + (device->Hrtf ? 2 : 0));
2104 device->DryBuffer = al_calloc(16, size);
2105 if(!device->DryBuffer)
2107 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2108 return ALC_INVALID_DEVICE;
2111 SetMixerFPUMode(&oldMode);
2112 V0(device->Backend,lock)();
2113 context = ATOMIC_LOAD(&device->ContextList);
2114 while(context)
2116 ALsizei pos;
2118 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2119 LockUIntMapRead(&context->EffectSlotMap);
2120 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2122 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2124 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2126 UnlockUIntMapRead(&context->EffectSlotMap);
2127 V0(device->Backend,unlock)();
2128 RestoreFPUMode(&oldMode);
2129 return ALC_INVALID_DEVICE;
2131 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2132 V(slot->EffectState,update)(device, slot);
2134 UnlockUIntMapRead(&context->EffectSlotMap);
2136 LockUIntMapRead(&context->SourceMap);
2137 for(pos = 0;pos < context->SourceMap.size;pos++)
2139 ALsource *source = context->SourceMap.array[pos].value;
2140 ALuint s = device->NumAuxSends;
2141 while(s < MAX_SENDS)
2143 if(source->Send[s].Slot)
2144 DecrementRef(&source->Send[s].Slot->ref);
2145 source->Send[s].Slot = NULL;
2146 source->Send[s].Gain = 1.0f;
2147 source->Send[s].GainHF = 1.0f;
2148 s++;
2150 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2152 UnlockUIntMapRead(&context->SourceMap);
2154 for(pos = 0;pos < context->VoiceCount;pos++)
2156 ALvoice *voice = &context->Voices[pos];
2157 ALsource *source = voice->Source;
2158 ALuint s = device->NumAuxSends;
2160 while(s < MAX_SENDS)
2162 voice->Send[s].Moving = AL_FALSE;
2163 voice->Send[s].Counter = 0;
2164 s++;
2167 if(source)
2169 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2170 voice->Update(voice, source, context);
2174 context = context->next;
2176 if(device->DefaultSlot)
2178 ALeffectslot *slot = device->DefaultSlot;
2180 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2182 V0(device->Backend,unlock)();
2183 RestoreFPUMode(&oldMode);
2184 return ALC_INVALID_DEVICE;
2186 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2187 V(slot->EffectState,update)(device, slot);
2189 V0(device->Backend,unlock)();
2190 RestoreFPUMode(&oldMode);
2192 if(!(device->Flags&DEVICE_PAUSED))
2194 if(V0(device->Backend,start)() == ALC_FALSE)
2195 return ALC_INVALID_DEVICE;
2196 device->Flags |= DEVICE_RUNNING;
2199 return ALC_NO_ERROR;
2202 /* FreeDevice
2204 * Frees the device structure, and destroys any objects the app failed to
2205 * delete. Called once there's no more references on the device.
2207 static ALCvoid FreeDevice(ALCdevice *device)
2209 TRACE("%p\n", device);
2211 V0(device->Backend,close)();
2212 DELETE_OBJ(device->Backend);
2213 device->Backend = NULL;
2215 if(device->DefaultSlot)
2217 ALeffectState *state = device->DefaultSlot->EffectState;
2218 device->DefaultSlot = NULL;
2219 DELETE_OBJ(state);
2222 if(device->BufferMap.size > 0)
2224 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2225 ReleaseALBuffers(device);
2227 ResetUIntMap(&device->BufferMap);
2229 if(device->EffectMap.size > 0)
2231 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2232 ReleaseALEffects(device);
2234 ResetUIntMap(&device->EffectMap);
2236 if(device->FilterMap.size > 0)
2238 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2239 ReleaseALFilters(device);
2241 ResetUIntMap(&device->FilterMap);
2243 AL_STRING_DEINIT(device->Hrtf_Name);
2244 FreeHrtfList(&device->Hrtf_List);
2246 free(device->Bs2b);
2247 device->Bs2b = NULL;
2249 AL_STRING_DEINIT(device->DeviceName);
2251 al_free(device->DryBuffer);
2252 device->DryBuffer = NULL;
2254 al_free(device);
2258 void ALCdevice_IncRef(ALCdevice *device)
2260 uint ref;
2261 ref = IncrementRef(&device->ref);
2262 TRACEREF("%p increasing refcount to %u\n", device, ref);
2265 void ALCdevice_DecRef(ALCdevice *device)
2267 uint ref;
2268 ref = DecrementRef(&device->ref);
2269 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2270 if(ref == 0) FreeDevice(device);
2273 /* VerifyDevice
2275 * Checks if the device handle is valid, and increments its ref count if so.
2277 static ALCboolean VerifyDevice(ALCdevice **device)
2279 ALCdevice *tmpDevice;
2281 LockLists();
2282 tmpDevice = ATOMIC_LOAD(&DeviceList);
2283 while(tmpDevice)
2285 if(tmpDevice == *device)
2287 ALCdevice_IncRef(tmpDevice);
2288 UnlockLists();
2289 return ALC_TRUE;
2291 tmpDevice = tmpDevice->next;
2293 UnlockLists();
2295 *device = NULL;
2296 return ALC_FALSE;
2300 /* InitContext
2302 * Initializes context fields
2304 static ALvoid InitContext(ALCcontext *Context)
2306 ALlistener *listener = Context->Listener;
2307 //Initialise listener
2308 listener->Gain = 1.0f;
2309 listener->MetersPerUnit = 1.0f;
2310 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2311 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2312 listener->Forward[0] = 0.0f;
2313 listener->Forward[1] = 0.0f;
2314 listener->Forward[2] = -1.0f;
2315 listener->Up[0] = 0.0f;
2316 listener->Up[1] = 1.0f;
2317 listener->Up[2] = 0.0f;
2318 aluMatrixdSet(&listener->Params.Matrix,
2319 1.0, 0.0, 0.0, 0.0,
2320 0.0, 1.0, 0.0, 0.0,
2321 0.0, 0.0, 1.0, 0.0,
2322 0.0, 0.0, 0.0, 1.0
2324 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2326 //Validate Context
2327 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2328 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2329 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2330 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2332 //Set globals
2333 Context->DistanceModel = DefaultDistanceModel;
2334 Context->SourceDistanceModel = AL_FALSE;
2335 Context->DopplerFactor = 1.0f;
2336 Context->DopplerVelocity = 1.0f;
2337 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2338 Context->DeferUpdates = AL_FALSE;
2340 Context->ExtensionList = alExtList;
2344 /* FreeContext
2346 * Cleans up the context, and destroys any remaining objects the app failed to
2347 * delete. Called once there's no more references on the context.
2349 static void FreeContext(ALCcontext *context)
2351 TRACE("%p\n", context);
2353 if(context->SourceMap.size > 0)
2355 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2356 ReleaseALSources(context);
2358 ResetUIntMap(&context->SourceMap);
2360 if(context->EffectSlotMap.size > 0)
2362 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2363 ReleaseALAuxiliaryEffectSlots(context);
2365 ResetUIntMap(&context->EffectSlotMap);
2367 al_free(context->Voices);
2368 context->Voices = NULL;
2369 context->VoiceCount = 0;
2370 context->MaxVoices = 0;
2372 VECTOR_DEINIT(context->ActiveAuxSlots);
2374 ALCdevice_DecRef(context->Device);
2375 context->Device = NULL;
2377 //Invalidate context
2378 memset(context, 0, sizeof(ALCcontext));
2379 al_free(context);
2382 /* ReleaseContext
2384 * Removes the context reference from the given device and removes it from
2385 * being current on the running thread or globally.
2387 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2389 ALCcontext *nextctx;
2390 ALCcontext *origctx;
2392 if(altss_get(LocalContext) == context)
2394 WARN("%p released while current on thread\n", context);
2395 altss_set(LocalContext, NULL);
2396 ALCcontext_DecRef(context);
2399 origctx = context;
2400 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2401 ALCcontext_DecRef(context);
2403 ALCdevice_Lock(device);
2404 origctx = context;
2405 nextctx = context->next;
2406 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2408 ALCcontext *list;
2409 do {
2410 list = origctx;
2411 origctx = context;
2412 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2414 ALCdevice_Unlock(device);
2416 ALCcontext_DecRef(context);
2419 void ALCcontext_IncRef(ALCcontext *context)
2421 uint ref;
2422 ref = IncrementRef(&context->ref);
2423 TRACEREF("%p increasing refcount to %u\n", context, ref);
2426 void ALCcontext_DecRef(ALCcontext *context)
2428 uint ref;
2429 ref = DecrementRef(&context->ref);
2430 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2431 if(ref == 0) FreeContext(context);
2434 static void ReleaseThreadCtx(void *ptr)
2436 WARN("%p current for thread being destroyed\n", ptr);
2437 ALCcontext_DecRef(ptr);
2440 /* VerifyContext
2442 * Checks that the given context is valid, and increments its reference count.
2444 static ALCboolean VerifyContext(ALCcontext **context)
2446 ALCdevice *dev;
2448 LockLists();
2449 dev = ATOMIC_LOAD(&DeviceList);
2450 while(dev)
2452 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2453 while(ctx)
2455 if(ctx == *context)
2457 ALCcontext_IncRef(ctx);
2458 UnlockLists();
2459 return ALC_TRUE;
2461 ctx = ctx->next;
2463 dev = dev->next;
2465 UnlockLists();
2467 *context = NULL;
2468 return ALC_FALSE;
2472 /* GetContextRef
2474 * Returns the currently active context for this thread, and adds a reference
2475 * without locking it.
2477 ALCcontext *GetContextRef(void)
2479 ALCcontext *context;
2481 context = altss_get(LocalContext);
2482 if(context)
2483 ALCcontext_IncRef(context);
2484 else
2486 LockLists();
2487 context = ATOMIC_LOAD(&GlobalContext);
2488 if(context)
2489 ALCcontext_IncRef(context);
2490 UnlockLists();
2493 return context;
2497 /************************************************
2498 * Standard ALC functions
2499 ************************************************/
2501 /* alcGetError
2503 * Return last ALC generated error code for the given device
2505 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2507 ALCenum errorCode;
2509 if(VerifyDevice(&device))
2511 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2512 ALCdevice_DecRef(device);
2514 else
2515 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2517 return errorCode;
2521 /* alcSuspendContext
2523 * Suspends updates for the given context
2525 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2527 if(!SuspendDefers)
2528 return;
2530 if(!VerifyContext(&context))
2531 alcSetError(NULL, ALC_INVALID_CONTEXT);
2532 else
2534 ALCcontext_DeferUpdates(context);
2535 ALCcontext_DecRef(context);
2539 /* alcProcessContext
2541 * Resumes processing updates for the given context
2543 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2545 if(!SuspendDefers)
2546 return;
2548 if(!VerifyContext(&context))
2549 alcSetError(NULL, ALC_INVALID_CONTEXT);
2550 else
2552 ALCcontext_ProcessUpdates(context);
2553 ALCcontext_DecRef(context);
2558 /* alcGetString
2560 * Returns information about the device, and error strings
2562 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2564 const ALCchar *value = NULL;
2566 switch(param)
2568 case ALC_NO_ERROR:
2569 value = alcNoError;
2570 break;
2572 case ALC_INVALID_ENUM:
2573 value = alcErrInvalidEnum;
2574 break;
2576 case ALC_INVALID_VALUE:
2577 value = alcErrInvalidValue;
2578 break;
2580 case ALC_INVALID_DEVICE:
2581 value = alcErrInvalidDevice;
2582 break;
2584 case ALC_INVALID_CONTEXT:
2585 value = alcErrInvalidContext;
2586 break;
2588 case ALC_OUT_OF_MEMORY:
2589 value = alcErrOutOfMemory;
2590 break;
2592 case ALC_DEVICE_SPECIFIER:
2593 value = alcDefaultName;
2594 break;
2596 case ALC_ALL_DEVICES_SPECIFIER:
2597 if(VerifyDevice(&Device))
2599 value = al_string_get_cstr(Device->DeviceName);
2600 ALCdevice_DecRef(Device);
2602 else
2604 ProbeAllDevicesList();
2605 value = al_string_get_cstr(alcAllDevicesList);
2607 break;
2609 case ALC_CAPTURE_DEVICE_SPECIFIER:
2610 if(VerifyDevice(&Device))
2612 value = al_string_get_cstr(Device->DeviceName);
2613 ALCdevice_DecRef(Device);
2615 else
2617 ProbeCaptureDeviceList();
2618 value = al_string_get_cstr(alcCaptureDeviceList);
2620 break;
2622 /* Default devices are always first in the list */
2623 case ALC_DEFAULT_DEVICE_SPECIFIER:
2624 value = alcDefaultName;
2625 break;
2627 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2628 if(al_string_empty(alcAllDevicesList))
2629 ProbeAllDevicesList();
2631 VerifyDevice(&Device);
2633 free(alcDefaultAllDevicesSpecifier);
2634 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2635 if(!alcDefaultAllDevicesSpecifier)
2636 alcSetError(Device, ALC_OUT_OF_MEMORY);
2638 value = alcDefaultAllDevicesSpecifier;
2639 if(Device) ALCdevice_DecRef(Device);
2640 break;
2642 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2643 if(al_string_empty(alcCaptureDeviceList))
2644 ProbeCaptureDeviceList();
2646 VerifyDevice(&Device);
2648 free(alcCaptureDefaultDeviceSpecifier);
2649 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2650 if(!alcCaptureDefaultDeviceSpecifier)
2651 alcSetError(Device, ALC_OUT_OF_MEMORY);
2653 value = alcCaptureDefaultDeviceSpecifier;
2654 if(Device) ALCdevice_DecRef(Device);
2655 break;
2657 case ALC_EXTENSIONS:
2658 if(!VerifyDevice(&Device))
2659 value = alcNoDeviceExtList;
2660 else
2662 value = alcExtensionList;
2663 ALCdevice_DecRef(Device);
2665 break;
2667 case ALC_HRTF_SPECIFIER_SOFT:
2668 if(!VerifyDevice(&Device))
2669 alcSetError(NULL, ALC_INVALID_DEVICE);
2670 else
2672 LockLists();
2673 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2674 UnlockLists();
2675 ALCdevice_DecRef(Device);
2677 break;
2679 default:
2680 VerifyDevice(&Device);
2681 alcSetError(Device, ALC_INVALID_ENUM);
2682 if(Device) ALCdevice_DecRef(Device);
2683 break;
2686 return value;
2690 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2692 ALCsizei i;
2694 if(size <= 0 || values == NULL)
2696 alcSetError(device, ALC_INVALID_VALUE);
2697 return 0;
2700 if(!device)
2702 switch(param)
2704 case ALC_MAJOR_VERSION:
2705 values[0] = alcMajorVersion;
2706 return 1;
2707 case ALC_MINOR_VERSION:
2708 values[0] = alcMinorVersion;
2709 return 1;
2711 case ALC_ATTRIBUTES_SIZE:
2712 case ALC_ALL_ATTRIBUTES:
2713 case ALC_FREQUENCY:
2714 case ALC_REFRESH:
2715 case ALC_SYNC:
2716 case ALC_MONO_SOURCES:
2717 case ALC_STEREO_SOURCES:
2718 case ALC_CAPTURE_SAMPLES:
2719 case ALC_FORMAT_CHANNELS_SOFT:
2720 case ALC_FORMAT_TYPE_SOFT:
2721 alcSetError(NULL, ALC_INVALID_DEVICE);
2722 return 0;
2724 default:
2725 alcSetError(NULL, ALC_INVALID_ENUM);
2726 return 0;
2728 return 0;
2731 if(device->Type == Capture)
2733 switch(param)
2735 case ALC_CAPTURE_SAMPLES:
2736 V0(device->Backend,lock)();
2737 values[0] = V0(device->Backend,availableSamples)();
2738 V0(device->Backend,unlock)();
2739 return 1;
2741 case ALC_CONNECTED:
2742 values[0] = device->Connected;
2743 return 1;
2745 default:
2746 alcSetError(device, ALC_INVALID_ENUM);
2747 return 0;
2749 return 0;
2752 /* render device */
2753 switch(param)
2755 case ALC_MAJOR_VERSION:
2756 values[0] = alcMajorVersion;
2757 return 1;
2759 case ALC_MINOR_VERSION:
2760 values[0] = alcMinorVersion;
2761 return 1;
2763 case ALC_EFX_MAJOR_VERSION:
2764 values[0] = alcEFXMajorVersion;
2765 return 1;
2767 case ALC_EFX_MINOR_VERSION:
2768 values[0] = alcEFXMinorVersion;
2769 return 1;
2771 case ALC_ATTRIBUTES_SIZE:
2772 values[0] = 17;
2773 return 1;
2775 case ALC_ALL_ATTRIBUTES:
2776 if(size < 17)
2778 alcSetError(device, ALC_INVALID_VALUE);
2779 return 0;
2782 i = 0;
2783 values[i++] = ALC_FREQUENCY;
2784 values[i++] = device->Frequency;
2786 if(device->Type != Loopback)
2788 values[i++] = ALC_REFRESH;
2789 values[i++] = device->Frequency / device->UpdateSize;
2791 values[i++] = ALC_SYNC;
2792 values[i++] = ALC_FALSE;
2794 else
2796 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2797 values[i++] = device->FmtChans;
2799 values[i++] = ALC_FORMAT_TYPE_SOFT;
2800 values[i++] = device->FmtType;
2803 values[i++] = ALC_MONO_SOURCES;
2804 values[i++] = device->NumMonoSources;
2806 values[i++] = ALC_STEREO_SOURCES;
2807 values[i++] = device->NumStereoSources;
2809 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2810 values[i++] = device->NumAuxSends;
2812 values[i++] = ALC_HRTF_SOFT;
2813 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2815 values[i++] = ALC_HRTF_STATUS_SOFT;
2816 values[i++] = device->Hrtf_Status;
2818 values[i++] = 0;
2819 return i;
2821 case ALC_FREQUENCY:
2822 values[0] = device->Frequency;
2823 return 1;
2825 case ALC_REFRESH:
2826 if(device->Type == Loopback)
2828 alcSetError(device, ALC_INVALID_DEVICE);
2829 return 0;
2831 values[0] = device->Frequency / device->UpdateSize;
2832 return 1;
2834 case ALC_SYNC:
2835 if(device->Type == Loopback)
2837 alcSetError(device, ALC_INVALID_DEVICE);
2838 return 0;
2840 values[0] = ALC_FALSE;
2841 return 1;
2843 case ALC_FORMAT_CHANNELS_SOFT:
2844 if(device->Type != Loopback)
2846 alcSetError(device, ALC_INVALID_DEVICE);
2847 return 0;
2849 values[0] = device->FmtChans;
2850 return 1;
2852 case ALC_FORMAT_TYPE_SOFT:
2853 if(device->Type != Loopback)
2855 alcSetError(device, ALC_INVALID_DEVICE);
2856 return 0;
2858 values[0] = device->FmtType;
2859 return 1;
2861 case ALC_MONO_SOURCES:
2862 values[0] = device->NumMonoSources;
2863 return 1;
2865 case ALC_STEREO_SOURCES:
2866 values[0] = device->NumStereoSources;
2867 return 1;
2869 case ALC_MAX_AUXILIARY_SENDS:
2870 values[0] = device->NumAuxSends;
2871 return 1;
2873 case ALC_CONNECTED:
2874 values[0] = device->Connected;
2875 return 1;
2877 case ALC_HRTF_SOFT:
2878 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2879 return 1;
2881 case ALC_HRTF_STATUS_SOFT:
2882 values[0] = device->Hrtf_Status;
2883 return 1;
2885 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2886 FreeHrtfList(&device->Hrtf_List);
2887 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2888 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2889 return 1;
2891 default:
2892 alcSetError(device, ALC_INVALID_ENUM);
2893 return 0;
2895 return 0;
2898 /* alcGetIntegerv
2900 * Returns information about the device and the version of OpenAL
2902 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2904 VerifyDevice(&device);
2905 if(size <= 0 || values == NULL)
2906 alcSetError(device, ALC_INVALID_VALUE);
2907 else
2908 GetIntegerv(device, param, size, values);
2909 if(device) ALCdevice_DecRef(device);
2912 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2914 ALCint *ivals;
2915 ALsizei i;
2917 VerifyDevice(&device);
2918 if(size <= 0 || values == NULL)
2919 alcSetError(device, ALC_INVALID_VALUE);
2920 else if(!device || device->Type == Capture)
2922 ivals = malloc(size * sizeof(ALCint));
2923 size = GetIntegerv(device, pname, size, ivals);
2924 for(i = 0;i < size;i++)
2925 values[i] = ivals[i];
2926 free(ivals);
2928 else /* render device */
2930 switch(pname)
2932 case ALC_ATTRIBUTES_SIZE:
2933 *values = 19;
2934 break;
2936 case ALC_ALL_ATTRIBUTES:
2937 if(size < 19)
2938 alcSetError(device, ALC_INVALID_VALUE);
2939 else
2941 int i = 0;
2943 V0(device->Backend,lock)();
2944 values[i++] = ALC_FREQUENCY;
2945 values[i++] = device->Frequency;
2947 if(device->Type != Loopback)
2949 values[i++] = ALC_REFRESH;
2950 values[i++] = device->Frequency / device->UpdateSize;
2952 values[i++] = ALC_SYNC;
2953 values[i++] = ALC_FALSE;
2955 else
2957 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2958 values[i++] = device->FmtChans;
2960 values[i++] = ALC_FORMAT_TYPE_SOFT;
2961 values[i++] = device->FmtType;
2964 values[i++] = ALC_MONO_SOURCES;
2965 values[i++] = device->NumMonoSources;
2967 values[i++] = ALC_STEREO_SOURCES;
2968 values[i++] = device->NumStereoSources;
2970 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2971 values[i++] = device->NumAuxSends;
2973 values[i++] = ALC_HRTF_SOFT;
2974 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2976 values[i++] = ALC_HRTF_STATUS_SOFT;
2977 values[i++] = device->Hrtf_Status;
2979 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2980 values[i++] = device->ClockBase +
2981 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2983 values[i++] = 0;
2984 V0(device->Backend,unlock)();
2986 break;
2988 case ALC_DEVICE_CLOCK_SOFT:
2989 V0(device->Backend,lock)();
2990 *values = device->ClockBase +
2991 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2992 V0(device->Backend,unlock)();
2993 break;
2995 default:
2996 ivals = malloc(size * sizeof(ALCint));
2997 size = GetIntegerv(device, pname, size, ivals);
2998 for(i = 0;i < size;i++)
2999 values[i] = ivals[i];
3000 free(ivals);
3001 break;
3004 if(device)
3005 ALCdevice_DecRef(device);
3009 /* alcIsExtensionPresent
3011 * Determines if there is support for a particular extension
3013 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3015 ALCboolean bResult = ALC_FALSE;
3017 VerifyDevice(&device);
3019 if(!extName)
3020 alcSetError(device, ALC_INVALID_VALUE);
3021 else
3023 size_t len = strlen(extName);
3024 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3025 while(ptr && *ptr)
3027 if(strncasecmp(ptr, extName, len) == 0 &&
3028 (ptr[len] == '\0' || isspace(ptr[len])))
3030 bResult = ALC_TRUE;
3031 break;
3033 if((ptr=strchr(ptr, ' ')) != NULL)
3035 do {
3036 ++ptr;
3037 } while(isspace(*ptr));
3041 if(device)
3042 ALCdevice_DecRef(device);
3043 return bResult;
3047 /* alcGetProcAddress
3049 * Retrieves the function address for a particular extension function
3051 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3053 ALCvoid *ptr = NULL;
3055 if(!funcName)
3057 VerifyDevice(&device);
3058 alcSetError(device, ALC_INVALID_VALUE);
3059 if(device) ALCdevice_DecRef(device);
3061 else
3063 ALsizei i = 0;
3064 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3065 i++;
3066 ptr = alcFunctions[i].address;
3069 return ptr;
3073 /* alcGetEnumValue
3075 * Get the value for a particular ALC enumeration name
3077 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3079 ALCenum val = 0;
3081 if(!enumName)
3083 VerifyDevice(&device);
3084 alcSetError(device, ALC_INVALID_VALUE);
3085 if(device) ALCdevice_DecRef(device);
3087 else
3089 ALsizei i = 0;
3090 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3091 i++;
3092 val = enumeration[i].value;
3095 return val;
3099 /* alcCreateContext
3101 * Create and attach a context to the given device.
3103 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3105 ALCcontext *ALContext;
3106 ALCenum err;
3108 LockLists();
3109 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3111 UnlockLists();
3112 alcSetError(device, ALC_INVALID_DEVICE);
3113 if(device) ALCdevice_DecRef(device);
3114 return NULL;
3117 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3119 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3121 UnlockLists();
3122 alcSetError(device, err);
3123 if(err == ALC_INVALID_DEVICE)
3125 V0(device->Backend,lock)();
3126 aluHandleDisconnect(device);
3127 V0(device->Backend,unlock)();
3129 ALCdevice_DecRef(device);
3130 return NULL;
3133 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3134 if(ALContext)
3136 InitRef(&ALContext->ref, 1);
3137 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3139 VECTOR_INIT(ALContext->ActiveAuxSlots);
3141 ALContext->VoiceCount = 0;
3142 ALContext->MaxVoices = 256;
3143 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3145 if(!ALContext || !ALContext->Voices)
3147 if(!ATOMIC_LOAD(&device->ContextList))
3149 V0(device->Backend,stop)();
3150 device->Flags &= ~DEVICE_RUNNING;
3152 UnlockLists();
3154 if(ALContext)
3156 al_free(ALContext->Voices);
3157 ALContext->Voices = NULL;
3159 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3161 al_free(ALContext);
3162 ALContext = NULL;
3165 alcSetError(device, ALC_OUT_OF_MEMORY);
3166 ALCdevice_DecRef(device);
3167 return NULL;
3170 ALContext->Device = device;
3171 ALCdevice_IncRef(device);
3172 InitContext(ALContext);
3175 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3176 do {
3177 ALContext->next = head;
3178 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3180 UnlockLists();
3182 ALCdevice_DecRef(device);
3184 TRACE("Created context %p\n", ALContext);
3185 return ALContext;
3188 /* alcDestroyContext
3190 * Remove a context from its device
3192 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3194 ALCdevice *Device;
3196 LockLists();
3197 /* alcGetContextsDevice sets an error for invalid contexts */
3198 Device = alcGetContextsDevice(context);
3199 if(Device)
3201 ReleaseContext(context, Device);
3202 if(!ATOMIC_LOAD(&Device->ContextList))
3204 V0(Device->Backend,stop)();
3205 Device->Flags &= ~DEVICE_RUNNING;
3208 UnlockLists();
3212 /* alcGetCurrentContext
3214 * Returns the currently active context on the calling thread
3216 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3218 ALCcontext *Context = altss_get(LocalContext);
3219 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3220 return Context;
3223 /* alcGetThreadContext
3225 * Returns the currently active thread-local context
3227 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3229 return altss_get(LocalContext);
3233 /* alcMakeContextCurrent
3235 * Makes the given context the active process-wide context, and removes the
3236 * thread-local context for the calling thread.
3238 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3240 /* context must be valid or NULL */
3241 if(context && !VerifyContext(&context))
3243 alcSetError(NULL, ALC_INVALID_CONTEXT);
3244 return ALC_FALSE;
3246 /* context's reference count is already incremented */
3247 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3248 if(context) ALCcontext_DecRef(context);
3250 if((context=altss_get(LocalContext)) != NULL)
3252 altss_set(LocalContext, NULL);
3253 ALCcontext_DecRef(context);
3256 return ALC_TRUE;
3259 /* alcSetThreadContext
3261 * Makes the given context the active context for the current thread
3263 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3265 ALCcontext *old;
3267 /* context must be valid or NULL */
3268 if(context && !VerifyContext(&context))
3270 alcSetError(NULL, ALC_INVALID_CONTEXT);
3271 return ALC_FALSE;
3273 /* context's reference count is already incremented */
3274 old = altss_get(LocalContext);
3275 altss_set(LocalContext, context);
3276 if(old) ALCcontext_DecRef(old);
3278 return ALC_TRUE;
3282 /* alcGetContextsDevice
3284 * Returns the device that a particular context is attached to
3286 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3288 ALCdevice *Device;
3290 if(!VerifyContext(&Context))
3292 alcSetError(NULL, ALC_INVALID_CONTEXT);
3293 return NULL;
3295 Device = Context->Device;
3296 ALCcontext_DecRef(Context);
3298 return Device;
3302 /* alcOpenDevice
3304 * Opens the named device.
3306 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3308 const ALCchar *fmt;
3309 ALCdevice *device;
3310 ALCenum err;
3312 DO_INITCONFIG();
3314 if(!PlaybackBackend.name)
3316 alcSetError(NULL, ALC_INVALID_VALUE);
3317 return NULL;
3320 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3321 #ifdef _WIN32
3322 /* Some old Windows apps hardcode these expecting OpenAL to use a
3323 * specific audio API, even when they're not enumerated. Creative's
3324 * router effectively ignores them too.
3326 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3327 || strcasecmp(deviceName, "MMSYSTEM") == 0
3328 #endif
3330 deviceName = NULL;
3332 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3333 if(!device)
3335 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3336 return NULL;
3339 //Validate device
3340 InitRef(&device->ref, 1);
3341 device->Connected = ALC_TRUE;
3342 device->Type = Playback;
3343 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3345 device->Flags = 0;
3346 device->Bs2b = NULL;
3347 VECTOR_INIT(device->Hrtf_List);
3348 AL_STRING_INIT(device->Hrtf_Name);
3349 device->Hrtf_Mode = DisabledHrtf;
3350 AL_STRING_INIT(device->DeviceName);
3351 device->DryBuffer = NULL;
3353 ATOMIC_INIT(&device->ContextList, NULL);
3355 device->ClockBase = 0;
3356 device->SamplesDone = 0;
3358 device->MaxNoOfSources = 256;
3359 device->AuxiliaryEffectSlotMax = 4;
3360 device->NumAuxSends = MAX_SENDS;
3362 InitUIntMap(&device->BufferMap, ~0);
3363 InitUIntMap(&device->EffectMap, ~0);
3364 InitUIntMap(&device->FilterMap, ~0);
3366 //Set output format
3367 device->FmtChans = DevFmtChannelsDefault;
3368 device->FmtType = DevFmtTypeDefault;
3369 device->Frequency = DEFAULT_OUTPUT_RATE;
3370 device->IsHeadphones = AL_FALSE;
3371 device->NumUpdates = 4;
3372 device->UpdateSize = 1024;
3374 if(!PlaybackBackend.getFactory)
3375 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3376 ALCbackend_Playback);
3377 else
3379 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3380 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3382 if(!device->Backend)
3384 al_free(device);
3385 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3386 return NULL;
3390 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3392 static const struct {
3393 const char name[16];
3394 enum DevFmtChannels chans;
3395 } chanlist[] = {
3396 { "mono", DevFmtMono },
3397 { "stereo", DevFmtStereo },
3398 { "quad", DevFmtQuad },
3399 { "surround51", DevFmtX51 },
3400 { "surround61", DevFmtX61 },
3401 { "surround71", DevFmtX71 },
3402 { "surround51rear", DevFmtX51Rear },
3404 size_t i;
3406 for(i = 0;i < COUNTOF(chanlist);i++)
3408 if(strcasecmp(chanlist[i].name, fmt) == 0)
3410 device->FmtChans = chanlist[i].chans;
3411 device->Flags |= DEVICE_CHANNELS_REQUEST;
3412 break;
3415 if(i == COUNTOF(chanlist))
3416 ERR("Unsupported channels: %s\n", fmt);
3418 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3420 static const struct {
3421 const char name[16];
3422 enum DevFmtType type;
3423 } typelist[] = {
3424 { "int8", DevFmtByte },
3425 { "uint8", DevFmtUByte },
3426 { "int16", DevFmtShort },
3427 { "uint16", DevFmtUShort },
3428 { "int32", DevFmtInt },
3429 { "uint32", DevFmtUInt },
3430 { "float32", DevFmtFloat },
3432 size_t i;
3434 for(i = 0;i < COUNTOF(typelist);i++)
3436 if(strcasecmp(typelist[i].name, fmt) == 0)
3438 device->FmtType = typelist[i].type;
3439 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3440 break;
3443 if(i == COUNTOF(typelist))
3444 ERR("Unsupported sample-type: %s\n", fmt);
3447 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3449 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3450 if(device->Frequency < MIN_OUTPUT_RATE)
3451 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3452 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3455 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3456 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3458 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3459 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3460 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3461 device->UpdateSize = (device->UpdateSize+3)&~3;
3463 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3464 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3466 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3467 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3469 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3470 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3472 device->NumStereoSources = 1;
3473 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3475 // Find a playback device to open
3476 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3478 DELETE_OBJ(device->Backend);
3479 al_free(device);
3480 alcSetError(NULL, err);
3481 return NULL;
3484 if(DefaultEffect.type != AL_EFFECT_NULL)
3486 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3487 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3489 device->DefaultSlot = NULL;
3490 ERR("Failed to initialize the default effect slot\n");
3492 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3494 ALeffectState *state = device->DefaultSlot->EffectState;
3495 device->DefaultSlot = NULL;
3496 DELETE_OBJ(state);
3497 ERR("Failed to initialize the default effect\n");
3499 else
3500 aluInitEffectPanning(device->DefaultSlot);
3504 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3505 do {
3506 device->next = head;
3507 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3510 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3511 return device;
3514 /* alcCloseDevice
3516 * Closes the given device.
3518 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3520 ALCdevice *list, *origdev, *nextdev;
3521 ALCcontext *ctx;
3523 LockLists();
3524 list = ATOMIC_LOAD(&DeviceList);
3525 do {
3526 if(list == device)
3527 break;
3528 } while((list=list->next) != NULL);
3529 if(!list || list->Type == Capture)
3531 alcSetError(list, ALC_INVALID_DEVICE);
3532 UnlockLists();
3533 return ALC_FALSE;
3536 origdev = device;
3537 nextdev = device->next;
3538 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3540 do {
3541 list = origdev;
3542 origdev = device;
3543 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3545 UnlockLists();
3547 ctx = ATOMIC_LOAD(&device->ContextList);
3548 while(ctx != NULL)
3550 ALCcontext *next = ctx->next;
3551 WARN("Releasing context %p\n", ctx);
3552 ReleaseContext(ctx, device);
3553 ctx = next;
3555 if((device->Flags&DEVICE_RUNNING))
3556 V0(device->Backend,stop)();
3557 device->Flags &= ~DEVICE_RUNNING;
3559 ALCdevice_DecRef(device);
3561 return ALC_TRUE;
3565 /************************************************
3566 * ALC capture functions
3567 ************************************************/
3568 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3570 ALCdevice *device = NULL;
3571 ALCenum err;
3573 DO_INITCONFIG();
3575 if(!CaptureBackend.name)
3577 alcSetError(NULL, ALC_INVALID_VALUE);
3578 return NULL;
3581 if(samples <= 0)
3583 alcSetError(NULL, ALC_INVALID_VALUE);
3584 return NULL;
3587 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3588 deviceName = NULL;
3590 device = al_calloc(16, sizeof(ALCdevice));
3591 if(!device)
3593 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3594 return NULL;
3597 //Validate device
3598 InitRef(&device->ref, 1);
3599 device->Connected = ALC_TRUE;
3600 device->Type = Capture;
3602 VECTOR_INIT(device->Hrtf_List);
3603 AL_STRING_INIT(device->Hrtf_Name);
3605 AL_STRING_INIT(device->DeviceName);
3606 device->DryBuffer = NULL;
3608 InitUIntMap(&device->BufferMap, ~0);
3609 InitUIntMap(&device->EffectMap, ~0);
3610 InitUIntMap(&device->FilterMap, ~0);
3612 if(!CaptureBackend.getFactory)
3613 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3614 ALCbackend_Capture);
3615 else
3617 ALCbackendFactory *factory = CaptureBackend.getFactory();
3618 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3620 if(!device->Backend)
3622 al_free(device);
3623 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3624 return NULL;
3627 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3628 device->Frequency = frequency;
3630 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3631 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3633 al_free(device);
3634 alcSetError(NULL, ALC_INVALID_ENUM);
3635 return NULL;
3637 device->IsHeadphones = AL_FALSE;
3639 device->UpdateSize = samples;
3640 device->NumUpdates = 1;
3642 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3644 al_free(device);
3645 alcSetError(NULL, err);
3646 return NULL;
3650 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3651 do {
3652 device->next = head;
3653 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3656 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3657 return device;
3660 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3662 ALCdevice *list, *next, *nextdev;
3664 LockLists();
3665 list = ATOMIC_LOAD(&DeviceList);
3666 do {
3667 if(list == device)
3668 break;
3669 } while((list=list->next) != NULL);
3670 if(!list || list->Type != Capture)
3672 alcSetError(list, ALC_INVALID_DEVICE);
3673 UnlockLists();
3674 return ALC_FALSE;
3677 next = device;
3678 nextdev = device->next;
3679 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3681 do {
3682 list = next;
3683 next = device;
3684 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3686 UnlockLists();
3688 ALCdevice_DecRef(device);
3690 return ALC_TRUE;
3693 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3695 if(!VerifyDevice(&device) || device->Type != Capture)
3696 alcSetError(device, ALC_INVALID_DEVICE);
3697 else
3699 V0(device->Backend,lock)();
3700 if(!device->Connected)
3701 alcSetError(device, ALC_INVALID_DEVICE);
3702 else if(!(device->Flags&DEVICE_RUNNING))
3704 if(V0(device->Backend,start)())
3705 device->Flags |= DEVICE_RUNNING;
3706 else
3708 aluHandleDisconnect(device);
3709 alcSetError(device, ALC_INVALID_DEVICE);
3712 V0(device->Backend,unlock)();
3715 if(device) ALCdevice_DecRef(device);
3718 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3720 if(!VerifyDevice(&device) || device->Type != Capture)
3721 alcSetError(device, ALC_INVALID_DEVICE);
3722 else
3724 V0(device->Backend,lock)();
3725 if((device->Flags&DEVICE_RUNNING))
3726 V0(device->Backend,stop)();
3727 device->Flags &= ~DEVICE_RUNNING;
3728 V0(device->Backend,unlock)();
3731 if(device) ALCdevice_DecRef(device);
3734 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3736 if(!VerifyDevice(&device) || device->Type != Capture)
3737 alcSetError(device, ALC_INVALID_DEVICE);
3738 else
3740 ALCenum err = ALC_INVALID_VALUE;
3742 V0(device->Backend,lock)();
3743 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3744 err = V(device->Backend,captureSamples)(buffer, samples);
3745 V0(device->Backend,unlock)();
3747 if(err != ALC_NO_ERROR)
3748 alcSetError(device, err);
3750 if(device) ALCdevice_DecRef(device);
3754 /************************************************
3755 * ALC loopback functions
3756 ************************************************/
3758 /* alcLoopbackOpenDeviceSOFT
3760 * Open a loopback device, for manual rendering.
3762 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3764 ALCbackendFactory *factory;
3765 ALCdevice *device;
3767 DO_INITCONFIG();
3769 /* Make sure the device name, if specified, is us. */
3770 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3772 alcSetError(NULL, ALC_INVALID_VALUE);
3773 return NULL;
3776 device = al_calloc(16, sizeof(ALCdevice));
3777 if(!device)
3779 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3780 return NULL;
3783 //Validate device
3784 InitRef(&device->ref, 1);
3785 device->Connected = ALC_TRUE;
3786 device->Type = Loopback;
3787 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3789 device->Flags = 0;
3790 VECTOR_INIT(device->Hrtf_List);
3791 AL_STRING_INIT(device->Hrtf_Name);
3792 device->Bs2b = NULL;
3793 device->Hrtf_Mode = DisabledHrtf;
3794 AL_STRING_INIT(device->DeviceName);
3795 device->DryBuffer = NULL;
3797 ATOMIC_INIT(&device->ContextList, NULL);
3799 device->ClockBase = 0;
3800 device->SamplesDone = 0;
3802 device->MaxNoOfSources = 256;
3803 device->AuxiliaryEffectSlotMax = 4;
3804 device->NumAuxSends = MAX_SENDS;
3806 InitUIntMap(&device->BufferMap, ~0);
3807 InitUIntMap(&device->EffectMap, ~0);
3808 InitUIntMap(&device->FilterMap, ~0);
3810 factory = ALCloopbackFactory_getFactory();
3811 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3812 if(!device->Backend)
3814 al_free(device);
3815 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3816 return NULL;
3819 //Set output format
3820 device->NumUpdates = 0;
3821 device->UpdateSize = 0;
3823 device->Frequency = DEFAULT_OUTPUT_RATE;
3824 device->FmtChans = DevFmtChannelsDefault;
3825 device->FmtType = DevFmtTypeDefault;
3826 device->IsHeadphones = AL_FALSE;
3828 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3829 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3831 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3832 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3834 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3835 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3837 device->NumStereoSources = 1;
3838 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3840 // Open the "backend"
3841 V(device->Backend,open)("Loopback");
3844 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3845 do {
3846 device->next = head;
3847 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3850 TRACE("Created device %p\n", device);
3851 return device;
3854 /* alcIsRenderFormatSupportedSOFT
3856 * Determines if the loopback device supports the given format for rendering.
3858 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3860 ALCboolean ret = ALC_FALSE;
3862 if(!VerifyDevice(&device) || device->Type != Loopback)
3863 alcSetError(device, ALC_INVALID_DEVICE);
3864 else if(freq <= 0)
3865 alcSetError(device, ALC_INVALID_VALUE);
3866 else
3868 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3869 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3870 freq >= MIN_OUTPUT_RATE)
3871 ret = ALC_TRUE;
3873 if(device) ALCdevice_DecRef(device);
3875 return ret;
3878 /* alcRenderSamplesSOFT
3880 * Renders some samples into a buffer, using the format last set by the
3881 * attributes given to alcCreateContext.
3883 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3885 if(!VerifyDevice(&device) || device->Type != Loopback)
3886 alcSetError(device, ALC_INVALID_DEVICE);
3887 else if(samples < 0 || (samples > 0 && buffer == NULL))
3888 alcSetError(device, ALC_INVALID_VALUE);
3889 else
3890 aluMixData(device, buffer, samples);
3891 if(device) ALCdevice_DecRef(device);
3895 /************************************************
3896 * ALC DSP pause/resume functions
3897 ************************************************/
3899 /* alcDevicePauseSOFT
3901 * Pause the DSP to stop audio processing.
3903 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3905 if(!VerifyDevice(&device) || device->Type != Playback)
3906 alcSetError(device, ALC_INVALID_DEVICE);
3907 else
3909 LockLists();
3910 if((device->Flags&DEVICE_RUNNING))
3911 V0(device->Backend,stop)();
3912 device->Flags &= ~DEVICE_RUNNING;
3913 device->Flags |= DEVICE_PAUSED;
3914 UnlockLists();
3916 if(device) ALCdevice_DecRef(device);
3919 /* alcDeviceResumeSOFT
3921 * Resume the DSP to restart audio processing.
3923 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3925 if(!VerifyDevice(&device) || device->Type != Playback)
3926 alcSetError(device, ALC_INVALID_DEVICE);
3927 else
3929 LockLists();
3930 if((device->Flags&DEVICE_PAUSED))
3932 device->Flags &= ~DEVICE_PAUSED;
3933 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3935 if(V0(device->Backend,start)() != ALC_FALSE)
3936 device->Flags |= DEVICE_RUNNING;
3937 else
3939 alcSetError(device, ALC_INVALID_DEVICE);
3940 V0(device->Backend,lock)();
3941 aluHandleDisconnect(device);
3942 V0(device->Backend,unlock)();
3946 UnlockLists();
3948 if(device) ALCdevice_DecRef(device);
3952 /************************************************
3953 * ALC HRTF functions
3954 ************************************************/
3956 /* alcGetStringiSOFT
3958 * Gets a string parameter at the given index.
3960 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3962 const ALCchar *str = NULL;
3964 if(!VerifyDevice(&device) || device->Type == Capture)
3965 alcSetError(device, ALC_INVALID_DEVICE);
3966 else switch(paramName)
3968 case ALC_HRTF_SPECIFIER_SOFT:
3969 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
3970 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
3971 else
3972 alcSetError(device, ALC_INVALID_VALUE);
3973 break;
3975 default:
3976 alcSetError(device, ALC_INVALID_ENUM);
3977 break;
3979 if(device) ALCdevice_DecRef(device);
3981 return str;
3984 /* alcResetDeviceSOFT
3986 * Resets the given device output, using the specified attribute list.
3988 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
3990 ALCenum err;
3992 LockLists();
3993 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3995 UnlockLists();
3996 alcSetError(device, ALC_INVALID_DEVICE);
3997 if(device) ALCdevice_DecRef(device);
3998 return ALC_FALSE;
4001 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
4003 UnlockLists();
4004 alcSetError(device, err);
4005 if(err == ALC_INVALID_DEVICE)
4007 V0(device->Backend,lock)();
4008 aluHandleDisconnect(device);
4009 V0(device->Backend,unlock)();
4011 ALCdevice_DecRef(device);
4012 return ALC_FALSE;
4014 UnlockLists();
4015 ALCdevice_DecRef(device);
4017 return ALC_TRUE;