Use 2-channel UHJ for stereo output
[openal-soft.git] / Alc / ALc.c
blob01fc8a34bd33bb08f91ce26c7e3d4ba171bd3f97
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 "uhjfilter.h"
40 #include "alu.h"
42 #include "compat.h"
43 #include "threads.h"
44 #include "alstring.h"
46 #include "backends/base.h"
49 /************************************************
50 * Backends
51 ************************************************/
52 struct BackendInfo {
53 const char *name;
54 ALCbackendFactory* (*getFactory)(void);
55 ALCboolean (*Init)(BackendFuncs*);
56 void (*Deinit)(void);
57 void (*Probe)(enum DevProbe);
58 BackendFuncs Funcs;
61 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
62 static struct BackendInfo BackendList[] = {
63 #ifdef HAVE_JACK
64 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
65 #endif
66 #ifdef HAVE_PULSEAUDIO
67 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
68 #endif
69 #ifdef HAVE_ALSA
70 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
71 #endif
72 #ifdef HAVE_COREAUDIO
73 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
74 #endif
75 #ifdef HAVE_OSS
76 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
77 #endif
78 #ifdef HAVE_SOLARIS
79 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
80 #endif
81 #ifdef HAVE_SNDIO
82 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
83 #endif
84 #ifdef HAVE_QSA
85 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
86 #endif
87 #ifdef HAVE_MMDEVAPI
88 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
89 #endif
90 #ifdef HAVE_DSOUND
91 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
92 #endif
93 #ifdef HAVE_WINMM
94 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
95 #endif
96 #ifdef HAVE_PORTAUDIO
97 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
98 #endif
99 #ifdef HAVE_OPENSL
100 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
101 #endif
103 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
104 #ifdef HAVE_WAVE
105 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
106 #endif
108 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
110 #undef EmptyFuncs
112 static struct BackendInfo PlaybackBackend;
113 static struct BackendInfo CaptureBackend;
116 /************************************************
117 * Functions, enums, and errors
118 ************************************************/
119 typedef struct ALCfunction {
120 const ALCchar *funcName;
121 ALCvoid *address;
122 } ALCfunction;
124 typedef struct ALCenums {
125 const ALCchar *enumName;
126 ALCenum value;
127 } ALCenums;
129 #define DECL(x) { #x, (ALCvoid*)(x) }
130 static const ALCfunction alcFunctions[] = {
131 DECL(alcCreateContext),
132 DECL(alcMakeContextCurrent),
133 DECL(alcProcessContext),
134 DECL(alcSuspendContext),
135 DECL(alcDestroyContext),
136 DECL(alcGetCurrentContext),
137 DECL(alcGetContextsDevice),
138 DECL(alcOpenDevice),
139 DECL(alcCloseDevice),
140 DECL(alcGetError),
141 DECL(alcIsExtensionPresent),
142 DECL(alcGetProcAddress),
143 DECL(alcGetEnumValue),
144 DECL(alcGetString),
145 DECL(alcGetIntegerv),
146 DECL(alcCaptureOpenDevice),
147 DECL(alcCaptureCloseDevice),
148 DECL(alcCaptureStart),
149 DECL(alcCaptureStop),
150 DECL(alcCaptureSamples),
152 DECL(alcSetThreadContext),
153 DECL(alcGetThreadContext),
155 DECL(alcLoopbackOpenDeviceSOFT),
156 DECL(alcIsRenderFormatSupportedSOFT),
157 DECL(alcRenderSamplesSOFT),
159 DECL(alcDevicePauseSOFT),
160 DECL(alcDeviceResumeSOFT),
162 DECL(alcGetStringiSOFT),
163 DECL(alcResetDeviceSOFT),
165 DECL(alcGetInteger64vSOFT),
167 DECL(alEnable),
168 DECL(alDisable),
169 DECL(alIsEnabled),
170 DECL(alGetString),
171 DECL(alGetBooleanv),
172 DECL(alGetIntegerv),
173 DECL(alGetFloatv),
174 DECL(alGetDoublev),
175 DECL(alGetBoolean),
176 DECL(alGetInteger),
177 DECL(alGetFloat),
178 DECL(alGetDouble),
179 DECL(alGetError),
180 DECL(alIsExtensionPresent),
181 DECL(alGetProcAddress),
182 DECL(alGetEnumValue),
183 DECL(alListenerf),
184 DECL(alListener3f),
185 DECL(alListenerfv),
186 DECL(alListeneri),
187 DECL(alListener3i),
188 DECL(alListeneriv),
189 DECL(alGetListenerf),
190 DECL(alGetListener3f),
191 DECL(alGetListenerfv),
192 DECL(alGetListeneri),
193 DECL(alGetListener3i),
194 DECL(alGetListeneriv),
195 DECL(alGenSources),
196 DECL(alDeleteSources),
197 DECL(alIsSource),
198 DECL(alSourcef),
199 DECL(alSource3f),
200 DECL(alSourcefv),
201 DECL(alSourcei),
202 DECL(alSource3i),
203 DECL(alSourceiv),
204 DECL(alGetSourcef),
205 DECL(alGetSource3f),
206 DECL(alGetSourcefv),
207 DECL(alGetSourcei),
208 DECL(alGetSource3i),
209 DECL(alGetSourceiv),
210 DECL(alSourcePlayv),
211 DECL(alSourceStopv),
212 DECL(alSourceRewindv),
213 DECL(alSourcePausev),
214 DECL(alSourcePlay),
215 DECL(alSourceStop),
216 DECL(alSourceRewind),
217 DECL(alSourcePause),
218 DECL(alSourceQueueBuffers),
219 DECL(alSourceUnqueueBuffers),
220 DECL(alGenBuffers),
221 DECL(alDeleteBuffers),
222 DECL(alIsBuffer),
223 DECL(alBufferData),
224 DECL(alBufferf),
225 DECL(alBuffer3f),
226 DECL(alBufferfv),
227 DECL(alBufferi),
228 DECL(alBuffer3i),
229 DECL(alBufferiv),
230 DECL(alGetBufferf),
231 DECL(alGetBuffer3f),
232 DECL(alGetBufferfv),
233 DECL(alGetBufferi),
234 DECL(alGetBuffer3i),
235 DECL(alGetBufferiv),
236 DECL(alDopplerFactor),
237 DECL(alDopplerVelocity),
238 DECL(alSpeedOfSound),
239 DECL(alDistanceModel),
241 DECL(alGenFilters),
242 DECL(alDeleteFilters),
243 DECL(alIsFilter),
244 DECL(alFilteri),
245 DECL(alFilteriv),
246 DECL(alFilterf),
247 DECL(alFilterfv),
248 DECL(alGetFilteri),
249 DECL(alGetFilteriv),
250 DECL(alGetFilterf),
251 DECL(alGetFilterfv),
252 DECL(alGenEffects),
253 DECL(alDeleteEffects),
254 DECL(alIsEffect),
255 DECL(alEffecti),
256 DECL(alEffectiv),
257 DECL(alEffectf),
258 DECL(alEffectfv),
259 DECL(alGetEffecti),
260 DECL(alGetEffectiv),
261 DECL(alGetEffectf),
262 DECL(alGetEffectfv),
263 DECL(alGenAuxiliaryEffectSlots),
264 DECL(alDeleteAuxiliaryEffectSlots),
265 DECL(alIsAuxiliaryEffectSlot),
266 DECL(alAuxiliaryEffectSloti),
267 DECL(alAuxiliaryEffectSlotiv),
268 DECL(alAuxiliaryEffectSlotf),
269 DECL(alAuxiliaryEffectSlotfv),
270 DECL(alGetAuxiliaryEffectSloti),
271 DECL(alGetAuxiliaryEffectSlotiv),
272 DECL(alGetAuxiliaryEffectSlotf),
273 DECL(alGetAuxiliaryEffectSlotfv),
275 DECL(alBufferSubDataSOFT),
277 DECL(alBufferSamplesSOFT),
278 DECL(alBufferSubSamplesSOFT),
279 DECL(alGetBufferSamplesSOFT),
280 DECL(alIsBufferFormatSupportedSOFT),
282 DECL(alDeferUpdatesSOFT),
283 DECL(alProcessUpdatesSOFT),
285 DECL(alSourcedSOFT),
286 DECL(alSource3dSOFT),
287 DECL(alSourcedvSOFT),
288 DECL(alGetSourcedSOFT),
289 DECL(alGetSource3dSOFT),
290 DECL(alGetSourcedvSOFT),
291 DECL(alSourcei64SOFT),
292 DECL(alSource3i64SOFT),
293 DECL(alSourcei64vSOFT),
294 DECL(alGetSourcei64SOFT),
295 DECL(alGetSource3i64SOFT),
296 DECL(alGetSourcei64vSOFT),
298 { NULL, NULL }
300 #undef DECL
302 #define DECL(x) { #x, (x) }
303 static const ALCenums enumeration[] = {
304 DECL(ALC_INVALID),
305 DECL(ALC_FALSE),
306 DECL(ALC_TRUE),
308 DECL(ALC_MAJOR_VERSION),
309 DECL(ALC_MINOR_VERSION),
310 DECL(ALC_ATTRIBUTES_SIZE),
311 DECL(ALC_ALL_ATTRIBUTES),
312 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
313 DECL(ALC_DEVICE_SPECIFIER),
314 DECL(ALC_ALL_DEVICES_SPECIFIER),
315 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
316 DECL(ALC_EXTENSIONS),
317 DECL(ALC_FREQUENCY),
318 DECL(ALC_REFRESH),
319 DECL(ALC_SYNC),
320 DECL(ALC_MONO_SOURCES),
321 DECL(ALC_STEREO_SOURCES),
322 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
323 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
324 DECL(ALC_CAPTURE_SAMPLES),
325 DECL(ALC_CONNECTED),
327 DECL(ALC_EFX_MAJOR_VERSION),
328 DECL(ALC_EFX_MINOR_VERSION),
329 DECL(ALC_MAX_AUXILIARY_SENDS),
331 DECL(ALC_FORMAT_CHANNELS_SOFT),
332 DECL(ALC_FORMAT_TYPE_SOFT),
334 DECL(ALC_MONO_SOFT),
335 DECL(ALC_STEREO_SOFT),
336 DECL(ALC_QUAD_SOFT),
337 DECL(ALC_5POINT1_SOFT),
338 DECL(ALC_6POINT1_SOFT),
339 DECL(ALC_7POINT1_SOFT),
341 DECL(ALC_BYTE_SOFT),
342 DECL(ALC_UNSIGNED_BYTE_SOFT),
343 DECL(ALC_SHORT_SOFT),
344 DECL(ALC_UNSIGNED_SHORT_SOFT),
345 DECL(ALC_INT_SOFT),
346 DECL(ALC_UNSIGNED_INT_SOFT),
347 DECL(ALC_FLOAT_SOFT),
349 DECL(ALC_HRTF_SOFT),
350 DECL(ALC_DONT_CARE_SOFT),
351 DECL(ALC_HRTF_STATUS_SOFT),
352 DECL(ALC_HRTF_DISABLED_SOFT),
353 DECL(ALC_HRTF_ENABLED_SOFT),
354 DECL(ALC_HRTF_DENIED_SOFT),
355 DECL(ALC_HRTF_REQUIRED_SOFT),
356 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
357 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
358 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
359 DECL(ALC_HRTF_SPECIFIER_SOFT),
360 DECL(ALC_HRTF_ID_SOFT),
362 DECL(ALC_NO_ERROR),
363 DECL(ALC_INVALID_DEVICE),
364 DECL(ALC_INVALID_CONTEXT),
365 DECL(ALC_INVALID_ENUM),
366 DECL(ALC_INVALID_VALUE),
367 DECL(ALC_OUT_OF_MEMORY),
370 DECL(AL_INVALID),
371 DECL(AL_NONE),
372 DECL(AL_FALSE),
373 DECL(AL_TRUE),
375 DECL(AL_SOURCE_RELATIVE),
376 DECL(AL_CONE_INNER_ANGLE),
377 DECL(AL_CONE_OUTER_ANGLE),
378 DECL(AL_PITCH),
379 DECL(AL_POSITION),
380 DECL(AL_DIRECTION),
381 DECL(AL_VELOCITY),
382 DECL(AL_LOOPING),
383 DECL(AL_BUFFER),
384 DECL(AL_GAIN),
385 DECL(AL_MIN_GAIN),
386 DECL(AL_MAX_GAIN),
387 DECL(AL_ORIENTATION),
388 DECL(AL_REFERENCE_DISTANCE),
389 DECL(AL_ROLLOFF_FACTOR),
390 DECL(AL_CONE_OUTER_GAIN),
391 DECL(AL_MAX_DISTANCE),
392 DECL(AL_SEC_OFFSET),
393 DECL(AL_SAMPLE_OFFSET),
394 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
395 DECL(AL_BYTE_OFFSET),
396 DECL(AL_BYTE_RW_OFFSETS_SOFT),
397 DECL(AL_SOURCE_TYPE),
398 DECL(AL_STATIC),
399 DECL(AL_STREAMING),
400 DECL(AL_UNDETERMINED),
401 DECL(AL_METERS_PER_UNIT),
402 DECL(AL_LOOP_POINTS_SOFT),
403 DECL(AL_DIRECT_CHANNELS_SOFT),
405 DECL(AL_DIRECT_FILTER),
406 DECL(AL_AUXILIARY_SEND_FILTER),
407 DECL(AL_AIR_ABSORPTION_FACTOR),
408 DECL(AL_ROOM_ROLLOFF_FACTOR),
409 DECL(AL_CONE_OUTER_GAINHF),
410 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
412 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
414 DECL(AL_SOURCE_STATE),
415 DECL(AL_INITIAL),
416 DECL(AL_PLAYING),
417 DECL(AL_PAUSED),
418 DECL(AL_STOPPED),
420 DECL(AL_BUFFERS_QUEUED),
421 DECL(AL_BUFFERS_PROCESSED),
423 DECL(AL_FORMAT_MONO8),
424 DECL(AL_FORMAT_MONO16),
425 DECL(AL_FORMAT_MONO_FLOAT32),
426 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
427 DECL(AL_FORMAT_STEREO8),
428 DECL(AL_FORMAT_STEREO16),
429 DECL(AL_FORMAT_STEREO_FLOAT32),
430 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
431 DECL(AL_FORMAT_MONO_IMA4),
432 DECL(AL_FORMAT_STEREO_IMA4),
433 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
434 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
435 DECL(AL_FORMAT_QUAD8_LOKI),
436 DECL(AL_FORMAT_QUAD16_LOKI),
437 DECL(AL_FORMAT_QUAD8),
438 DECL(AL_FORMAT_QUAD16),
439 DECL(AL_FORMAT_QUAD32),
440 DECL(AL_FORMAT_51CHN8),
441 DECL(AL_FORMAT_51CHN16),
442 DECL(AL_FORMAT_51CHN32),
443 DECL(AL_FORMAT_61CHN8),
444 DECL(AL_FORMAT_61CHN16),
445 DECL(AL_FORMAT_61CHN32),
446 DECL(AL_FORMAT_71CHN8),
447 DECL(AL_FORMAT_71CHN16),
448 DECL(AL_FORMAT_71CHN32),
449 DECL(AL_FORMAT_REAR8),
450 DECL(AL_FORMAT_REAR16),
451 DECL(AL_FORMAT_REAR32),
452 DECL(AL_FORMAT_MONO_MULAW),
453 DECL(AL_FORMAT_MONO_MULAW_EXT),
454 DECL(AL_FORMAT_STEREO_MULAW),
455 DECL(AL_FORMAT_STEREO_MULAW_EXT),
456 DECL(AL_FORMAT_QUAD_MULAW),
457 DECL(AL_FORMAT_51CHN_MULAW),
458 DECL(AL_FORMAT_61CHN_MULAW),
459 DECL(AL_FORMAT_71CHN_MULAW),
460 DECL(AL_FORMAT_REAR_MULAW),
461 DECL(AL_FORMAT_MONO_ALAW_EXT),
462 DECL(AL_FORMAT_STEREO_ALAW_EXT),
464 DECL(AL_MONO8_SOFT),
465 DECL(AL_MONO16_SOFT),
466 DECL(AL_MONO32F_SOFT),
467 DECL(AL_STEREO8_SOFT),
468 DECL(AL_STEREO16_SOFT),
469 DECL(AL_STEREO32F_SOFT),
470 DECL(AL_QUAD8_SOFT),
471 DECL(AL_QUAD16_SOFT),
472 DECL(AL_QUAD32F_SOFT),
473 DECL(AL_REAR8_SOFT),
474 DECL(AL_REAR16_SOFT),
475 DECL(AL_REAR32F_SOFT),
476 DECL(AL_5POINT1_8_SOFT),
477 DECL(AL_5POINT1_16_SOFT),
478 DECL(AL_5POINT1_32F_SOFT),
479 DECL(AL_6POINT1_8_SOFT),
480 DECL(AL_6POINT1_16_SOFT),
481 DECL(AL_6POINT1_32F_SOFT),
482 DECL(AL_7POINT1_8_SOFT),
483 DECL(AL_7POINT1_16_SOFT),
484 DECL(AL_7POINT1_32F_SOFT),
485 DECL(AL_FORMAT_BFORMAT2D_8),
486 DECL(AL_FORMAT_BFORMAT2D_16),
487 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
488 DECL(AL_FORMAT_BFORMAT2D_MULAW),
489 DECL(AL_FORMAT_BFORMAT3D_8),
490 DECL(AL_FORMAT_BFORMAT3D_16),
491 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
492 DECL(AL_FORMAT_BFORMAT3D_MULAW),
494 DECL(AL_MONO_SOFT),
495 DECL(AL_STEREO_SOFT),
496 DECL(AL_QUAD_SOFT),
497 DECL(AL_REAR_SOFT),
498 DECL(AL_5POINT1_SOFT),
499 DECL(AL_6POINT1_SOFT),
500 DECL(AL_7POINT1_SOFT),
502 DECL(AL_BYTE_SOFT),
503 DECL(AL_UNSIGNED_BYTE_SOFT),
504 DECL(AL_SHORT_SOFT),
505 DECL(AL_UNSIGNED_SHORT_SOFT),
506 DECL(AL_INT_SOFT),
507 DECL(AL_UNSIGNED_INT_SOFT),
508 DECL(AL_FLOAT_SOFT),
509 DECL(AL_DOUBLE_SOFT),
510 DECL(AL_BYTE3_SOFT),
511 DECL(AL_UNSIGNED_BYTE3_SOFT),
513 DECL(AL_FREQUENCY),
514 DECL(AL_BITS),
515 DECL(AL_CHANNELS),
516 DECL(AL_SIZE),
517 DECL(AL_INTERNAL_FORMAT_SOFT),
518 DECL(AL_BYTE_LENGTH_SOFT),
519 DECL(AL_SAMPLE_LENGTH_SOFT),
520 DECL(AL_SEC_LENGTH_SOFT),
521 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
522 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
524 DECL(AL_UNUSED),
525 DECL(AL_PENDING),
526 DECL(AL_PROCESSED),
528 DECL(AL_NO_ERROR),
529 DECL(AL_INVALID_NAME),
530 DECL(AL_INVALID_ENUM),
531 DECL(AL_INVALID_VALUE),
532 DECL(AL_INVALID_OPERATION),
533 DECL(AL_OUT_OF_MEMORY),
535 DECL(AL_VENDOR),
536 DECL(AL_VERSION),
537 DECL(AL_RENDERER),
538 DECL(AL_EXTENSIONS),
540 DECL(AL_DOPPLER_FACTOR),
541 DECL(AL_DOPPLER_VELOCITY),
542 DECL(AL_DISTANCE_MODEL),
543 DECL(AL_SPEED_OF_SOUND),
544 DECL(AL_SOURCE_DISTANCE_MODEL),
545 DECL(AL_DEFERRED_UPDATES_SOFT),
547 DECL(AL_INVERSE_DISTANCE),
548 DECL(AL_INVERSE_DISTANCE_CLAMPED),
549 DECL(AL_LINEAR_DISTANCE),
550 DECL(AL_LINEAR_DISTANCE_CLAMPED),
551 DECL(AL_EXPONENT_DISTANCE),
552 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
554 DECL(AL_FILTER_TYPE),
555 DECL(AL_FILTER_NULL),
556 DECL(AL_FILTER_LOWPASS),
557 DECL(AL_FILTER_HIGHPASS),
558 DECL(AL_FILTER_BANDPASS),
560 DECL(AL_LOWPASS_GAIN),
561 DECL(AL_LOWPASS_GAINHF),
563 DECL(AL_HIGHPASS_GAIN),
564 DECL(AL_HIGHPASS_GAINLF),
566 DECL(AL_BANDPASS_GAIN),
567 DECL(AL_BANDPASS_GAINHF),
568 DECL(AL_BANDPASS_GAINLF),
570 DECL(AL_EFFECT_TYPE),
571 DECL(AL_EFFECT_NULL),
572 DECL(AL_EFFECT_REVERB),
573 DECL(AL_EFFECT_EAXREVERB),
574 DECL(AL_EFFECT_CHORUS),
575 DECL(AL_EFFECT_DISTORTION),
576 DECL(AL_EFFECT_ECHO),
577 DECL(AL_EFFECT_FLANGER),
578 #if 0
579 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
580 DECL(AL_EFFECT_VOCAL_MORPHER),
581 DECL(AL_EFFECT_PITCH_SHIFTER),
582 #endif
583 DECL(AL_EFFECT_RING_MODULATOR),
584 #if 0
585 DECL(AL_EFFECT_AUTOWAH),
586 #endif
587 DECL(AL_EFFECT_COMPRESSOR),
588 DECL(AL_EFFECT_EQUALIZER),
589 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
590 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
592 DECL(AL_EAXREVERB_DENSITY),
593 DECL(AL_EAXREVERB_DIFFUSION),
594 DECL(AL_EAXREVERB_GAIN),
595 DECL(AL_EAXREVERB_GAINHF),
596 DECL(AL_EAXREVERB_GAINLF),
597 DECL(AL_EAXREVERB_DECAY_TIME),
598 DECL(AL_EAXREVERB_DECAY_HFRATIO),
599 DECL(AL_EAXREVERB_DECAY_LFRATIO),
600 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
601 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
602 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
603 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
604 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
605 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
606 DECL(AL_EAXREVERB_ECHO_TIME),
607 DECL(AL_EAXREVERB_ECHO_DEPTH),
608 DECL(AL_EAXREVERB_MODULATION_TIME),
609 DECL(AL_EAXREVERB_MODULATION_DEPTH),
610 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
611 DECL(AL_EAXREVERB_HFREFERENCE),
612 DECL(AL_EAXREVERB_LFREFERENCE),
613 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
614 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
616 DECL(AL_REVERB_DENSITY),
617 DECL(AL_REVERB_DIFFUSION),
618 DECL(AL_REVERB_GAIN),
619 DECL(AL_REVERB_GAINHF),
620 DECL(AL_REVERB_DECAY_TIME),
621 DECL(AL_REVERB_DECAY_HFRATIO),
622 DECL(AL_REVERB_REFLECTIONS_GAIN),
623 DECL(AL_REVERB_REFLECTIONS_DELAY),
624 DECL(AL_REVERB_LATE_REVERB_GAIN),
625 DECL(AL_REVERB_LATE_REVERB_DELAY),
626 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
627 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
628 DECL(AL_REVERB_DECAY_HFLIMIT),
630 DECL(AL_CHORUS_WAVEFORM),
631 DECL(AL_CHORUS_PHASE),
632 DECL(AL_CHORUS_RATE),
633 DECL(AL_CHORUS_DEPTH),
634 DECL(AL_CHORUS_FEEDBACK),
635 DECL(AL_CHORUS_DELAY),
637 DECL(AL_DISTORTION_EDGE),
638 DECL(AL_DISTORTION_GAIN),
639 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
640 DECL(AL_DISTORTION_EQCENTER),
641 DECL(AL_DISTORTION_EQBANDWIDTH),
643 DECL(AL_ECHO_DELAY),
644 DECL(AL_ECHO_LRDELAY),
645 DECL(AL_ECHO_DAMPING),
646 DECL(AL_ECHO_FEEDBACK),
647 DECL(AL_ECHO_SPREAD),
649 DECL(AL_FLANGER_WAVEFORM),
650 DECL(AL_FLANGER_PHASE),
651 DECL(AL_FLANGER_RATE),
652 DECL(AL_FLANGER_DEPTH),
653 DECL(AL_FLANGER_FEEDBACK),
654 DECL(AL_FLANGER_DELAY),
656 DECL(AL_RING_MODULATOR_FREQUENCY),
657 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
658 DECL(AL_RING_MODULATOR_WAVEFORM),
660 #if 0
661 DECL(AL_AUTOWAH_ATTACK_TIME),
662 DECL(AL_AUTOWAH_PEAK_GAIN),
663 DECL(AL_AUTOWAH_RELEASE_TIME),
664 DECL(AL_AUTOWAH_RESONANCE),
665 #endif
667 DECL(AL_COMPRESSOR_ONOFF),
669 DECL(AL_EQUALIZER_LOW_GAIN),
670 DECL(AL_EQUALIZER_LOW_CUTOFF),
671 DECL(AL_EQUALIZER_MID1_GAIN),
672 DECL(AL_EQUALIZER_MID1_CENTER),
673 DECL(AL_EQUALIZER_MID1_WIDTH),
674 DECL(AL_EQUALIZER_MID2_GAIN),
675 DECL(AL_EQUALIZER_MID2_CENTER),
676 DECL(AL_EQUALIZER_MID2_WIDTH),
677 DECL(AL_EQUALIZER_HIGH_GAIN),
678 DECL(AL_EQUALIZER_HIGH_CUTOFF),
680 DECL(AL_DEDICATED_GAIN),
682 { NULL, (ALCenum)0 }
684 #undef DECL
686 static const ALCchar alcNoError[] = "No Error";
687 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
688 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
689 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
690 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
691 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
694 /************************************************
695 * Global variables
696 ************************************************/
698 /* Enumerated device names */
699 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
701 static al_string alcAllDevicesList;
702 static al_string alcCaptureDeviceList;
704 /* Default is always the first in the list */
705 static ALCchar *alcDefaultAllDevicesSpecifier;
706 static ALCchar *alcCaptureDefaultDeviceSpecifier;
708 /* Default context extensions */
709 static const ALchar alExtList[] =
710 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
711 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
712 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
713 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
714 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
715 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
716 "AL_SOFT_source_latency AL_SOFT_source_length";
718 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
720 /* Thread-local current context */
721 static altss_t LocalContext;
722 /* Process-wide current context */
723 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
725 /* Mixing thread piority level */
726 ALint RTPrioLevel;
728 FILE *LogFile;
729 #ifdef _DEBUG
730 enum LogLevel LogLevel = LogWarning;
731 #else
732 enum LogLevel LogLevel = LogError;
733 #endif
735 /* Flag to trap ALC device errors */
736 static ALCboolean TrapALCError = ALC_FALSE;
738 /* One-time configuration init control */
739 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
741 /* Default effect that applies to sources that don't have an effect on send 0 */
742 static ALeffect DefaultEffect;
744 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
745 * updates.
747 static ALCboolean SuspendDefers = ALC_TRUE;
750 /************************************************
751 * ALC information
752 ************************************************/
753 static const ALCchar alcNoDeviceExtList[] =
754 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
755 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
756 static const ALCchar alcExtensionList[] =
757 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
758 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
759 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
760 "ALC_SOFT_loopback ALC_SOFT_pause_device";
761 static const ALCint alcMajorVersion = 1;
762 static const ALCint alcMinorVersion = 1;
764 static const ALCint alcEFXMajorVersion = 1;
765 static const ALCint alcEFXMinorVersion = 0;
768 /************************************************
769 * Device lists
770 ************************************************/
771 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
773 static almtx_t ListLock;
774 static inline void LockLists(void)
776 int lockret = almtx_lock(&ListLock);
777 assert(lockret == althrd_success);
779 static inline void UnlockLists(void)
781 int unlockret = almtx_unlock(&ListLock);
782 assert(unlockret == althrd_success);
785 /************************************************
786 * Library initialization
787 ************************************************/
788 #if defined(_WIN32)
789 static void alc_init(void);
790 static void alc_deinit(void);
791 static void alc_deinit_safe(void);
793 #ifndef AL_LIBTYPE_STATIC
794 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
796 switch(reason)
798 case DLL_PROCESS_ATTACH:
799 /* Pin the DLL so we won't get unloaded until the process terminates */
800 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
801 (WCHAR*)hModule, &hModule);
802 alc_init();
803 break;
805 case DLL_THREAD_DETACH:
806 break;
808 case DLL_PROCESS_DETACH:
809 if(!lpReserved)
810 alc_deinit();
811 else
812 alc_deinit_safe();
813 break;
815 return TRUE;
817 #elif defined(_MSC_VER)
818 #pragma section(".CRT$XCU",read)
819 static void alc_constructor(void);
820 static void alc_destructor(void);
821 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
823 static void alc_constructor(void)
825 atexit(alc_destructor);
826 alc_init();
829 static void alc_destructor(void)
831 alc_deinit();
833 #elif defined(HAVE_GCC_DESTRUCTOR)
834 static void alc_init(void) __attribute__((constructor));
835 static void alc_deinit(void) __attribute__((destructor));
836 #else
837 #error "No static initialization available on this platform!"
838 #endif
840 #elif defined(HAVE_GCC_DESTRUCTOR)
842 static void alc_init(void) __attribute__((constructor));
843 static void alc_deinit(void) __attribute__((destructor));
845 #else
846 #error "No global initialization available on this platform!"
847 #endif
849 static void ReleaseThreadCtx(void *ptr);
850 static void alc_init(void)
852 const char *str;
853 int ret;
855 LogFile = stderr;
857 AL_STRING_INIT(alcAllDevicesList);
858 AL_STRING_INIT(alcCaptureDeviceList);
860 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
861 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
862 ConeScale *= 0.5f;
864 str = getenv("__ALSOFT_REVERSE_Z");
865 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
866 ZScale *= -1.0f;
868 ret = altss_create(&LocalContext, ReleaseThreadCtx);
869 assert(ret == althrd_success);
871 ret = almtx_init(&ListLock, almtx_recursive);
872 assert(ret == althrd_success);
874 ThunkInit();
877 static void alc_initconfig(void)
879 const char *devs, *str;
880 ALuint capfilter;
881 float valf;
882 int i, n;
884 str = getenv("ALSOFT_LOGLEVEL");
885 if(str)
887 long lvl = strtol(str, NULL, 0);
888 if(lvl >= NoLog && lvl <= LogRef)
889 LogLevel = lvl;
892 str = getenv("ALSOFT_LOGFILE");
893 if(str && str[0])
895 FILE *logfile = al_fopen(str, "wt");
896 if(logfile) LogFile = logfile;
897 else ERR("Failed to open log file '%s'\n", str);
901 char buf[1024] = "";
902 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
903 for(i = 1;BackendList[i].name;i++)
904 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
905 TRACE("Supported backends: %s\n", buf);
907 ReadALConfig();
909 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
910 if(str && *str)
912 if(strcasecmp(str, "ignore") == 0)
914 SuspendDefers = ALC_FALSE;
915 TRACE("Selected context suspend behavior, \"ignore\"\n");
917 else
918 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
921 capfilter = 0;
922 #if defined(HAVE_SSE4_1)
923 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
924 #elif defined(HAVE_SSE3)
925 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
926 #elif defined(HAVE_SSE2)
927 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
928 #elif defined(HAVE_SSE)
929 capfilter |= CPU_CAP_SSE;
930 #endif
931 #ifdef HAVE_NEON
932 capfilter |= CPU_CAP_NEON;
933 #endif
934 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
936 if(strcasecmp(str, "all") == 0)
937 capfilter = 0;
938 else
940 size_t len;
941 const char *next = str;
943 do {
944 str = next;
945 while(isspace(str[0]))
946 str++;
947 next = strchr(str, ',');
949 if(!str[0] || str[0] == ',')
950 continue;
952 len = (next ? ((size_t)(next-str)) : strlen(str));
953 while(len > 0 && isspace(str[len-1]))
954 len--;
955 if(len == 3 && strncasecmp(str, "sse", len) == 0)
956 capfilter &= ~CPU_CAP_SSE;
957 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
958 capfilter &= ~CPU_CAP_SSE2;
959 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
960 capfilter &= ~CPU_CAP_SSE3;
961 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
962 capfilter &= ~CPU_CAP_SSE4_1;
963 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
964 capfilter &= ~CPU_CAP_NEON;
965 else
966 WARN("Invalid CPU extension \"%s\"\n", str);
967 } while(next++);
970 FillCPUCaps(capfilter);
972 #ifdef _WIN32
973 RTPrioLevel = 1;
974 #else
975 RTPrioLevel = 0;
976 #endif
977 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
979 aluInitMixer();
981 str = getenv("ALSOFT_TRAP_ERROR");
982 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
984 TrapALError = AL_TRUE;
985 TrapALCError = AL_TRUE;
987 else
989 str = getenv("ALSOFT_TRAP_AL_ERROR");
990 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
991 TrapALError = AL_TRUE;
992 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
994 str = getenv("ALSOFT_TRAP_ALC_ERROR");
995 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
996 TrapALCError = ALC_TRUE;
997 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1000 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1001 ReverbBoost *= powf(10.0f, valf / 20.0f);
1003 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1005 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1006 ConfigValueStr(NULL, NULL, "drivers", &devs))
1008 int n;
1009 size_t len;
1010 const char *next = devs;
1011 int endlist, delitem;
1013 i = 0;
1014 do {
1015 devs = next;
1016 while(isspace(devs[0]))
1017 devs++;
1018 next = strchr(devs, ',');
1020 delitem = (devs[0] == '-');
1021 if(devs[0] == '-') devs++;
1023 if(!devs[0] || devs[0] == ',')
1025 endlist = 0;
1026 continue;
1028 endlist = 1;
1030 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1031 while(len > 0 && isspace(devs[len-1]))
1032 len--;
1033 for(n = i;BackendList[n].name;n++)
1035 if(len == strlen(BackendList[n].name) &&
1036 strncmp(BackendList[n].name, devs, len) == 0)
1038 if(delitem)
1040 do {
1041 BackendList[n] = BackendList[n+1];
1042 ++n;
1043 } while(BackendList[n].name);
1045 else
1047 struct BackendInfo Bkp = BackendList[n];
1048 while(n > i)
1050 BackendList[n] = BackendList[n-1];
1051 --n;
1053 BackendList[n] = Bkp;
1055 i++;
1057 break;
1060 } while(next++);
1062 if(endlist)
1064 BackendList[i].name = NULL;
1065 BackendList[i].getFactory = NULL;
1066 BackendList[i].Init = NULL;
1067 BackendList[i].Deinit = NULL;
1068 BackendList[i].Probe = NULL;
1072 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1074 if(BackendList[i].getFactory)
1076 ALCbackendFactory *factory = BackendList[i].getFactory();
1077 if(!V0(factory,init)())
1079 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1080 continue;
1083 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1084 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1086 PlaybackBackend = BackendList[i];
1087 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1089 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1091 CaptureBackend = BackendList[i];
1092 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1095 continue;
1098 if(!BackendList[i].Init(&BackendList[i].Funcs))
1100 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1101 continue;
1104 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1105 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1107 PlaybackBackend = BackendList[i];
1108 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1110 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1112 CaptureBackend = BackendList[i];
1113 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1117 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1118 V0(factory,init)();
1121 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1123 size_t len;
1124 const char *next = str;
1126 do {
1127 str = next;
1128 next = strchr(str, ',');
1130 if(!str[0] || next == str)
1131 continue;
1133 len = (next ? ((size_t)(next-str)) : strlen(str));
1134 for(n = 0;EffectList[n].name;n++)
1136 if(len == strlen(EffectList[n].name) &&
1137 strncmp(EffectList[n].name, str, len) == 0)
1138 DisabledEffects[EffectList[n].type] = AL_TRUE;
1140 } while(next++);
1143 InitEffectFactoryMap();
1145 InitEffect(&DefaultEffect);
1146 str = getenv("ALSOFT_DEFAULT_REVERB");
1147 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1148 LoadReverbPreset(str, &DefaultEffect);
1150 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1153 /************************************************
1154 * Library deinitialization
1155 ************************************************/
1156 static void alc_cleanup(void)
1158 ALCdevice *dev;
1160 AL_STRING_DEINIT(alcAllDevicesList);
1161 AL_STRING_DEINIT(alcCaptureDeviceList);
1163 free(alcDefaultAllDevicesSpecifier);
1164 alcDefaultAllDevicesSpecifier = NULL;
1165 free(alcCaptureDefaultDeviceSpecifier);
1166 alcCaptureDefaultDeviceSpecifier = NULL;
1168 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1170 ALCuint num = 0;
1171 do {
1172 num++;
1173 } while((dev=dev->next) != NULL);
1174 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1177 DeinitEffectFactoryMap();
1180 static void alc_deinit_safe(void)
1182 alc_cleanup();
1184 FreeHrtfs();
1185 FreeALConfig();
1187 ThunkExit();
1188 almtx_destroy(&ListLock);
1189 altss_delete(LocalContext);
1191 if(LogFile != stderr)
1192 fclose(LogFile);
1193 LogFile = NULL;
1196 static void alc_deinit(void)
1198 int i;
1200 alc_cleanup();
1202 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1203 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1205 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1207 if(!BackendList[i].getFactory)
1208 BackendList[i].Deinit();
1209 else
1211 ALCbackendFactory *factory = BackendList[i].getFactory();
1212 V0(factory,deinit)();
1216 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1217 V0(factory,deinit)();
1220 alc_deinit_safe();
1224 /************************************************
1225 * Device enumeration
1226 ************************************************/
1227 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1229 DO_INITCONFIG();
1231 LockLists();
1232 al_string_clear(list);
1234 if(!backendinfo->getFactory)
1235 backendinfo->Probe(type);
1236 else
1238 ALCbackendFactory *factory = backendinfo->getFactory();
1239 V(factory,probe)(type);
1242 UnlockLists();
1244 static void ProbeAllDevicesList(void)
1245 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1246 static void ProbeCaptureDeviceList(void)
1247 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1249 static void AppendDevice(const ALCchar *name, al_string *devnames)
1251 size_t len = strlen(name);
1252 if(len > 0)
1253 al_string_append_range(devnames, name, name+len+1);
1255 void AppendAllDevicesList(const ALCchar *name)
1256 { AppendDevice(name, &alcAllDevicesList); }
1257 void AppendCaptureDeviceList(const ALCchar *name)
1258 { AppendDevice(name, &alcCaptureDeviceList); }
1261 /************************************************
1262 * Device format information
1263 ************************************************/
1264 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1266 switch(type)
1268 case DevFmtByte: return "Signed Byte";
1269 case DevFmtUByte: return "Unsigned Byte";
1270 case DevFmtShort: return "Signed Short";
1271 case DevFmtUShort: return "Unsigned Short";
1272 case DevFmtInt: return "Signed Int";
1273 case DevFmtUInt: return "Unsigned Int";
1274 case DevFmtFloat: return "Float";
1276 return "(unknown type)";
1278 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1280 switch(chans)
1282 case DevFmtMono: return "Mono";
1283 case DevFmtStereo: return "Stereo";
1284 case DevFmtQuad: return "Quadraphonic";
1285 case DevFmtX51: return "5.1 Surround";
1286 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1287 case DevFmtX61: return "6.1 Surround";
1288 case DevFmtX71: return "7.1 Surround";
1289 case DevFmtBFormat3D: return "B-Format 3D";
1291 return "(unknown channels)";
1294 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1295 ALuint BytesFromDevFmt(enum DevFmtType type)
1297 switch(type)
1299 case DevFmtByte: return sizeof(ALbyte);
1300 case DevFmtUByte: return sizeof(ALubyte);
1301 case DevFmtShort: return sizeof(ALshort);
1302 case DevFmtUShort: return sizeof(ALushort);
1303 case DevFmtInt: return sizeof(ALint);
1304 case DevFmtUInt: return sizeof(ALuint);
1305 case DevFmtFloat: return sizeof(ALfloat);
1307 return 0;
1309 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1311 switch(chans)
1313 case DevFmtMono: return 1;
1314 case DevFmtStereo: return 2;
1315 case DevFmtQuad: return 4;
1316 case DevFmtX51: return 6;
1317 case DevFmtX51Rear: return 6;
1318 case DevFmtX61: return 7;
1319 case DevFmtX71: return 8;
1320 case DevFmtBFormat3D: return 4;
1322 return 0;
1325 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1326 enum DevFmtChannels *chans, enum DevFmtType *type)
1328 static const struct {
1329 ALenum format;
1330 enum DevFmtChannels channels;
1331 enum DevFmtType type;
1332 } list[] = {
1333 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1334 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1335 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1337 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1338 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1339 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1341 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1342 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1343 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1345 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1346 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1347 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1349 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1350 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1351 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1353 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1354 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1355 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1357 ALuint i;
1359 for(i = 0;i < COUNTOF(list);i++)
1361 if(list[i].format == format)
1363 *chans = list[i].channels;
1364 *type = list[i].type;
1365 return AL_TRUE;
1369 return AL_FALSE;
1372 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1374 switch(type)
1376 case ALC_BYTE_SOFT:
1377 case ALC_UNSIGNED_BYTE_SOFT:
1378 case ALC_SHORT_SOFT:
1379 case ALC_UNSIGNED_SHORT_SOFT:
1380 case ALC_INT_SOFT:
1381 case ALC_UNSIGNED_INT_SOFT:
1382 case ALC_FLOAT_SOFT:
1383 return ALC_TRUE;
1385 return ALC_FALSE;
1388 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1390 switch(channels)
1392 case ALC_MONO_SOFT:
1393 case ALC_STEREO_SOFT:
1394 case ALC_QUAD_SOFT:
1395 case ALC_5POINT1_SOFT:
1396 case ALC_6POINT1_SOFT:
1397 case ALC_7POINT1_SOFT:
1398 return ALC_TRUE;
1400 return ALC_FALSE;
1404 /************************************************
1405 * Miscellaneous ALC helpers
1406 ************************************************/
1407 enum HrtfRequestMode {
1408 Hrtf_Default = 0,
1409 Hrtf_Enable = 1,
1410 Hrtf_Disable = 2,
1413 extern inline void LockContext(ALCcontext *context);
1414 extern inline void UnlockContext(ALCcontext *context);
1416 void ALCdevice_Lock(ALCdevice *device)
1418 V0(device->Backend,lock)();
1421 void ALCdevice_Unlock(ALCdevice *device)
1423 V0(device->Backend,unlock)();
1427 /* SetDefaultWFXChannelOrder
1429 * Sets the default channel order used by WaveFormatEx.
1431 void SetDefaultWFXChannelOrder(ALCdevice *device)
1433 ALuint i;
1435 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1436 device->ChannelName[i] = InvalidChannel;
1438 switch(device->FmtChans)
1440 case DevFmtMono:
1441 device->ChannelName[0] = FrontCenter;
1442 break;
1443 case DevFmtStereo:
1444 device->ChannelName[0] = FrontLeft;
1445 device->ChannelName[1] = FrontRight;
1446 break;
1447 case DevFmtQuad:
1448 device->ChannelName[0] = FrontLeft;
1449 device->ChannelName[1] = FrontRight;
1450 device->ChannelName[2] = BackLeft;
1451 device->ChannelName[3] = BackRight;
1452 break;
1453 case DevFmtX51:
1454 device->ChannelName[0] = FrontLeft;
1455 device->ChannelName[1] = FrontRight;
1456 device->ChannelName[2] = FrontCenter;
1457 device->ChannelName[3] = LFE;
1458 device->ChannelName[4] = SideLeft;
1459 device->ChannelName[5] = SideRight;
1460 break;
1461 case DevFmtX51Rear:
1462 device->ChannelName[0] = FrontLeft;
1463 device->ChannelName[1] = FrontRight;
1464 device->ChannelName[2] = FrontCenter;
1465 device->ChannelName[3] = LFE;
1466 device->ChannelName[4] = BackLeft;
1467 device->ChannelName[5] = BackRight;
1468 break;
1469 case DevFmtX61:
1470 device->ChannelName[0] = FrontLeft;
1471 device->ChannelName[1] = FrontRight;
1472 device->ChannelName[2] = FrontCenter;
1473 device->ChannelName[3] = LFE;
1474 device->ChannelName[4] = BackCenter;
1475 device->ChannelName[5] = SideLeft;
1476 device->ChannelName[6] = SideRight;
1477 break;
1478 case DevFmtX71:
1479 device->ChannelName[0] = FrontLeft;
1480 device->ChannelName[1] = FrontRight;
1481 device->ChannelName[2] = FrontCenter;
1482 device->ChannelName[3] = LFE;
1483 device->ChannelName[4] = BackLeft;
1484 device->ChannelName[5] = BackRight;
1485 device->ChannelName[6] = SideLeft;
1486 device->ChannelName[7] = SideRight;
1487 break;
1488 case DevFmtBFormat3D:
1489 device->ChannelName[0] = BFormatW;
1490 device->ChannelName[1] = BFormatX;
1491 device->ChannelName[2] = BFormatY;
1492 device->ChannelName[3] = BFormatZ;
1493 break;
1497 /* SetDefaultChannelOrder
1499 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1501 void SetDefaultChannelOrder(ALCdevice *device)
1503 ALuint i;
1505 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1506 device->ChannelName[i] = InvalidChannel;
1508 switch(device->FmtChans)
1510 case DevFmtX51Rear:
1511 device->ChannelName[0] = FrontLeft;
1512 device->ChannelName[1] = FrontRight;
1513 device->ChannelName[2] = BackLeft;
1514 device->ChannelName[3] = BackRight;
1515 device->ChannelName[4] = FrontCenter;
1516 device->ChannelName[5] = LFE;
1517 return;
1518 case DevFmtX71:
1519 device->ChannelName[0] = FrontLeft;
1520 device->ChannelName[1] = FrontRight;
1521 device->ChannelName[2] = BackLeft;
1522 device->ChannelName[3] = BackRight;
1523 device->ChannelName[4] = FrontCenter;
1524 device->ChannelName[5] = LFE;
1525 device->ChannelName[6] = SideLeft;
1526 device->ChannelName[7] = SideRight;
1527 return;
1529 /* Same as WFX order */
1530 case DevFmtMono:
1531 case DevFmtStereo:
1532 case DevFmtQuad:
1533 case DevFmtX51:
1534 case DevFmtX61:
1535 case DevFmtBFormat3D:
1536 SetDefaultWFXChannelOrder(device);
1537 break;
1541 extern inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan);
1544 /* ALCcontext_DeferUpdates
1546 * Defers/suspends updates for the given context's listener and sources. This
1547 * does *NOT* stop mixing, but rather prevents certain property changes from
1548 * taking effect.
1550 void ALCcontext_DeferUpdates(ALCcontext *context)
1552 ALCdevice *device = context->Device;
1553 FPUCtl oldMode;
1555 SetMixerFPUMode(&oldMode);
1557 V0(device->Backend,lock)();
1558 if(!context->DeferUpdates)
1560 context->DeferUpdates = AL_TRUE;
1562 /* Make sure all pending updates are performed */
1563 UpdateContextSources(context);
1564 #define UPDATE_SLOT(iter) do { \
1565 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1566 V((*iter)->EffectState,update)(device, *iter); \
1567 } while(0)
1568 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1569 #undef UPDATE_SLOT
1571 V0(device->Backend,unlock)();
1573 RestoreFPUMode(&oldMode);
1576 /* ALCcontext_ProcessUpdates
1578 * Resumes update processing after being deferred.
1580 void ALCcontext_ProcessUpdates(ALCcontext *context)
1582 ALCdevice *device = context->Device;
1584 V0(device->Backend,lock)();
1585 if(context->DeferUpdates)
1587 ALsizei pos;
1589 context->DeferUpdates = AL_FALSE;
1591 LockUIntMapRead(&context->SourceMap);
1592 for(pos = 0;pos < context->SourceMap.size;pos++)
1594 ALsource *Source = context->SourceMap.array[pos].value;
1595 ALenum new_state;
1597 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1598 Source->Offset >= 0.0)
1600 WriteLock(&Source->queue_lock);
1601 ApplyOffset(Source);
1602 WriteUnlock(&Source->queue_lock);
1605 new_state = Source->new_state;
1606 Source->new_state = AL_NONE;
1607 if(new_state)
1608 SetSourceState(Source, context, new_state);
1610 UnlockUIntMapRead(&context->SourceMap);
1612 V0(device->Backend,unlock)();
1616 /* alcSetError
1618 * Stores the latest ALC device error
1620 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1622 if(TrapALCError)
1624 #ifdef _WIN32
1625 /* DebugBreak() will cause an exception if there is no debugger */
1626 if(IsDebuggerPresent())
1627 DebugBreak();
1628 #elif defined(SIGTRAP)
1629 raise(SIGTRAP);
1630 #endif
1633 if(device)
1634 ATOMIC_STORE(&device->LastError, errorCode);
1635 else
1636 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1640 /* UpdateClockBase
1642 * Updates the device's base clock time with however many samples have been
1643 * done. This is used so frequency changes on the device don't cause the time
1644 * to jump forward or back.
1646 static inline void UpdateClockBase(ALCdevice *device)
1648 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1649 device->SamplesDone = 0;
1652 /* UpdateDeviceParams
1654 * Updates device parameters according to the attribute list (caller is
1655 * responsible for holding the list lock).
1657 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1659 ALCcontext *context;
1660 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1661 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1662 enum DevFmtChannels oldChans;
1663 enum DevFmtType oldType;
1664 ALCuint oldFreq;
1665 FPUCtl oldMode;
1666 ALCsizei hrtf_id = -1;
1667 size_t size;
1669 // Check for attributes
1670 if(device->Type == Loopback)
1672 enum {
1673 GotFreq = 1<<0,
1674 GotChans = 1<<1,
1675 GotType = 1<<2,
1676 GotAll = GotFreq|GotChans|GotType
1678 ALCuint freq, numMono, numStereo, numSends;
1679 enum DevFmtChannels schans;
1680 enum DevFmtType stype;
1681 ALCuint attrIdx = 0;
1682 ALCint gotFmt = 0;
1684 if(!attrList)
1686 WARN("Missing attributes for loopback device\n");
1687 return ALC_INVALID_VALUE;
1690 numMono = device->NumMonoSources;
1691 numStereo = device->NumStereoSources;
1692 numSends = device->NumAuxSends;
1693 schans = device->FmtChans;
1694 stype = device->FmtType;
1695 freq = device->Frequency;
1697 while(attrList[attrIdx])
1699 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1701 ALCint val = attrList[attrIdx + 1];
1702 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1703 return ALC_INVALID_VALUE;
1704 schans = val;
1705 gotFmt |= GotChans;
1708 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1710 ALCint val = attrList[attrIdx + 1];
1711 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1712 return ALC_INVALID_VALUE;
1713 stype = val;
1714 gotFmt |= GotType;
1717 if(attrList[attrIdx] == ALC_FREQUENCY)
1719 freq = attrList[attrIdx + 1];
1720 if(freq < MIN_OUTPUT_RATE)
1721 return ALC_INVALID_VALUE;
1722 gotFmt |= GotFreq;
1725 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1727 numStereo = attrList[attrIdx + 1];
1728 if(numStereo > device->MaxNoOfSources)
1729 numStereo = device->MaxNoOfSources;
1731 numMono = device->MaxNoOfSources - numStereo;
1734 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1735 numSends = attrList[attrIdx + 1];
1737 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1739 if(attrList[attrIdx + 1] == ALC_FALSE)
1740 hrtf_appreq = Hrtf_Disable;
1741 else if(attrList[attrIdx + 1] == ALC_TRUE)
1742 hrtf_appreq = Hrtf_Enable;
1743 else
1744 hrtf_appreq = Hrtf_Default;
1747 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1748 hrtf_id = attrList[attrIdx + 1];
1750 attrIdx += 2;
1753 if(gotFmt != GotAll)
1755 WARN("Missing format for loopback device\n");
1756 return ALC_INVALID_VALUE;
1759 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1760 numSends = minu(MAX_SENDS, numSends);
1762 if((device->Flags&DEVICE_RUNNING))
1763 V0(device->Backend,stop)();
1764 device->Flags &= ~DEVICE_RUNNING;
1766 UpdateClockBase(device);
1768 device->Frequency = freq;
1769 device->FmtChans = schans;
1770 device->FmtType = stype;
1771 device->NumMonoSources = numMono;
1772 device->NumStereoSources = numStereo;
1773 device->NumAuxSends = numSends;
1775 else if(attrList && attrList[0])
1777 ALCuint freq, numMono, numStereo, numSends;
1778 ALCuint attrIdx = 0;
1780 /* If a context is already running on the device, stop playback so the
1781 * device attributes can be updated. */
1782 if((device->Flags&DEVICE_RUNNING))
1783 V0(device->Backend,stop)();
1784 device->Flags &= ~DEVICE_RUNNING;
1786 freq = device->Frequency;
1787 numMono = device->NumMonoSources;
1788 numStereo = device->NumStereoSources;
1789 numSends = device->NumAuxSends;
1791 while(attrList[attrIdx])
1793 if(attrList[attrIdx] == ALC_FREQUENCY)
1795 freq = attrList[attrIdx + 1];
1796 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1799 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1801 numStereo = attrList[attrIdx + 1];
1802 if(numStereo > device->MaxNoOfSources)
1803 numStereo = device->MaxNoOfSources;
1805 numMono = device->MaxNoOfSources - numStereo;
1808 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1809 numSends = attrList[attrIdx + 1];
1811 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1813 if(attrList[attrIdx + 1] == ALC_FALSE)
1814 hrtf_appreq = Hrtf_Disable;
1815 else if(attrList[attrIdx + 1] == ALC_TRUE)
1816 hrtf_appreq = Hrtf_Enable;
1817 else
1818 hrtf_appreq = Hrtf_Default;
1821 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1822 hrtf_id = attrList[attrIdx + 1];
1824 attrIdx += 2;
1827 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1828 freq = maxu(freq, MIN_OUTPUT_RATE);
1830 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1831 numSends = minu(MAX_SENDS, numSends);
1833 UpdateClockBase(device);
1835 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1836 device->Frequency;
1837 /* SSE and Neon do best with the update size being a multiple of 4 */
1838 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1839 device->UpdateSize = (device->UpdateSize+3)&~3;
1841 device->Frequency = freq;
1842 device->NumMonoSources = numMono;
1843 device->NumStereoSources = numStereo;
1844 device->NumAuxSends = numSends;
1847 if((device->Flags&DEVICE_RUNNING))
1848 return ALC_NO_ERROR;
1850 al_free(device->Uhj_Encoder);
1851 device->Uhj_Encoder = NULL;
1853 al_free(device->Bs2b);
1854 device->Bs2b = NULL;
1856 al_free(device->DryBuffer);
1857 device->DryBuffer = NULL;
1859 UpdateClockBase(device);
1861 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1862 if(device->Type != Loopback)
1864 const char *hrtf;
1865 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1867 if(strcasecmp(hrtf, "true") == 0)
1868 hrtf_userreq = Hrtf_Enable;
1869 else if(strcasecmp(hrtf, "false") == 0)
1870 hrtf_userreq = Hrtf_Disable;
1871 else if(strcasecmp(hrtf, "auto") != 0)
1872 ERR("Unexpected hrtf value: %s\n", hrtf);
1875 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1877 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1879 VECTOR_DEINIT(device->Hrtf_List);
1880 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1882 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1884 device->FmtChans = DevFmtStereo;
1885 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1886 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1887 else
1888 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1889 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1891 else
1893 hrtf_userreq = hrtf_appreq = Hrtf_Default;
1894 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1898 else if(hrtf_appreq == Hrtf_Enable)
1900 size_t i;
1901 /* Loopback device. We don't need to match to a specific HRTF entry
1902 * here. If the requested ID matches, we'll pick that later, if not,
1903 * we'll try to auto-select one anyway. */
1904 if(device->FmtChans != DevFmtStereo)
1905 i = VECTOR_SIZE(device->Hrtf_List);
1906 else
1908 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1910 VECTOR_DEINIT(device->Hrtf_List);
1911 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1913 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1915 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1916 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1917 break;
1920 if(i == VECTOR_SIZE(device->Hrtf_List))
1922 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1923 DevFmtChannelsString(device->FmtChans), device->Frequency);
1924 hrtf_appreq = Hrtf_Default;
1925 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1929 oldFreq = device->Frequency;
1930 oldChans = device->FmtChans;
1931 oldType = device->FmtType;
1933 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1934 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1935 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1936 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1937 device->UpdateSize, device->NumUpdates
1940 if(V0(device->Backend,reset)() == ALC_FALSE)
1941 return ALC_INVALID_DEVICE;
1943 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1945 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1946 DevFmtChannelsString(device->FmtChans));
1947 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1949 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1951 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1952 DevFmtTypeString(device->FmtType));
1953 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1955 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1957 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1958 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1961 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1962 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1963 device->Frequency, device->UpdateSize, device->NumUpdates
1966 if((device->UpdateSize&3) != 0)
1968 if((CPUCapFlags&CPU_CAP_SSE))
1969 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1970 if((CPUCapFlags&CPU_CAP_NEON))
1971 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1974 device->Hrtf = NULL;
1975 device->Hrtf_Mode = DisabledHrtf;
1976 al_string_clear(&device->Hrtf_Name);
1977 if(device->FmtChans != DevFmtStereo)
1979 if(hrtf_appreq == Hrtf_Enable)
1980 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1982 else
1984 bool headphones = device->IsHeadphones;
1985 enum HrtfMode hrtf_mode = FullHrtf;
1986 ALCenum hrtf_status = device->Hrtf_Status;
1987 const char *mode;
1988 int bs2blevel;
1989 int usehrtf;
1991 if(device->Type != Loopback)
1993 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
1995 if(strcasecmp(mode, "headphones") == 0)
1996 headphones = true;
1997 else if(strcasecmp(mode, "speakers") == 0)
1998 headphones = false;
1999 else if(strcasecmp(mode, "auto") != 0)
2000 ERR("Unexpected stereo-mode: %s\n", mode);
2003 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
2005 if(strcasecmp(mode, "full") == 0)
2006 hrtf_mode = FullHrtf;
2007 else if(strcasecmp(mode, "basic") == 0)
2008 hrtf_mode = BasicHrtf;
2009 else
2010 ERR("Unexpected hrtf-mode: %s\n", mode);
2015 if(hrtf_userreq == Hrtf_Default)
2017 usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
2018 (hrtf_appreq == Hrtf_Enable);
2019 if(headphones && hrtf_appreq != Hrtf_Disable)
2020 hrtf_status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
2021 else if(usehrtf)
2022 hrtf_status = ALC_HRTF_ENABLED_SOFT;
2024 else
2026 usehrtf = (hrtf_userreq == Hrtf_Enable);
2027 if(!usehrtf)
2028 hrtf_status = ALC_HRTF_DENIED_SOFT;
2029 else
2030 hrtf_status = ALC_HRTF_REQUIRED_SOFT;
2033 if(!usehrtf)
2034 device->Hrtf_Status = hrtf_status;
2035 else
2037 size_t i;
2039 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2040 if(VECTOR_SIZE(device->Hrtf_List) == 0)
2042 VECTOR_DEINIT(device->Hrtf_List);
2043 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2046 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
2048 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, hrtf_id);
2049 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2051 device->Hrtf = entry->hrtf;
2052 al_string_copy(&device->Hrtf_Name, entry->name);
2055 if(!device->Hrtf)
2057 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
2059 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
2060 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2062 device->Hrtf = entry->hrtf;
2063 al_string_copy(&device->Hrtf_Name, entry->name);
2064 break;
2069 if(device->Hrtf)
2071 device->Hrtf_Mode = hrtf_mode;
2072 device->Hrtf_Status = hrtf_status;
2073 TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
2075 else
2077 TRACE("HRTF disabled\n");
2079 bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
2080 (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
2081 if(device->Type != Loopback)
2082 ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
2083 if(bs2blevel > 0 && bs2blevel <= 6)
2085 device->Bs2b = al_calloc(16, sizeof(*device->Bs2b));
2086 bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
2087 TRACE("BS2B enabled\n");
2089 else
2091 TRACE("BS2B disabled\n");
2094 device->Uhj_Encoder = al_calloc(16, sizeof(Uhj2Encoder));
2098 aluInitPanning(device);
2100 /* With HRTF, allocate two extra channels for the post-filter output. */
2101 size = device->NumChannels * sizeof(device->DryBuffer[0]);
2102 if(device->Hrtf || device->Uhj_Encoder)
2103 size += 2 * sizeof(device->DryBuffer[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;
2159 if(source)
2161 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2162 voice->Update(voice, source, context);
2166 context = context->next;
2168 if(device->DefaultSlot)
2170 ALeffectslot *slot = device->DefaultSlot;
2172 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2174 V0(device->Backend,unlock)();
2175 RestoreFPUMode(&oldMode);
2176 return ALC_INVALID_DEVICE;
2178 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2179 V(slot->EffectState,update)(device, slot);
2181 V0(device->Backend,unlock)();
2182 RestoreFPUMode(&oldMode);
2184 if(!(device->Flags&DEVICE_PAUSED))
2186 if(V0(device->Backend,start)() == ALC_FALSE)
2187 return ALC_INVALID_DEVICE;
2188 device->Flags |= DEVICE_RUNNING;
2191 return ALC_NO_ERROR;
2194 /* FreeDevice
2196 * Frees the device structure, and destroys any objects the app failed to
2197 * delete. Called once there's no more references on the device.
2199 static ALCvoid FreeDevice(ALCdevice *device)
2201 TRACE("%p\n", device);
2203 V0(device->Backend,close)();
2204 DELETE_OBJ(device->Backend);
2205 device->Backend = NULL;
2207 if(device->DefaultSlot)
2209 ALeffectState *state = device->DefaultSlot->EffectState;
2210 device->DefaultSlot = NULL;
2211 DELETE_OBJ(state);
2214 if(device->BufferMap.size > 0)
2216 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2217 ReleaseALBuffers(device);
2219 ResetUIntMap(&device->BufferMap);
2221 if(device->EffectMap.size > 0)
2223 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2224 ReleaseALEffects(device);
2226 ResetUIntMap(&device->EffectMap);
2228 if(device->FilterMap.size > 0)
2230 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2231 ReleaseALFilters(device);
2233 ResetUIntMap(&device->FilterMap);
2235 AL_STRING_DEINIT(device->Hrtf_Name);
2236 FreeHrtfList(&device->Hrtf_List);
2238 al_free(device->Bs2b);
2239 device->Bs2b = NULL;
2241 al_free(device->Uhj_Encoder);
2242 device->Uhj_Encoder = NULL;
2244 AL_STRING_DEINIT(device->DeviceName);
2246 al_free(device->DryBuffer);
2247 device->DryBuffer = NULL;
2249 al_free(device);
2253 void ALCdevice_IncRef(ALCdevice *device)
2255 uint ref;
2256 ref = IncrementRef(&device->ref);
2257 TRACEREF("%p increasing refcount to %u\n", device, ref);
2260 void ALCdevice_DecRef(ALCdevice *device)
2262 uint ref;
2263 ref = DecrementRef(&device->ref);
2264 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2265 if(ref == 0) FreeDevice(device);
2268 /* VerifyDevice
2270 * Checks if the device handle is valid, and increments its ref count if so.
2272 static ALCboolean VerifyDevice(ALCdevice **device)
2274 ALCdevice *tmpDevice;
2276 LockLists();
2277 tmpDevice = ATOMIC_LOAD(&DeviceList);
2278 while(tmpDevice)
2280 if(tmpDevice == *device)
2282 ALCdevice_IncRef(tmpDevice);
2283 UnlockLists();
2284 return ALC_TRUE;
2286 tmpDevice = tmpDevice->next;
2288 UnlockLists();
2290 *device = NULL;
2291 return ALC_FALSE;
2295 /* InitContext
2297 * Initializes context fields
2299 static ALvoid InitContext(ALCcontext *Context)
2301 ALlistener *listener = Context->Listener;
2302 //Initialise listener
2303 listener->Gain = 1.0f;
2304 listener->MetersPerUnit = 1.0f;
2305 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2306 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2307 listener->Forward[0] = 0.0f;
2308 listener->Forward[1] = 0.0f;
2309 listener->Forward[2] = -1.0f;
2310 listener->Up[0] = 0.0f;
2311 listener->Up[1] = 1.0f;
2312 listener->Up[2] = 0.0f;
2313 aluMatrixdSet(&listener->Params.Matrix,
2314 1.0, 0.0, 0.0, 0.0,
2315 0.0, 1.0, 0.0, 0.0,
2316 0.0, 0.0, 1.0, 0.0,
2317 0.0, 0.0, 0.0, 1.0
2319 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2321 //Validate Context
2322 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2323 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2324 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2325 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2327 //Set globals
2328 Context->DistanceModel = DefaultDistanceModel;
2329 Context->SourceDistanceModel = AL_FALSE;
2330 Context->DopplerFactor = 1.0f;
2331 Context->DopplerVelocity = 1.0f;
2332 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2333 Context->DeferUpdates = AL_FALSE;
2335 Context->ExtensionList = alExtList;
2339 /* FreeContext
2341 * Cleans up the context, and destroys any remaining objects the app failed to
2342 * delete. Called once there's no more references on the context.
2344 static void FreeContext(ALCcontext *context)
2346 TRACE("%p\n", context);
2348 if(context->SourceMap.size > 0)
2350 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2351 ReleaseALSources(context);
2353 ResetUIntMap(&context->SourceMap);
2355 if(context->EffectSlotMap.size > 0)
2357 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2358 ReleaseALAuxiliaryEffectSlots(context);
2360 ResetUIntMap(&context->EffectSlotMap);
2362 al_free(context->Voices);
2363 context->Voices = NULL;
2364 context->VoiceCount = 0;
2365 context->MaxVoices = 0;
2367 VECTOR_DEINIT(context->ActiveAuxSlots);
2369 ALCdevice_DecRef(context->Device);
2370 context->Device = NULL;
2372 //Invalidate context
2373 memset(context, 0, sizeof(ALCcontext));
2374 al_free(context);
2377 /* ReleaseContext
2379 * Removes the context reference from the given device and removes it from
2380 * being current on the running thread or globally.
2382 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2384 ALCcontext *nextctx;
2385 ALCcontext *origctx;
2387 if(altss_get(LocalContext) == context)
2389 WARN("%p released while current on thread\n", context);
2390 altss_set(LocalContext, NULL);
2391 ALCcontext_DecRef(context);
2394 origctx = context;
2395 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2396 ALCcontext_DecRef(context);
2398 ALCdevice_Lock(device);
2399 origctx = context;
2400 nextctx = context->next;
2401 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2403 ALCcontext *list;
2404 do {
2405 list = origctx;
2406 origctx = context;
2407 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2409 ALCdevice_Unlock(device);
2411 ALCcontext_DecRef(context);
2414 void ALCcontext_IncRef(ALCcontext *context)
2416 uint ref;
2417 ref = IncrementRef(&context->ref);
2418 TRACEREF("%p increasing refcount to %u\n", context, ref);
2421 void ALCcontext_DecRef(ALCcontext *context)
2423 uint ref;
2424 ref = DecrementRef(&context->ref);
2425 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2426 if(ref == 0) FreeContext(context);
2429 static void ReleaseThreadCtx(void *ptr)
2431 WARN("%p current for thread being destroyed\n", ptr);
2432 ALCcontext_DecRef(ptr);
2435 /* VerifyContext
2437 * Checks that the given context is valid, and increments its reference count.
2439 static ALCboolean VerifyContext(ALCcontext **context)
2441 ALCdevice *dev;
2443 LockLists();
2444 dev = ATOMIC_LOAD(&DeviceList);
2445 while(dev)
2447 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2448 while(ctx)
2450 if(ctx == *context)
2452 ALCcontext_IncRef(ctx);
2453 UnlockLists();
2454 return ALC_TRUE;
2456 ctx = ctx->next;
2458 dev = dev->next;
2460 UnlockLists();
2462 *context = NULL;
2463 return ALC_FALSE;
2467 /* GetContextRef
2469 * Returns the currently active context for this thread, and adds a reference
2470 * without locking it.
2472 ALCcontext *GetContextRef(void)
2474 ALCcontext *context;
2476 context = altss_get(LocalContext);
2477 if(context)
2478 ALCcontext_IncRef(context);
2479 else
2481 LockLists();
2482 context = ATOMIC_LOAD(&GlobalContext);
2483 if(context)
2484 ALCcontext_IncRef(context);
2485 UnlockLists();
2488 return context;
2492 /************************************************
2493 * Standard ALC functions
2494 ************************************************/
2496 /* alcGetError
2498 * Return last ALC generated error code for the given device
2500 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2502 ALCenum errorCode;
2504 if(VerifyDevice(&device))
2506 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2507 ALCdevice_DecRef(device);
2509 else
2510 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2512 return errorCode;
2516 /* alcSuspendContext
2518 * Suspends updates for the given context
2520 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2522 if(!SuspendDefers)
2523 return;
2525 if(!VerifyContext(&context))
2526 alcSetError(NULL, ALC_INVALID_CONTEXT);
2527 else
2529 ALCcontext_DeferUpdates(context);
2530 ALCcontext_DecRef(context);
2534 /* alcProcessContext
2536 * Resumes processing updates for the given context
2538 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2540 if(!SuspendDefers)
2541 return;
2543 if(!VerifyContext(&context))
2544 alcSetError(NULL, ALC_INVALID_CONTEXT);
2545 else
2547 ALCcontext_ProcessUpdates(context);
2548 ALCcontext_DecRef(context);
2553 /* alcGetString
2555 * Returns information about the device, and error strings
2557 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2559 const ALCchar *value = NULL;
2561 switch(param)
2563 case ALC_NO_ERROR:
2564 value = alcNoError;
2565 break;
2567 case ALC_INVALID_ENUM:
2568 value = alcErrInvalidEnum;
2569 break;
2571 case ALC_INVALID_VALUE:
2572 value = alcErrInvalidValue;
2573 break;
2575 case ALC_INVALID_DEVICE:
2576 value = alcErrInvalidDevice;
2577 break;
2579 case ALC_INVALID_CONTEXT:
2580 value = alcErrInvalidContext;
2581 break;
2583 case ALC_OUT_OF_MEMORY:
2584 value = alcErrOutOfMemory;
2585 break;
2587 case ALC_DEVICE_SPECIFIER:
2588 value = alcDefaultName;
2589 break;
2591 case ALC_ALL_DEVICES_SPECIFIER:
2592 if(VerifyDevice(&Device))
2594 value = al_string_get_cstr(Device->DeviceName);
2595 ALCdevice_DecRef(Device);
2597 else
2599 ProbeAllDevicesList();
2600 value = al_string_get_cstr(alcAllDevicesList);
2602 break;
2604 case ALC_CAPTURE_DEVICE_SPECIFIER:
2605 if(VerifyDevice(&Device))
2607 value = al_string_get_cstr(Device->DeviceName);
2608 ALCdevice_DecRef(Device);
2610 else
2612 ProbeCaptureDeviceList();
2613 value = al_string_get_cstr(alcCaptureDeviceList);
2615 break;
2617 /* Default devices are always first in the list */
2618 case ALC_DEFAULT_DEVICE_SPECIFIER:
2619 value = alcDefaultName;
2620 break;
2622 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2623 if(al_string_empty(alcAllDevicesList))
2624 ProbeAllDevicesList();
2626 VerifyDevice(&Device);
2628 free(alcDefaultAllDevicesSpecifier);
2629 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2630 if(!alcDefaultAllDevicesSpecifier)
2631 alcSetError(Device, ALC_OUT_OF_MEMORY);
2633 value = alcDefaultAllDevicesSpecifier;
2634 if(Device) ALCdevice_DecRef(Device);
2635 break;
2637 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2638 if(al_string_empty(alcCaptureDeviceList))
2639 ProbeCaptureDeviceList();
2641 VerifyDevice(&Device);
2643 free(alcCaptureDefaultDeviceSpecifier);
2644 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2645 if(!alcCaptureDefaultDeviceSpecifier)
2646 alcSetError(Device, ALC_OUT_OF_MEMORY);
2648 value = alcCaptureDefaultDeviceSpecifier;
2649 if(Device) ALCdevice_DecRef(Device);
2650 break;
2652 case ALC_EXTENSIONS:
2653 if(!VerifyDevice(&Device))
2654 value = alcNoDeviceExtList;
2655 else
2657 value = alcExtensionList;
2658 ALCdevice_DecRef(Device);
2660 break;
2662 case ALC_HRTF_SPECIFIER_SOFT:
2663 if(!VerifyDevice(&Device))
2664 alcSetError(NULL, ALC_INVALID_DEVICE);
2665 else
2667 LockLists();
2668 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2669 UnlockLists();
2670 ALCdevice_DecRef(Device);
2672 break;
2674 default:
2675 VerifyDevice(&Device);
2676 alcSetError(Device, ALC_INVALID_ENUM);
2677 if(Device) ALCdevice_DecRef(Device);
2678 break;
2681 return value;
2685 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2687 ALCsizei i;
2689 if(size <= 0 || values == NULL)
2691 alcSetError(device, ALC_INVALID_VALUE);
2692 return 0;
2695 if(!device)
2697 switch(param)
2699 case ALC_MAJOR_VERSION:
2700 values[0] = alcMajorVersion;
2701 return 1;
2702 case ALC_MINOR_VERSION:
2703 values[0] = alcMinorVersion;
2704 return 1;
2706 case ALC_ATTRIBUTES_SIZE:
2707 case ALC_ALL_ATTRIBUTES:
2708 case ALC_FREQUENCY:
2709 case ALC_REFRESH:
2710 case ALC_SYNC:
2711 case ALC_MONO_SOURCES:
2712 case ALC_STEREO_SOURCES:
2713 case ALC_CAPTURE_SAMPLES:
2714 case ALC_FORMAT_CHANNELS_SOFT:
2715 case ALC_FORMAT_TYPE_SOFT:
2716 alcSetError(NULL, ALC_INVALID_DEVICE);
2717 return 0;
2719 default:
2720 alcSetError(NULL, ALC_INVALID_ENUM);
2721 return 0;
2723 return 0;
2726 if(device->Type == Capture)
2728 switch(param)
2730 case ALC_CAPTURE_SAMPLES:
2731 V0(device->Backend,lock)();
2732 values[0] = V0(device->Backend,availableSamples)();
2733 V0(device->Backend,unlock)();
2734 return 1;
2736 case ALC_CONNECTED:
2737 values[0] = device->Connected;
2738 return 1;
2740 default:
2741 alcSetError(device, ALC_INVALID_ENUM);
2742 return 0;
2744 return 0;
2747 /* render device */
2748 switch(param)
2750 case ALC_MAJOR_VERSION:
2751 values[0] = alcMajorVersion;
2752 return 1;
2754 case ALC_MINOR_VERSION:
2755 values[0] = alcMinorVersion;
2756 return 1;
2758 case ALC_EFX_MAJOR_VERSION:
2759 values[0] = alcEFXMajorVersion;
2760 return 1;
2762 case ALC_EFX_MINOR_VERSION:
2763 values[0] = alcEFXMinorVersion;
2764 return 1;
2766 case ALC_ATTRIBUTES_SIZE:
2767 values[0] = 17;
2768 return 1;
2770 case ALC_ALL_ATTRIBUTES:
2771 if(size < 17)
2773 alcSetError(device, ALC_INVALID_VALUE);
2774 return 0;
2777 i = 0;
2778 values[i++] = ALC_FREQUENCY;
2779 values[i++] = device->Frequency;
2781 if(device->Type != Loopback)
2783 values[i++] = ALC_REFRESH;
2784 values[i++] = device->Frequency / device->UpdateSize;
2786 values[i++] = ALC_SYNC;
2787 values[i++] = ALC_FALSE;
2789 else
2791 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2792 values[i++] = device->FmtChans;
2794 values[i++] = ALC_FORMAT_TYPE_SOFT;
2795 values[i++] = device->FmtType;
2798 values[i++] = ALC_MONO_SOURCES;
2799 values[i++] = device->NumMonoSources;
2801 values[i++] = ALC_STEREO_SOURCES;
2802 values[i++] = device->NumStereoSources;
2804 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2805 values[i++] = device->NumAuxSends;
2807 values[i++] = ALC_HRTF_SOFT;
2808 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2810 values[i++] = ALC_HRTF_STATUS_SOFT;
2811 values[i++] = device->Hrtf_Status;
2813 values[i++] = 0;
2814 return i;
2816 case ALC_FREQUENCY:
2817 values[0] = device->Frequency;
2818 return 1;
2820 case ALC_REFRESH:
2821 if(device->Type == Loopback)
2823 alcSetError(device, ALC_INVALID_DEVICE);
2824 return 0;
2826 values[0] = device->Frequency / device->UpdateSize;
2827 return 1;
2829 case ALC_SYNC:
2830 if(device->Type == Loopback)
2832 alcSetError(device, ALC_INVALID_DEVICE);
2833 return 0;
2835 values[0] = ALC_FALSE;
2836 return 1;
2838 case ALC_FORMAT_CHANNELS_SOFT:
2839 if(device->Type != Loopback)
2841 alcSetError(device, ALC_INVALID_DEVICE);
2842 return 0;
2844 values[0] = device->FmtChans;
2845 return 1;
2847 case ALC_FORMAT_TYPE_SOFT:
2848 if(device->Type != Loopback)
2850 alcSetError(device, ALC_INVALID_DEVICE);
2851 return 0;
2853 values[0] = device->FmtType;
2854 return 1;
2856 case ALC_MONO_SOURCES:
2857 values[0] = device->NumMonoSources;
2858 return 1;
2860 case ALC_STEREO_SOURCES:
2861 values[0] = device->NumStereoSources;
2862 return 1;
2864 case ALC_MAX_AUXILIARY_SENDS:
2865 values[0] = device->NumAuxSends;
2866 return 1;
2868 case ALC_CONNECTED:
2869 values[0] = device->Connected;
2870 return 1;
2872 case ALC_HRTF_SOFT:
2873 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2874 return 1;
2876 case ALC_HRTF_STATUS_SOFT:
2877 values[0] = device->Hrtf_Status;
2878 return 1;
2880 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2881 FreeHrtfList(&device->Hrtf_List);
2882 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2883 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2884 return 1;
2886 default:
2887 alcSetError(device, ALC_INVALID_ENUM);
2888 return 0;
2890 return 0;
2893 /* alcGetIntegerv
2895 * Returns information about the device and the version of OpenAL
2897 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2899 VerifyDevice(&device);
2900 if(size <= 0 || values == NULL)
2901 alcSetError(device, ALC_INVALID_VALUE);
2902 else
2903 GetIntegerv(device, param, size, values);
2904 if(device) ALCdevice_DecRef(device);
2907 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2909 ALCint *ivals;
2910 ALsizei i;
2912 VerifyDevice(&device);
2913 if(size <= 0 || values == NULL)
2914 alcSetError(device, ALC_INVALID_VALUE);
2915 else if(!device || device->Type == Capture)
2917 ivals = malloc(size * sizeof(ALCint));
2918 size = GetIntegerv(device, pname, size, ivals);
2919 for(i = 0;i < size;i++)
2920 values[i] = ivals[i];
2921 free(ivals);
2923 else /* render device */
2925 switch(pname)
2927 case ALC_ATTRIBUTES_SIZE:
2928 *values = 19;
2929 break;
2931 case ALC_ALL_ATTRIBUTES:
2932 if(size < 19)
2933 alcSetError(device, ALC_INVALID_VALUE);
2934 else
2936 int i = 0;
2938 V0(device->Backend,lock)();
2939 values[i++] = ALC_FREQUENCY;
2940 values[i++] = device->Frequency;
2942 if(device->Type != Loopback)
2944 values[i++] = ALC_REFRESH;
2945 values[i++] = device->Frequency / device->UpdateSize;
2947 values[i++] = ALC_SYNC;
2948 values[i++] = ALC_FALSE;
2950 else
2952 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2953 values[i++] = device->FmtChans;
2955 values[i++] = ALC_FORMAT_TYPE_SOFT;
2956 values[i++] = device->FmtType;
2959 values[i++] = ALC_MONO_SOURCES;
2960 values[i++] = device->NumMonoSources;
2962 values[i++] = ALC_STEREO_SOURCES;
2963 values[i++] = device->NumStereoSources;
2965 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2966 values[i++] = device->NumAuxSends;
2968 values[i++] = ALC_HRTF_SOFT;
2969 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2971 values[i++] = ALC_HRTF_STATUS_SOFT;
2972 values[i++] = device->Hrtf_Status;
2974 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2975 values[i++] = device->ClockBase +
2976 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2978 values[i++] = 0;
2979 V0(device->Backend,unlock)();
2981 break;
2983 case ALC_DEVICE_CLOCK_SOFT:
2984 V0(device->Backend,lock)();
2985 *values = device->ClockBase +
2986 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2987 V0(device->Backend,unlock)();
2988 break;
2990 default:
2991 ivals = malloc(size * sizeof(ALCint));
2992 size = GetIntegerv(device, pname, size, ivals);
2993 for(i = 0;i < size;i++)
2994 values[i] = ivals[i];
2995 free(ivals);
2996 break;
2999 if(device)
3000 ALCdevice_DecRef(device);
3004 /* alcIsExtensionPresent
3006 * Determines if there is support for a particular extension
3008 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3010 ALCboolean bResult = ALC_FALSE;
3012 VerifyDevice(&device);
3014 if(!extName)
3015 alcSetError(device, ALC_INVALID_VALUE);
3016 else
3018 size_t len = strlen(extName);
3019 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3020 while(ptr && *ptr)
3022 if(strncasecmp(ptr, extName, len) == 0 &&
3023 (ptr[len] == '\0' || isspace(ptr[len])))
3025 bResult = ALC_TRUE;
3026 break;
3028 if((ptr=strchr(ptr, ' ')) != NULL)
3030 do {
3031 ++ptr;
3032 } while(isspace(*ptr));
3036 if(device)
3037 ALCdevice_DecRef(device);
3038 return bResult;
3042 /* alcGetProcAddress
3044 * Retrieves the function address for a particular extension function
3046 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3048 ALCvoid *ptr = NULL;
3050 if(!funcName)
3052 VerifyDevice(&device);
3053 alcSetError(device, ALC_INVALID_VALUE);
3054 if(device) ALCdevice_DecRef(device);
3056 else
3058 ALsizei i = 0;
3059 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3060 i++;
3061 ptr = alcFunctions[i].address;
3064 return ptr;
3068 /* alcGetEnumValue
3070 * Get the value for a particular ALC enumeration name
3072 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3074 ALCenum val = 0;
3076 if(!enumName)
3078 VerifyDevice(&device);
3079 alcSetError(device, ALC_INVALID_VALUE);
3080 if(device) ALCdevice_DecRef(device);
3082 else
3084 ALsizei i = 0;
3085 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3086 i++;
3087 val = enumeration[i].value;
3090 return val;
3094 /* alcCreateContext
3096 * Create and attach a context to the given device.
3098 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3100 ALCcontext *ALContext;
3101 ALCenum err;
3103 LockLists();
3104 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3106 UnlockLists();
3107 alcSetError(device, ALC_INVALID_DEVICE);
3108 if(device) ALCdevice_DecRef(device);
3109 return NULL;
3112 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3114 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3116 UnlockLists();
3117 alcSetError(device, err);
3118 if(err == ALC_INVALID_DEVICE)
3120 V0(device->Backend,lock)();
3121 aluHandleDisconnect(device);
3122 V0(device->Backend,unlock)();
3124 ALCdevice_DecRef(device);
3125 return NULL;
3128 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3129 if(ALContext)
3131 InitRef(&ALContext->ref, 1);
3132 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3134 VECTOR_INIT(ALContext->ActiveAuxSlots);
3136 ALContext->VoiceCount = 0;
3137 ALContext->MaxVoices = 256;
3138 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3140 if(!ALContext || !ALContext->Voices)
3142 if(!ATOMIC_LOAD(&device->ContextList))
3144 V0(device->Backend,stop)();
3145 device->Flags &= ~DEVICE_RUNNING;
3147 UnlockLists();
3149 if(ALContext)
3151 al_free(ALContext->Voices);
3152 ALContext->Voices = NULL;
3154 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3156 al_free(ALContext);
3157 ALContext = NULL;
3160 alcSetError(device, ALC_OUT_OF_MEMORY);
3161 ALCdevice_DecRef(device);
3162 return NULL;
3165 ALContext->Device = device;
3166 ALCdevice_IncRef(device);
3167 InitContext(ALContext);
3170 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3171 do {
3172 ALContext->next = head;
3173 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3175 UnlockLists();
3177 ALCdevice_DecRef(device);
3179 TRACE("Created context %p\n", ALContext);
3180 return ALContext;
3183 /* alcDestroyContext
3185 * Remove a context from its device
3187 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3189 ALCdevice *Device;
3191 LockLists();
3192 /* alcGetContextsDevice sets an error for invalid contexts */
3193 Device = alcGetContextsDevice(context);
3194 if(Device)
3196 ReleaseContext(context, Device);
3197 if(!ATOMIC_LOAD(&Device->ContextList))
3199 V0(Device->Backend,stop)();
3200 Device->Flags &= ~DEVICE_RUNNING;
3203 UnlockLists();
3207 /* alcGetCurrentContext
3209 * Returns the currently active context on the calling thread
3211 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3213 ALCcontext *Context = altss_get(LocalContext);
3214 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3215 return Context;
3218 /* alcGetThreadContext
3220 * Returns the currently active thread-local context
3222 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3224 return altss_get(LocalContext);
3228 /* alcMakeContextCurrent
3230 * Makes the given context the active process-wide context, and removes the
3231 * thread-local context for the calling thread.
3233 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3235 /* context must be valid or NULL */
3236 if(context && !VerifyContext(&context))
3238 alcSetError(NULL, ALC_INVALID_CONTEXT);
3239 return ALC_FALSE;
3241 /* context's reference count is already incremented */
3242 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3243 if(context) ALCcontext_DecRef(context);
3245 if((context=altss_get(LocalContext)) != NULL)
3247 altss_set(LocalContext, NULL);
3248 ALCcontext_DecRef(context);
3251 return ALC_TRUE;
3254 /* alcSetThreadContext
3256 * Makes the given context the active context for the current thread
3258 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3260 ALCcontext *old;
3262 /* context must be valid or NULL */
3263 if(context && !VerifyContext(&context))
3265 alcSetError(NULL, ALC_INVALID_CONTEXT);
3266 return ALC_FALSE;
3268 /* context's reference count is already incremented */
3269 old = altss_get(LocalContext);
3270 altss_set(LocalContext, context);
3271 if(old) ALCcontext_DecRef(old);
3273 return ALC_TRUE;
3277 /* alcGetContextsDevice
3279 * Returns the device that a particular context is attached to
3281 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3283 ALCdevice *Device;
3285 if(!VerifyContext(&Context))
3287 alcSetError(NULL, ALC_INVALID_CONTEXT);
3288 return NULL;
3290 Device = Context->Device;
3291 ALCcontext_DecRef(Context);
3293 return Device;
3297 /* alcOpenDevice
3299 * Opens the named device.
3301 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3303 const ALCchar *fmt;
3304 ALCdevice *device;
3305 ALCenum err;
3307 DO_INITCONFIG();
3309 if(!PlaybackBackend.name)
3311 alcSetError(NULL, ALC_INVALID_VALUE);
3312 return NULL;
3315 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3316 #ifdef _WIN32
3317 /* Some old Windows apps hardcode these expecting OpenAL to use a
3318 * specific audio API, even when they're not enumerated. Creative's
3319 * router effectively ignores them too.
3321 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3322 || strcasecmp(deviceName, "MMSYSTEM") == 0
3323 #endif
3325 deviceName = NULL;
3327 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3328 if(!device)
3330 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3331 return NULL;
3334 //Validate device
3335 InitRef(&device->ref, 1);
3336 device->Connected = ALC_TRUE;
3337 device->Type = Playback;
3338 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3340 device->Flags = 0;
3341 device->Bs2b = NULL;
3342 device->Uhj_Encoder = NULL;
3343 VECTOR_INIT(device->Hrtf_List);
3344 AL_STRING_INIT(device->Hrtf_Name);
3345 device->Hrtf_Mode = DisabledHrtf;
3346 AL_STRING_INIT(device->DeviceName);
3347 device->DryBuffer = NULL;
3349 ATOMIC_INIT(&device->ContextList, NULL);
3351 device->ClockBase = 0;
3352 device->SamplesDone = 0;
3354 device->MaxNoOfSources = 256;
3355 device->AuxiliaryEffectSlotMax = 4;
3356 device->NumAuxSends = MAX_SENDS;
3358 InitUIntMap(&device->BufferMap, ~0);
3359 InitUIntMap(&device->EffectMap, ~0);
3360 InitUIntMap(&device->FilterMap, ~0);
3362 //Set output format
3363 device->FmtChans = DevFmtChannelsDefault;
3364 device->FmtType = DevFmtTypeDefault;
3365 device->Frequency = DEFAULT_OUTPUT_RATE;
3366 device->IsHeadphones = AL_FALSE;
3367 device->NumUpdates = 4;
3368 device->UpdateSize = 1024;
3370 if(!PlaybackBackend.getFactory)
3371 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3372 ALCbackend_Playback);
3373 else
3375 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3376 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3378 if(!device->Backend)
3380 al_free(device);
3381 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3382 return NULL;
3386 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3388 static const struct {
3389 const char name[16];
3390 enum DevFmtChannels chans;
3391 } chanlist[] = {
3392 { "mono", DevFmtMono },
3393 { "stereo", DevFmtStereo },
3394 { "quad", DevFmtQuad },
3395 { "surround51", DevFmtX51 },
3396 { "surround61", DevFmtX61 },
3397 { "surround71", DevFmtX71 },
3398 { "surround51rear", DevFmtX51Rear },
3400 size_t i;
3402 for(i = 0;i < COUNTOF(chanlist);i++)
3404 if(strcasecmp(chanlist[i].name, fmt) == 0)
3406 device->FmtChans = chanlist[i].chans;
3407 device->Flags |= DEVICE_CHANNELS_REQUEST;
3408 break;
3411 if(i == COUNTOF(chanlist))
3412 ERR("Unsupported channels: %s\n", fmt);
3414 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3416 static const struct {
3417 const char name[16];
3418 enum DevFmtType type;
3419 } typelist[] = {
3420 { "int8", DevFmtByte },
3421 { "uint8", DevFmtUByte },
3422 { "int16", DevFmtShort },
3423 { "uint16", DevFmtUShort },
3424 { "int32", DevFmtInt },
3425 { "uint32", DevFmtUInt },
3426 { "float32", DevFmtFloat },
3428 size_t i;
3430 for(i = 0;i < COUNTOF(typelist);i++)
3432 if(strcasecmp(typelist[i].name, fmt) == 0)
3434 device->FmtType = typelist[i].type;
3435 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3436 break;
3439 if(i == COUNTOF(typelist))
3440 ERR("Unsupported sample-type: %s\n", fmt);
3443 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3445 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3446 if(device->Frequency < MIN_OUTPUT_RATE)
3447 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3448 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3451 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3452 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3454 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3455 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3456 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3457 device->UpdateSize = (device->UpdateSize+3)&~3;
3459 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3460 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3462 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3463 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3465 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3466 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3468 device->NumStereoSources = 1;
3469 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3471 // Find a playback device to open
3472 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3474 DELETE_OBJ(device->Backend);
3475 al_free(device);
3476 alcSetError(NULL, err);
3477 return NULL;
3480 if(DefaultEffect.type != AL_EFFECT_NULL)
3482 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3483 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3485 device->DefaultSlot = NULL;
3486 ERR("Failed to initialize the default effect slot\n");
3488 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3490 ALeffectState *state = device->DefaultSlot->EffectState;
3491 device->DefaultSlot = NULL;
3492 DELETE_OBJ(state);
3493 ERR("Failed to initialize the default effect\n");
3495 else
3496 aluInitEffectPanning(device->DefaultSlot);
3500 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3501 do {
3502 device->next = head;
3503 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3506 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3507 return device;
3510 /* alcCloseDevice
3512 * Closes the given device.
3514 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3516 ALCdevice *list, *origdev, *nextdev;
3517 ALCcontext *ctx;
3519 LockLists();
3520 list = ATOMIC_LOAD(&DeviceList);
3521 do {
3522 if(list == device)
3523 break;
3524 } while((list=list->next) != NULL);
3525 if(!list || list->Type == Capture)
3527 alcSetError(list, ALC_INVALID_DEVICE);
3528 UnlockLists();
3529 return ALC_FALSE;
3532 origdev = device;
3533 nextdev = device->next;
3534 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3536 do {
3537 list = origdev;
3538 origdev = device;
3539 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3541 UnlockLists();
3543 ctx = ATOMIC_LOAD(&device->ContextList);
3544 while(ctx != NULL)
3546 ALCcontext *next = ctx->next;
3547 WARN("Releasing context %p\n", ctx);
3548 ReleaseContext(ctx, device);
3549 ctx = next;
3551 if((device->Flags&DEVICE_RUNNING))
3552 V0(device->Backend,stop)();
3553 device->Flags &= ~DEVICE_RUNNING;
3555 ALCdevice_DecRef(device);
3557 return ALC_TRUE;
3561 /************************************************
3562 * ALC capture functions
3563 ************************************************/
3564 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3566 ALCdevice *device = NULL;
3567 ALCenum err;
3569 DO_INITCONFIG();
3571 if(!CaptureBackend.name)
3573 alcSetError(NULL, ALC_INVALID_VALUE);
3574 return NULL;
3577 if(samples <= 0)
3579 alcSetError(NULL, ALC_INVALID_VALUE);
3580 return NULL;
3583 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3584 deviceName = NULL;
3586 device = al_calloc(16, sizeof(ALCdevice));
3587 if(!device)
3589 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3590 return NULL;
3593 //Validate device
3594 InitRef(&device->ref, 1);
3595 device->Connected = ALC_TRUE;
3596 device->Type = Capture;
3598 VECTOR_INIT(device->Hrtf_List);
3599 AL_STRING_INIT(device->Hrtf_Name);
3601 AL_STRING_INIT(device->DeviceName);
3602 device->DryBuffer = NULL;
3604 InitUIntMap(&device->BufferMap, ~0);
3605 InitUIntMap(&device->EffectMap, ~0);
3606 InitUIntMap(&device->FilterMap, ~0);
3608 if(!CaptureBackend.getFactory)
3609 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3610 ALCbackend_Capture);
3611 else
3613 ALCbackendFactory *factory = CaptureBackend.getFactory();
3614 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3616 if(!device->Backend)
3618 al_free(device);
3619 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3620 return NULL;
3623 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3624 device->Frequency = frequency;
3626 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3627 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3629 al_free(device);
3630 alcSetError(NULL, ALC_INVALID_ENUM);
3631 return NULL;
3633 device->IsHeadphones = AL_FALSE;
3635 device->UpdateSize = samples;
3636 device->NumUpdates = 1;
3638 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3640 al_free(device);
3641 alcSetError(NULL, err);
3642 return NULL;
3646 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3647 do {
3648 device->next = head;
3649 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3652 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3653 return device;
3656 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3658 ALCdevice *list, *next, *nextdev;
3660 LockLists();
3661 list = ATOMIC_LOAD(&DeviceList);
3662 do {
3663 if(list == device)
3664 break;
3665 } while((list=list->next) != NULL);
3666 if(!list || list->Type != Capture)
3668 alcSetError(list, ALC_INVALID_DEVICE);
3669 UnlockLists();
3670 return ALC_FALSE;
3673 next = device;
3674 nextdev = device->next;
3675 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3677 do {
3678 list = next;
3679 next = device;
3680 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3682 UnlockLists();
3684 ALCdevice_DecRef(device);
3686 return ALC_TRUE;
3689 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3691 if(!VerifyDevice(&device) || device->Type != Capture)
3692 alcSetError(device, ALC_INVALID_DEVICE);
3693 else
3695 V0(device->Backend,lock)();
3696 if(!device->Connected)
3697 alcSetError(device, ALC_INVALID_DEVICE);
3698 else if(!(device->Flags&DEVICE_RUNNING))
3700 if(V0(device->Backend,start)())
3701 device->Flags |= DEVICE_RUNNING;
3702 else
3704 aluHandleDisconnect(device);
3705 alcSetError(device, ALC_INVALID_DEVICE);
3708 V0(device->Backend,unlock)();
3711 if(device) ALCdevice_DecRef(device);
3714 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3716 if(!VerifyDevice(&device) || device->Type != Capture)
3717 alcSetError(device, ALC_INVALID_DEVICE);
3718 else
3720 V0(device->Backend,lock)();
3721 if((device->Flags&DEVICE_RUNNING))
3722 V0(device->Backend,stop)();
3723 device->Flags &= ~DEVICE_RUNNING;
3724 V0(device->Backend,unlock)();
3727 if(device) ALCdevice_DecRef(device);
3730 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3732 if(!VerifyDevice(&device) || device->Type != Capture)
3733 alcSetError(device, ALC_INVALID_DEVICE);
3734 else
3736 ALCenum err = ALC_INVALID_VALUE;
3738 V0(device->Backend,lock)();
3739 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3740 err = V(device->Backend,captureSamples)(buffer, samples);
3741 V0(device->Backend,unlock)();
3743 if(err != ALC_NO_ERROR)
3744 alcSetError(device, err);
3746 if(device) ALCdevice_DecRef(device);
3750 /************************************************
3751 * ALC loopback functions
3752 ************************************************/
3754 /* alcLoopbackOpenDeviceSOFT
3756 * Open a loopback device, for manual rendering.
3758 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3760 ALCbackendFactory *factory;
3761 ALCdevice *device;
3763 DO_INITCONFIG();
3765 /* Make sure the device name, if specified, is us. */
3766 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3768 alcSetError(NULL, ALC_INVALID_VALUE);
3769 return NULL;
3772 device = al_calloc(16, sizeof(ALCdevice));
3773 if(!device)
3775 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3776 return NULL;
3779 //Validate device
3780 InitRef(&device->ref, 1);
3781 device->Connected = ALC_TRUE;
3782 device->Type = Loopback;
3783 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3785 device->Flags = 0;
3786 VECTOR_INIT(device->Hrtf_List);
3787 AL_STRING_INIT(device->Hrtf_Name);
3788 device->Bs2b = NULL;
3789 device->Uhj_Encoder = NULL;
3790 device->Hrtf_Mode = DisabledHrtf;
3791 AL_STRING_INIT(device->DeviceName);
3792 device->DryBuffer = NULL;
3794 ATOMIC_INIT(&device->ContextList, NULL);
3796 device->ClockBase = 0;
3797 device->SamplesDone = 0;
3799 device->MaxNoOfSources = 256;
3800 device->AuxiliaryEffectSlotMax = 4;
3801 device->NumAuxSends = MAX_SENDS;
3803 InitUIntMap(&device->BufferMap, ~0);
3804 InitUIntMap(&device->EffectMap, ~0);
3805 InitUIntMap(&device->FilterMap, ~0);
3807 factory = ALCloopbackFactory_getFactory();
3808 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3809 if(!device->Backend)
3811 al_free(device);
3812 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3813 return NULL;
3816 //Set output format
3817 device->NumUpdates = 0;
3818 device->UpdateSize = 0;
3820 device->Frequency = DEFAULT_OUTPUT_RATE;
3821 device->FmtChans = DevFmtChannelsDefault;
3822 device->FmtType = DevFmtTypeDefault;
3823 device->IsHeadphones = AL_FALSE;
3825 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3826 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3828 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3829 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3831 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3832 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3834 device->NumStereoSources = 1;
3835 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3837 // Open the "backend"
3838 V(device->Backend,open)("Loopback");
3841 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3842 do {
3843 device->next = head;
3844 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3847 TRACE("Created device %p\n", device);
3848 return device;
3851 /* alcIsRenderFormatSupportedSOFT
3853 * Determines if the loopback device supports the given format for rendering.
3855 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3857 ALCboolean ret = ALC_FALSE;
3859 if(!VerifyDevice(&device) || device->Type != Loopback)
3860 alcSetError(device, ALC_INVALID_DEVICE);
3861 else if(freq <= 0)
3862 alcSetError(device, ALC_INVALID_VALUE);
3863 else
3865 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3866 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3867 freq >= MIN_OUTPUT_RATE)
3868 ret = ALC_TRUE;
3870 if(device) ALCdevice_DecRef(device);
3872 return ret;
3875 /* alcRenderSamplesSOFT
3877 * Renders some samples into a buffer, using the format last set by the
3878 * attributes given to alcCreateContext.
3880 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3882 if(!VerifyDevice(&device) || device->Type != Loopback)
3883 alcSetError(device, ALC_INVALID_DEVICE);
3884 else if(samples < 0 || (samples > 0 && buffer == NULL))
3885 alcSetError(device, ALC_INVALID_VALUE);
3886 else
3887 aluMixData(device, buffer, samples);
3888 if(device) ALCdevice_DecRef(device);
3892 /************************************************
3893 * ALC DSP pause/resume functions
3894 ************************************************/
3896 /* alcDevicePauseSOFT
3898 * Pause the DSP to stop audio processing.
3900 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3902 if(!VerifyDevice(&device) || device->Type != Playback)
3903 alcSetError(device, ALC_INVALID_DEVICE);
3904 else
3906 LockLists();
3907 if((device->Flags&DEVICE_RUNNING))
3908 V0(device->Backend,stop)();
3909 device->Flags &= ~DEVICE_RUNNING;
3910 device->Flags |= DEVICE_PAUSED;
3911 UnlockLists();
3913 if(device) ALCdevice_DecRef(device);
3916 /* alcDeviceResumeSOFT
3918 * Resume the DSP to restart audio processing.
3920 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3922 if(!VerifyDevice(&device) || device->Type != Playback)
3923 alcSetError(device, ALC_INVALID_DEVICE);
3924 else
3926 LockLists();
3927 if((device->Flags&DEVICE_PAUSED))
3929 device->Flags &= ~DEVICE_PAUSED;
3930 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3932 if(V0(device->Backend,start)() != ALC_FALSE)
3933 device->Flags |= DEVICE_RUNNING;
3934 else
3936 alcSetError(device, ALC_INVALID_DEVICE);
3937 V0(device->Backend,lock)();
3938 aluHandleDisconnect(device);
3939 V0(device->Backend,unlock)();
3943 UnlockLists();
3945 if(device) ALCdevice_DecRef(device);
3949 /************************************************
3950 * ALC HRTF functions
3951 ************************************************/
3953 /* alcGetStringiSOFT
3955 * Gets a string parameter at the given index.
3957 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3959 const ALCchar *str = NULL;
3961 if(!VerifyDevice(&device) || device->Type == Capture)
3962 alcSetError(device, ALC_INVALID_DEVICE);
3963 else switch(paramName)
3965 case ALC_HRTF_SPECIFIER_SOFT:
3966 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
3967 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
3968 else
3969 alcSetError(device, ALC_INVALID_VALUE);
3970 break;
3972 default:
3973 alcSetError(device, ALC_INVALID_ENUM);
3974 break;
3976 if(device) ALCdevice_DecRef(device);
3978 return str;
3981 /* alcResetDeviceSOFT
3983 * Resets the given device output, using the specified attribute list.
3985 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
3987 ALCenum err;
3989 LockLists();
3990 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3992 UnlockLists();
3993 alcSetError(device, ALC_INVALID_DEVICE);
3994 if(device) ALCdevice_DecRef(device);
3995 return ALC_FALSE;
3998 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
4000 UnlockLists();
4001 alcSetError(device, err);
4002 if(err == ALC_INVALID_DEVICE)
4004 V0(device->Backend,lock)();
4005 aluHandleDisconnect(device);
4006 V0(device->Backend,unlock)();
4008 ALCdevice_DecRef(device);
4009 return ALC_FALSE;
4011 UnlockLists();
4012 ALCdevice_DecRef(device);
4014 return ALC_TRUE;