Calculate the output limiter gain using the RMS
[openal-soft.git] / Alc / ALc.c
blobfe8a0266c286ee93fc6e88694ebf10ed6f6203b3
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 "version.h"
25 #include <math.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <memory.h>
29 #include <ctype.h>
30 #include <signal.h>
32 #include "alMain.h"
33 #include "alSource.h"
34 #include "alListener.h"
35 #include "alThunk.h"
36 #include "alSource.h"
37 #include "alBuffer.h"
38 #include "alAuxEffectSlot.h"
39 #include "alError.h"
40 #include "bformatdec.h"
41 #include "alu.h"
43 #include "compat.h"
44 #include "threads.h"
45 #include "alstring.h"
46 #include "almalloc.h"
48 #include "backends/base.h"
51 /************************************************
52 * Backends
53 ************************************************/
54 struct BackendInfo {
55 const char *name;
56 ALCbackendFactory* (*getFactory)(void);
57 ALCboolean (*Init)(BackendFuncs*);
58 void (*Deinit)(void);
59 void (*Probe)(enum DevProbe);
60 BackendFuncs Funcs;
63 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
64 static struct BackendInfo BackendList[] = {
65 #ifdef HAVE_JACK
66 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
67 #endif
68 #ifdef HAVE_PULSEAUDIO
69 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
70 #endif
71 #ifdef HAVE_ALSA
72 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
73 #endif
74 #ifdef HAVE_COREAUDIO
75 { "core", ALCcoreAudioBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
76 #endif
77 #ifdef HAVE_OSS
78 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
79 #endif
80 #ifdef HAVE_SOLARIS
81 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
82 #endif
83 #ifdef HAVE_SNDIO
84 { "sndio", ALCsndioBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
85 #endif
86 #ifdef HAVE_QSA
87 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
88 #endif
89 #ifdef HAVE_MMDEVAPI
90 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
91 #endif
92 #ifdef HAVE_DSOUND
93 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
94 #endif
95 #ifdef HAVE_WINMM
96 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
97 #endif
98 #ifdef HAVE_PORTAUDIO
99 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
100 #endif
101 #ifdef HAVE_OPENSL
102 { "opensl", ALCopenslBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
103 #endif
105 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
106 #ifdef HAVE_WAVE
107 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
108 #endif
110 static ALsizei BackendListSize = COUNTOF(BackendList);
111 #undef EmptyFuncs
113 static struct BackendInfo PlaybackBackend;
114 static struct BackendInfo CaptureBackend;
117 /************************************************
118 * Functions, enums, and errors
119 ************************************************/
120 #define DECL(x) { #x, (ALCvoid*)(x) }
121 static const struct {
122 const ALCchar *funcName;
123 ALCvoid *address;
124 } alcFunctions[] = {
125 DECL(alcCreateContext),
126 DECL(alcMakeContextCurrent),
127 DECL(alcProcessContext),
128 DECL(alcSuspendContext),
129 DECL(alcDestroyContext),
130 DECL(alcGetCurrentContext),
131 DECL(alcGetContextsDevice),
132 DECL(alcOpenDevice),
133 DECL(alcCloseDevice),
134 DECL(alcGetError),
135 DECL(alcIsExtensionPresent),
136 DECL(alcGetProcAddress),
137 DECL(alcGetEnumValue),
138 DECL(alcGetString),
139 DECL(alcGetIntegerv),
140 DECL(alcCaptureOpenDevice),
141 DECL(alcCaptureCloseDevice),
142 DECL(alcCaptureStart),
143 DECL(alcCaptureStop),
144 DECL(alcCaptureSamples),
146 DECL(alcSetThreadContext),
147 DECL(alcGetThreadContext),
149 DECL(alcLoopbackOpenDeviceSOFT),
150 DECL(alcIsRenderFormatSupportedSOFT),
151 DECL(alcRenderSamplesSOFT),
153 DECL(alcIsAmbisonicFormatSupportedSOFT),
155 DECL(alcDevicePauseSOFT),
156 DECL(alcDeviceResumeSOFT),
158 DECL(alcGetStringiSOFT),
159 DECL(alcResetDeviceSOFT),
161 DECL(alcGetInteger64vSOFT),
163 DECL(alEnable),
164 DECL(alDisable),
165 DECL(alIsEnabled),
166 DECL(alGetString),
167 DECL(alGetBooleanv),
168 DECL(alGetIntegerv),
169 DECL(alGetFloatv),
170 DECL(alGetDoublev),
171 DECL(alGetBoolean),
172 DECL(alGetInteger),
173 DECL(alGetFloat),
174 DECL(alGetDouble),
175 DECL(alGetError),
176 DECL(alIsExtensionPresent),
177 DECL(alGetProcAddress),
178 DECL(alGetEnumValue),
179 DECL(alListenerf),
180 DECL(alListener3f),
181 DECL(alListenerfv),
182 DECL(alListeneri),
183 DECL(alListener3i),
184 DECL(alListeneriv),
185 DECL(alGetListenerf),
186 DECL(alGetListener3f),
187 DECL(alGetListenerfv),
188 DECL(alGetListeneri),
189 DECL(alGetListener3i),
190 DECL(alGetListeneriv),
191 DECL(alGenSources),
192 DECL(alDeleteSources),
193 DECL(alIsSource),
194 DECL(alSourcef),
195 DECL(alSource3f),
196 DECL(alSourcefv),
197 DECL(alSourcei),
198 DECL(alSource3i),
199 DECL(alSourceiv),
200 DECL(alGetSourcef),
201 DECL(alGetSource3f),
202 DECL(alGetSourcefv),
203 DECL(alGetSourcei),
204 DECL(alGetSource3i),
205 DECL(alGetSourceiv),
206 DECL(alSourcePlayv),
207 DECL(alSourceStopv),
208 DECL(alSourceRewindv),
209 DECL(alSourcePausev),
210 DECL(alSourcePlay),
211 DECL(alSourceStop),
212 DECL(alSourceRewind),
213 DECL(alSourcePause),
214 DECL(alSourceQueueBuffers),
215 DECL(alSourceUnqueueBuffers),
216 DECL(alGenBuffers),
217 DECL(alDeleteBuffers),
218 DECL(alIsBuffer),
219 DECL(alBufferData),
220 DECL(alBufferf),
221 DECL(alBuffer3f),
222 DECL(alBufferfv),
223 DECL(alBufferi),
224 DECL(alBuffer3i),
225 DECL(alBufferiv),
226 DECL(alGetBufferf),
227 DECL(alGetBuffer3f),
228 DECL(alGetBufferfv),
229 DECL(alGetBufferi),
230 DECL(alGetBuffer3i),
231 DECL(alGetBufferiv),
232 DECL(alDopplerFactor),
233 DECL(alDopplerVelocity),
234 DECL(alSpeedOfSound),
235 DECL(alDistanceModel),
237 DECL(alGenFilters),
238 DECL(alDeleteFilters),
239 DECL(alIsFilter),
240 DECL(alFilteri),
241 DECL(alFilteriv),
242 DECL(alFilterf),
243 DECL(alFilterfv),
244 DECL(alGetFilteri),
245 DECL(alGetFilteriv),
246 DECL(alGetFilterf),
247 DECL(alGetFilterfv),
248 DECL(alGenEffects),
249 DECL(alDeleteEffects),
250 DECL(alIsEffect),
251 DECL(alEffecti),
252 DECL(alEffectiv),
253 DECL(alEffectf),
254 DECL(alEffectfv),
255 DECL(alGetEffecti),
256 DECL(alGetEffectiv),
257 DECL(alGetEffectf),
258 DECL(alGetEffectfv),
259 DECL(alGenAuxiliaryEffectSlots),
260 DECL(alDeleteAuxiliaryEffectSlots),
261 DECL(alIsAuxiliaryEffectSlot),
262 DECL(alAuxiliaryEffectSloti),
263 DECL(alAuxiliaryEffectSlotiv),
264 DECL(alAuxiliaryEffectSlotf),
265 DECL(alAuxiliaryEffectSlotfv),
266 DECL(alGetAuxiliaryEffectSloti),
267 DECL(alGetAuxiliaryEffectSlotiv),
268 DECL(alGetAuxiliaryEffectSlotf),
269 DECL(alGetAuxiliaryEffectSlotfv),
271 DECL(alDeferUpdatesSOFT),
272 DECL(alProcessUpdatesSOFT),
274 DECL(alSourcedSOFT),
275 DECL(alSource3dSOFT),
276 DECL(alSourcedvSOFT),
277 DECL(alGetSourcedSOFT),
278 DECL(alGetSource3dSOFT),
279 DECL(alGetSourcedvSOFT),
280 DECL(alSourcei64SOFT),
281 DECL(alSource3i64SOFT),
282 DECL(alSourcei64vSOFT),
283 DECL(alGetSourcei64SOFT),
284 DECL(alGetSource3i64SOFT),
285 DECL(alGetSourcei64vSOFT),
287 DECL(alBufferSamplesSOFT),
288 DECL(alGetBufferSamplesSOFT),
289 DECL(alIsBufferFormatSupportedSOFT),
291 DECL(alGetStringiSOFT),
293 #undef DECL
295 #define DECL(x) { #x, (x) }
296 static const struct {
297 const ALCchar *enumName;
298 ALCenum value;
299 } alcEnumerations[] = {
300 DECL(ALC_INVALID),
301 DECL(ALC_FALSE),
302 DECL(ALC_TRUE),
304 DECL(ALC_MAJOR_VERSION),
305 DECL(ALC_MINOR_VERSION),
306 DECL(ALC_ATTRIBUTES_SIZE),
307 DECL(ALC_ALL_ATTRIBUTES),
308 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
309 DECL(ALC_DEVICE_SPECIFIER),
310 DECL(ALC_ALL_DEVICES_SPECIFIER),
311 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
312 DECL(ALC_EXTENSIONS),
313 DECL(ALC_FREQUENCY),
314 DECL(ALC_REFRESH),
315 DECL(ALC_SYNC),
316 DECL(ALC_MONO_SOURCES),
317 DECL(ALC_STEREO_SOURCES),
318 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
319 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
320 DECL(ALC_CAPTURE_SAMPLES),
321 DECL(ALC_CONNECTED),
323 DECL(ALC_EFX_MAJOR_VERSION),
324 DECL(ALC_EFX_MINOR_VERSION),
325 DECL(ALC_MAX_AUXILIARY_SENDS),
327 DECL(ALC_FORMAT_CHANNELS_SOFT),
328 DECL(ALC_FORMAT_TYPE_SOFT),
330 DECL(ALC_MONO_SOFT),
331 DECL(ALC_STEREO_SOFT),
332 DECL(ALC_QUAD_SOFT),
333 DECL(ALC_5POINT1_SOFT),
334 DECL(ALC_6POINT1_SOFT),
335 DECL(ALC_7POINT1_SOFT),
336 DECL(ALC_BFORMAT3D_SOFT),
338 DECL(ALC_BYTE_SOFT),
339 DECL(ALC_UNSIGNED_BYTE_SOFT),
340 DECL(ALC_SHORT_SOFT),
341 DECL(ALC_UNSIGNED_SHORT_SOFT),
342 DECL(ALC_INT_SOFT),
343 DECL(ALC_UNSIGNED_INT_SOFT),
344 DECL(ALC_FLOAT_SOFT),
346 DECL(ALC_HRTF_SOFT),
347 DECL(ALC_DONT_CARE_SOFT),
348 DECL(ALC_HRTF_STATUS_SOFT),
349 DECL(ALC_HRTF_DISABLED_SOFT),
350 DECL(ALC_HRTF_ENABLED_SOFT),
351 DECL(ALC_HRTF_DENIED_SOFT),
352 DECL(ALC_HRTF_REQUIRED_SOFT),
353 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
354 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
355 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
356 DECL(ALC_HRTF_SPECIFIER_SOFT),
357 DECL(ALC_HRTF_ID_SOFT),
359 DECL(ALC_AMBISONIC_LAYOUT_SOFT),
360 DECL(ALC_AMBISONIC_SCALING_SOFT),
361 DECL(ALC_AMBISONIC_ORDER_SOFT),
362 DECL(ALC_ACN_SOFT),
363 DECL(ALC_FUMA_SOFT),
364 DECL(ALC_N3D_SOFT),
365 DECL(ALC_SN3D_SOFT),
367 DECL(ALC_OUTPUT_LIMITER_SOFT),
369 DECL(ALC_NO_ERROR),
370 DECL(ALC_INVALID_DEVICE),
371 DECL(ALC_INVALID_CONTEXT),
372 DECL(ALC_INVALID_ENUM),
373 DECL(ALC_INVALID_VALUE),
374 DECL(ALC_OUT_OF_MEMORY),
377 DECL(AL_INVALID),
378 DECL(AL_NONE),
379 DECL(AL_FALSE),
380 DECL(AL_TRUE),
382 DECL(AL_SOURCE_RELATIVE),
383 DECL(AL_CONE_INNER_ANGLE),
384 DECL(AL_CONE_OUTER_ANGLE),
385 DECL(AL_PITCH),
386 DECL(AL_POSITION),
387 DECL(AL_DIRECTION),
388 DECL(AL_VELOCITY),
389 DECL(AL_LOOPING),
390 DECL(AL_BUFFER),
391 DECL(AL_GAIN),
392 DECL(AL_MIN_GAIN),
393 DECL(AL_MAX_GAIN),
394 DECL(AL_ORIENTATION),
395 DECL(AL_REFERENCE_DISTANCE),
396 DECL(AL_ROLLOFF_FACTOR),
397 DECL(AL_CONE_OUTER_GAIN),
398 DECL(AL_MAX_DISTANCE),
399 DECL(AL_SEC_OFFSET),
400 DECL(AL_SAMPLE_OFFSET),
401 DECL(AL_BYTE_OFFSET),
402 DECL(AL_SOURCE_TYPE),
403 DECL(AL_STATIC),
404 DECL(AL_STREAMING),
405 DECL(AL_UNDETERMINED),
406 DECL(AL_METERS_PER_UNIT),
407 DECL(AL_LOOP_POINTS_SOFT),
408 DECL(AL_DIRECT_CHANNELS_SOFT),
410 DECL(AL_DIRECT_FILTER),
411 DECL(AL_AUXILIARY_SEND_FILTER),
412 DECL(AL_AIR_ABSORPTION_FACTOR),
413 DECL(AL_ROOM_ROLLOFF_FACTOR),
414 DECL(AL_CONE_OUTER_GAINHF),
415 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
416 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
417 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
419 DECL(AL_SOURCE_STATE),
420 DECL(AL_INITIAL),
421 DECL(AL_PLAYING),
422 DECL(AL_PAUSED),
423 DECL(AL_STOPPED),
425 DECL(AL_BUFFERS_QUEUED),
426 DECL(AL_BUFFERS_PROCESSED),
428 DECL(AL_FORMAT_MONO8),
429 DECL(AL_FORMAT_MONO16),
430 DECL(AL_FORMAT_MONO_FLOAT32),
431 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
432 DECL(AL_FORMAT_STEREO8),
433 DECL(AL_FORMAT_STEREO16),
434 DECL(AL_FORMAT_STEREO_FLOAT32),
435 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
436 DECL(AL_FORMAT_MONO_IMA4),
437 DECL(AL_FORMAT_STEREO_IMA4),
438 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
439 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
440 DECL(AL_FORMAT_QUAD8_LOKI),
441 DECL(AL_FORMAT_QUAD16_LOKI),
442 DECL(AL_FORMAT_QUAD8),
443 DECL(AL_FORMAT_QUAD16),
444 DECL(AL_FORMAT_QUAD32),
445 DECL(AL_FORMAT_51CHN8),
446 DECL(AL_FORMAT_51CHN16),
447 DECL(AL_FORMAT_51CHN32),
448 DECL(AL_FORMAT_61CHN8),
449 DECL(AL_FORMAT_61CHN16),
450 DECL(AL_FORMAT_61CHN32),
451 DECL(AL_FORMAT_71CHN8),
452 DECL(AL_FORMAT_71CHN16),
453 DECL(AL_FORMAT_71CHN32),
454 DECL(AL_FORMAT_REAR8),
455 DECL(AL_FORMAT_REAR16),
456 DECL(AL_FORMAT_REAR32),
457 DECL(AL_FORMAT_MONO_MULAW),
458 DECL(AL_FORMAT_MONO_MULAW_EXT),
459 DECL(AL_FORMAT_STEREO_MULAW),
460 DECL(AL_FORMAT_STEREO_MULAW_EXT),
461 DECL(AL_FORMAT_QUAD_MULAW),
462 DECL(AL_FORMAT_51CHN_MULAW),
463 DECL(AL_FORMAT_61CHN_MULAW),
464 DECL(AL_FORMAT_71CHN_MULAW),
465 DECL(AL_FORMAT_REAR_MULAW),
466 DECL(AL_FORMAT_MONO_ALAW_EXT),
467 DECL(AL_FORMAT_STEREO_ALAW_EXT),
469 DECL(AL_FORMAT_BFORMAT2D_8),
470 DECL(AL_FORMAT_BFORMAT2D_16),
471 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
472 DECL(AL_FORMAT_BFORMAT2D_MULAW),
473 DECL(AL_FORMAT_BFORMAT3D_8),
474 DECL(AL_FORMAT_BFORMAT3D_16),
475 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
476 DECL(AL_FORMAT_BFORMAT3D_MULAW),
478 DECL(AL_MONO8_SOFT),
479 DECL(AL_MONO16_SOFT),
480 DECL(AL_MONO32F_SOFT),
481 DECL(AL_STEREO8_SOFT),
482 DECL(AL_STEREO16_SOFT),
483 DECL(AL_STEREO32F_SOFT),
484 DECL(AL_QUAD8_SOFT),
485 DECL(AL_QUAD16_SOFT),
486 DECL(AL_QUAD32F_SOFT),
487 DECL(AL_REAR8_SOFT),
488 DECL(AL_REAR16_SOFT),
489 DECL(AL_REAR32F_SOFT),
490 DECL(AL_5POINT1_8_SOFT),
491 DECL(AL_5POINT1_16_SOFT),
492 DECL(AL_5POINT1_32F_SOFT),
493 DECL(AL_6POINT1_8_SOFT),
494 DECL(AL_6POINT1_16_SOFT),
495 DECL(AL_6POINT1_32F_SOFT),
496 DECL(AL_7POINT1_8_SOFT),
497 DECL(AL_7POINT1_16_SOFT),
498 DECL(AL_7POINT1_32F_SOFT),
499 DECL(AL_BFORMAT2D_8_SOFT),
500 DECL(AL_BFORMAT2D_16_SOFT),
501 DECL(AL_BFORMAT2D_32F_SOFT),
502 DECL(AL_BFORMAT3D_8_SOFT),
503 DECL(AL_BFORMAT3D_16_SOFT),
504 DECL(AL_BFORMAT3D_32F_SOFT),
506 DECL(AL_MONO_SOFT),
507 DECL(AL_STEREO_SOFT),
508 DECL(AL_QUAD_SOFT),
509 DECL(AL_REAR_SOFT),
510 DECL(AL_5POINT1_SOFT),
511 DECL(AL_6POINT1_SOFT),
512 DECL(AL_7POINT1_SOFT),
513 DECL(AL_BFORMAT2D_SOFT),
514 DECL(AL_BFORMAT3D_SOFT),
516 DECL(AL_BYTE_SOFT),
517 DECL(AL_UNSIGNED_BYTE_SOFT),
518 DECL(AL_SHORT_SOFT),
519 DECL(AL_UNSIGNED_SHORT_SOFT),
520 DECL(AL_INT_SOFT),
521 DECL(AL_UNSIGNED_INT_SOFT),
522 DECL(AL_FLOAT_SOFT),
523 DECL(AL_DOUBLE_SOFT),
524 DECL(AL_BYTE3_SOFT),
525 DECL(AL_UNSIGNED_BYTE3_SOFT),
526 DECL(AL_MULAW_SOFT),
528 DECL(AL_FREQUENCY),
529 DECL(AL_BITS),
530 DECL(AL_CHANNELS),
531 DECL(AL_SIZE),
532 DECL(AL_INTERNAL_FORMAT_SOFT),
533 DECL(AL_BYTE_LENGTH_SOFT),
534 DECL(AL_SAMPLE_LENGTH_SOFT),
535 DECL(AL_SEC_LENGTH_SOFT),
536 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
537 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
539 DECL(AL_SOURCE_RADIUS),
541 DECL(AL_STEREO_ANGLES),
543 DECL(AL_UNUSED),
544 DECL(AL_PENDING),
545 DECL(AL_PROCESSED),
547 DECL(AL_NO_ERROR),
548 DECL(AL_INVALID_NAME),
549 DECL(AL_INVALID_ENUM),
550 DECL(AL_INVALID_VALUE),
551 DECL(AL_INVALID_OPERATION),
552 DECL(AL_OUT_OF_MEMORY),
554 DECL(AL_VENDOR),
555 DECL(AL_VERSION),
556 DECL(AL_RENDERER),
557 DECL(AL_EXTENSIONS),
559 DECL(AL_DOPPLER_FACTOR),
560 DECL(AL_DOPPLER_VELOCITY),
561 DECL(AL_DISTANCE_MODEL),
562 DECL(AL_SPEED_OF_SOUND),
563 DECL(AL_SOURCE_DISTANCE_MODEL),
564 DECL(AL_DEFERRED_UPDATES_SOFT),
565 DECL(AL_GAIN_LIMIT_SOFT),
567 DECL(AL_INVERSE_DISTANCE),
568 DECL(AL_INVERSE_DISTANCE_CLAMPED),
569 DECL(AL_LINEAR_DISTANCE),
570 DECL(AL_LINEAR_DISTANCE_CLAMPED),
571 DECL(AL_EXPONENT_DISTANCE),
572 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
574 DECL(AL_FILTER_TYPE),
575 DECL(AL_FILTER_NULL),
576 DECL(AL_FILTER_LOWPASS),
577 DECL(AL_FILTER_HIGHPASS),
578 DECL(AL_FILTER_BANDPASS),
580 DECL(AL_LOWPASS_GAIN),
581 DECL(AL_LOWPASS_GAINHF),
583 DECL(AL_HIGHPASS_GAIN),
584 DECL(AL_HIGHPASS_GAINLF),
586 DECL(AL_BANDPASS_GAIN),
587 DECL(AL_BANDPASS_GAINHF),
588 DECL(AL_BANDPASS_GAINLF),
590 DECL(AL_EFFECT_TYPE),
591 DECL(AL_EFFECT_NULL),
592 DECL(AL_EFFECT_REVERB),
593 DECL(AL_EFFECT_EAXREVERB),
594 DECL(AL_EFFECT_CHORUS),
595 DECL(AL_EFFECT_DISTORTION),
596 DECL(AL_EFFECT_ECHO),
597 DECL(AL_EFFECT_FLANGER),
598 #if 0
599 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
600 DECL(AL_EFFECT_VOCAL_MORPHER),
601 DECL(AL_EFFECT_PITCH_SHIFTER),
602 #endif
603 DECL(AL_EFFECT_RING_MODULATOR),
604 #if 0
605 DECL(AL_EFFECT_AUTOWAH),
606 #endif
607 DECL(AL_EFFECT_COMPRESSOR),
608 DECL(AL_EFFECT_EQUALIZER),
609 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
610 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
612 DECL(AL_EFFECTSLOT_EFFECT),
613 DECL(AL_EFFECTSLOT_GAIN),
614 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
615 DECL(AL_EFFECTSLOT_NULL),
617 DECL(AL_EAXREVERB_DENSITY),
618 DECL(AL_EAXREVERB_DIFFUSION),
619 DECL(AL_EAXREVERB_GAIN),
620 DECL(AL_EAXREVERB_GAINHF),
621 DECL(AL_EAXREVERB_GAINLF),
622 DECL(AL_EAXREVERB_DECAY_TIME),
623 DECL(AL_EAXREVERB_DECAY_HFRATIO),
624 DECL(AL_EAXREVERB_DECAY_LFRATIO),
625 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
626 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
627 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
628 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
629 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
630 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
631 DECL(AL_EAXREVERB_ECHO_TIME),
632 DECL(AL_EAXREVERB_ECHO_DEPTH),
633 DECL(AL_EAXREVERB_MODULATION_TIME),
634 DECL(AL_EAXREVERB_MODULATION_DEPTH),
635 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
636 DECL(AL_EAXREVERB_HFREFERENCE),
637 DECL(AL_EAXREVERB_LFREFERENCE),
638 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
639 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
641 DECL(AL_REVERB_DENSITY),
642 DECL(AL_REVERB_DIFFUSION),
643 DECL(AL_REVERB_GAIN),
644 DECL(AL_REVERB_GAINHF),
645 DECL(AL_REVERB_DECAY_TIME),
646 DECL(AL_REVERB_DECAY_HFRATIO),
647 DECL(AL_REVERB_REFLECTIONS_GAIN),
648 DECL(AL_REVERB_REFLECTIONS_DELAY),
649 DECL(AL_REVERB_LATE_REVERB_GAIN),
650 DECL(AL_REVERB_LATE_REVERB_DELAY),
651 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
652 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
653 DECL(AL_REVERB_DECAY_HFLIMIT),
655 DECL(AL_CHORUS_WAVEFORM),
656 DECL(AL_CHORUS_PHASE),
657 DECL(AL_CHORUS_RATE),
658 DECL(AL_CHORUS_DEPTH),
659 DECL(AL_CHORUS_FEEDBACK),
660 DECL(AL_CHORUS_DELAY),
662 DECL(AL_DISTORTION_EDGE),
663 DECL(AL_DISTORTION_GAIN),
664 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
665 DECL(AL_DISTORTION_EQCENTER),
666 DECL(AL_DISTORTION_EQBANDWIDTH),
668 DECL(AL_ECHO_DELAY),
669 DECL(AL_ECHO_LRDELAY),
670 DECL(AL_ECHO_DAMPING),
671 DECL(AL_ECHO_FEEDBACK),
672 DECL(AL_ECHO_SPREAD),
674 DECL(AL_FLANGER_WAVEFORM),
675 DECL(AL_FLANGER_PHASE),
676 DECL(AL_FLANGER_RATE),
677 DECL(AL_FLANGER_DEPTH),
678 DECL(AL_FLANGER_FEEDBACK),
679 DECL(AL_FLANGER_DELAY),
681 DECL(AL_RING_MODULATOR_FREQUENCY),
682 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
683 DECL(AL_RING_MODULATOR_WAVEFORM),
685 DECL(AL_COMPRESSOR_ONOFF),
687 DECL(AL_EQUALIZER_LOW_GAIN),
688 DECL(AL_EQUALIZER_LOW_CUTOFF),
689 DECL(AL_EQUALIZER_MID1_GAIN),
690 DECL(AL_EQUALIZER_MID1_CENTER),
691 DECL(AL_EQUALIZER_MID1_WIDTH),
692 DECL(AL_EQUALIZER_MID2_GAIN),
693 DECL(AL_EQUALIZER_MID2_CENTER),
694 DECL(AL_EQUALIZER_MID2_WIDTH),
695 DECL(AL_EQUALIZER_HIGH_GAIN),
696 DECL(AL_EQUALIZER_HIGH_CUTOFF),
698 DECL(AL_DEDICATED_GAIN),
700 DECL(AL_NUM_RESAMPLERS_SOFT),
701 DECL(AL_DEFAULT_RESAMPLER_SOFT),
702 DECL(AL_SOURCE_RESAMPLER_SOFT),
703 DECL(AL_RESAMPLER_NAME_SOFT),
705 DECL(AL_SOURCE_SPATIALIZE_SOFT),
706 DECL(AL_AUTO_SOFT),
708 #undef DECL
710 static const ALCchar alcNoError[] = "No Error";
711 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
712 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
713 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
714 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
715 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
718 /************************************************
719 * Global variables
720 ************************************************/
722 /* Enumerated device names */
723 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
725 static al_string alcAllDevicesList;
726 static al_string alcCaptureDeviceList;
728 /* Default is always the first in the list */
729 static ALCchar *alcDefaultAllDevicesSpecifier;
730 static ALCchar *alcCaptureDefaultDeviceSpecifier;
732 /* Default context extensions */
733 static const ALchar alExtList[] =
734 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
735 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
736 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
737 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
738 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
739 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
740 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length "
741 "AL_SOFT_source_resampler AL_SOFTX_source_spatialize";
743 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
745 /* Thread-local current context */
746 static altss_t LocalContext;
747 /* Process-wide current context */
748 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
750 /* Mixing thread piority level */
751 ALint RTPrioLevel;
753 FILE *LogFile;
754 #ifdef _DEBUG
755 enum LogLevel LogLevel = LogWarning;
756 #else
757 enum LogLevel LogLevel = LogError;
758 #endif
760 /* Flag to trap ALC device errors */
761 static ALCboolean TrapALCError = ALC_FALSE;
763 /* One-time configuration init control */
764 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
766 /* Default effect that applies to sources that don't have an effect on send 0 */
767 static ALeffect DefaultEffect;
769 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
770 * updates.
772 static ALCboolean SuspendDefers = ALC_TRUE;
775 /************************************************
776 * ALC information
777 ************************************************/
778 static const ALCchar alcNoDeviceExtList[] =
779 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
780 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
781 static const ALCchar alcExtensionList[] =
782 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
783 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
784 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
785 "ALC_SOFT_loopback ALC_SOFTX_output_limiter ALC_SOFT_pause_device";
786 static const ALCint alcMajorVersion = 1;
787 static const ALCint alcMinorVersion = 1;
789 static const ALCint alcEFXMajorVersion = 1;
790 static const ALCint alcEFXMinorVersion = 0;
793 /************************************************
794 * Device lists
795 ************************************************/
796 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
798 static almtx_t ListLock;
799 static inline void LockLists(void)
801 int ret = almtx_lock(&ListLock);
802 assert(ret == althrd_success);
804 static inline void UnlockLists(void)
806 int ret = almtx_unlock(&ListLock);
807 assert(ret == althrd_success);
810 /************************************************
811 * Library initialization
812 ************************************************/
813 #if defined(_WIN32)
814 static void alc_init(void);
815 static void alc_deinit(void);
816 static void alc_deinit_safe(void);
818 #ifndef AL_LIBTYPE_STATIC
819 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
821 switch(reason)
823 case DLL_PROCESS_ATTACH:
824 /* Pin the DLL so we won't get unloaded until the process terminates */
825 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
826 (WCHAR*)hModule, &hModule);
827 alc_init();
828 break;
830 case DLL_THREAD_DETACH:
831 break;
833 case DLL_PROCESS_DETACH:
834 if(!lpReserved)
835 alc_deinit();
836 else
837 alc_deinit_safe();
838 break;
840 return TRUE;
842 #elif defined(_MSC_VER)
843 #pragma section(".CRT$XCU",read)
844 static void alc_constructor(void);
845 static void alc_destructor(void);
846 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
848 static void alc_constructor(void)
850 atexit(alc_destructor);
851 alc_init();
854 static void alc_destructor(void)
856 alc_deinit();
858 #elif defined(HAVE_GCC_DESTRUCTOR)
859 static void alc_init(void) __attribute__((constructor));
860 static void alc_deinit(void) __attribute__((destructor));
861 #else
862 #error "No static initialization available on this platform!"
863 #endif
865 #elif defined(HAVE_GCC_DESTRUCTOR)
867 static void alc_init(void) __attribute__((constructor));
868 static void alc_deinit(void) __attribute__((destructor));
870 #else
871 #error "No global initialization available on this platform!"
872 #endif
874 static void ReleaseThreadCtx(void *ptr);
875 static void alc_init(void)
877 const char *str;
878 int ret;
880 LogFile = stderr;
882 AL_STRING_INIT(alcAllDevicesList);
883 AL_STRING_INIT(alcCaptureDeviceList);
885 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
886 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
887 ConeScale *= 0.5f;
889 str = getenv("__ALSOFT_REVERSE_Z");
890 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
891 ZScale *= -1.0f;
893 ret = altss_create(&LocalContext, ReleaseThreadCtx);
894 assert(ret == althrd_success);
896 ret = almtx_init(&ListLock, almtx_recursive);
897 assert(ret == althrd_success);
899 ThunkInit();
902 static void alc_initconfig(void)
904 const char *devs, *str;
905 ALuint capfilter;
906 float valf;
907 int i, n;
909 str = getenv("ALSOFT_LOGLEVEL");
910 if(str)
912 long lvl = strtol(str, NULL, 0);
913 if(lvl >= NoLog && lvl <= LogRef)
914 LogLevel = lvl;
917 str = getenv("ALSOFT_LOGFILE");
918 if(str && str[0])
920 FILE *logfile = al_fopen(str, "wt");
921 if(logfile) LogFile = logfile;
922 else ERR("Failed to open log file '%s'\n", str);
925 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION,
926 ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
928 char buf[1024] = "";
929 int len = 0;
931 if(BackendListSize > 0)
932 len += snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
933 for(i = 1;i < BackendListSize;i++)
934 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
935 TRACE("Supported backends: %s\n", buf);
937 ReadALConfig();
939 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
940 if(str && *str)
942 if(strcasecmp(str, "ignore") == 0)
944 SuspendDefers = ALC_FALSE;
945 TRACE("Selected context suspend behavior, \"ignore\"\n");
947 else
948 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
951 capfilter = 0;
952 #if defined(HAVE_SSE4_1)
953 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
954 #elif defined(HAVE_SSE3)
955 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
956 #elif defined(HAVE_SSE2)
957 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
958 #elif defined(HAVE_SSE)
959 capfilter |= CPU_CAP_SSE;
960 #endif
961 #ifdef HAVE_NEON
962 capfilter |= CPU_CAP_NEON;
963 #endif
964 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
966 if(strcasecmp(str, "all") == 0)
967 capfilter = 0;
968 else
970 size_t len;
971 const char *next = str;
973 do {
974 str = next;
975 while(isspace(str[0]))
976 str++;
977 next = strchr(str, ',');
979 if(!str[0] || str[0] == ',')
980 continue;
982 len = (next ? ((size_t)(next-str)) : strlen(str));
983 while(len > 0 && isspace(str[len-1]))
984 len--;
985 if(len == 3 && strncasecmp(str, "sse", len) == 0)
986 capfilter &= ~CPU_CAP_SSE;
987 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
988 capfilter &= ~CPU_CAP_SSE2;
989 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
990 capfilter &= ~CPU_CAP_SSE3;
991 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
992 capfilter &= ~CPU_CAP_SSE4_1;
993 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
994 capfilter &= ~CPU_CAP_NEON;
995 else
996 WARN("Invalid CPU extension \"%s\"\n", str);
997 } while(next++);
1000 FillCPUCaps(capfilter);
1002 #ifdef _WIN32
1003 RTPrioLevel = 1;
1004 #else
1005 RTPrioLevel = 0;
1006 #endif
1007 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
1009 aluInitMixer();
1011 str = getenv("ALSOFT_TRAP_ERROR");
1012 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1014 TrapALError = AL_TRUE;
1015 TrapALCError = AL_TRUE;
1017 else
1019 str = getenv("ALSOFT_TRAP_AL_ERROR");
1020 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1021 TrapALError = AL_TRUE;
1022 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1024 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1025 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1026 TrapALCError = ALC_TRUE;
1027 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1030 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1031 ReverbBoost *= powf(10.0f, valf / 20.0f);
1033 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1035 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1036 ConfigValueStr(NULL, NULL, "drivers", &devs))
1038 int n;
1039 size_t len;
1040 const char *next = devs;
1041 int endlist, delitem;
1043 i = 0;
1044 do {
1045 devs = next;
1046 while(isspace(devs[0]))
1047 devs++;
1048 next = strchr(devs, ',');
1050 delitem = (devs[0] == '-');
1051 if(devs[0] == '-') devs++;
1053 if(!devs[0] || devs[0] == ',')
1055 endlist = 0;
1056 continue;
1058 endlist = 1;
1060 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1061 while(len > 0 && isspace(devs[len-1]))
1062 len--;
1063 for(n = i;n < BackendListSize;n++)
1065 if(len == strlen(BackendList[n].name) &&
1066 strncmp(BackendList[n].name, devs, len) == 0)
1068 if(delitem)
1070 for(;n+1 < BackendListSize;n++)
1071 BackendList[n] = BackendList[n+1];
1072 BackendListSize--;
1074 else
1076 struct BackendInfo Bkp = BackendList[n];
1077 for(;n > i;n--)
1078 BackendList[n] = BackendList[n-1];
1079 BackendList[n] = Bkp;
1081 i++;
1083 break;
1086 } while(next++);
1088 if(endlist)
1089 BackendListSize = i;
1092 for(i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1094 if(BackendList[i].getFactory)
1096 ALCbackendFactory *factory = BackendList[i].getFactory();
1097 if(!V0(factory,init)())
1099 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1100 continue;
1103 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1104 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1106 PlaybackBackend = BackendList[i];
1107 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1109 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1111 CaptureBackend = BackendList[i];
1112 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1115 continue;
1118 if(!BackendList[i].Init(&BackendList[i].Funcs))
1120 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1121 continue;
1124 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1125 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1127 PlaybackBackend = BackendList[i];
1128 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1130 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1132 CaptureBackend = BackendList[i];
1133 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1137 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1138 V0(factory,init)();
1141 if(!PlaybackBackend.name)
1142 WARN("No playback backend available!\n");
1143 if(!CaptureBackend.name)
1144 WARN("No capture backend available!\n");
1146 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1148 size_t len;
1149 const char *next = str;
1151 do {
1152 str = next;
1153 next = strchr(str, ',');
1155 if(!str[0] || next == str)
1156 continue;
1158 len = (next ? ((size_t)(next-str)) : strlen(str));
1159 for(n = 0;EffectList[n].name;n++)
1161 if(len == strlen(EffectList[n].name) &&
1162 strncmp(EffectList[n].name, str, len) == 0)
1163 DisabledEffects[EffectList[n].type] = AL_TRUE;
1165 } while(next++);
1168 InitEffectFactoryMap();
1170 InitEffect(&DefaultEffect);
1171 str = getenv("ALSOFT_DEFAULT_REVERB");
1172 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1173 LoadReverbPreset(str, &DefaultEffect);
1175 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1177 #ifdef __ANDROID__
1178 #include <jni.h>
1180 static JavaVM *gJavaVM;
1181 static pthread_key_t gJVMThreadKey;
1183 static void CleanupJNIEnv(void* UNUSED(ptr))
1185 JCALL0(gJavaVM,DetachCurrentThread)();
1188 void *Android_GetJNIEnv(void)
1190 if(!gJavaVM)
1192 WARN("gJavaVM is NULL!\n");
1193 return NULL;
1196 /* http://developer.android.com/guide/practices/jni.html
1198 * All threads are Linux threads, scheduled by the kernel. They're usually
1199 * started from managed code (using Thread.start), but they can also be
1200 * created elsewhere and then attached to the JavaVM. For example, a thread
1201 * started with pthread_create can be attached with the JNI
1202 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1203 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1204 * Attaching a natively-created thread causes a java.lang.Thread object to
1205 * be constructed and added to the "main" ThreadGroup, making it visible to
1206 * the debugger. Calling AttachCurrentThread on an already-attached thread
1207 * is a no-op.
1209 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1210 if(!env)
1212 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1213 if(status < 0)
1215 ERR("Failed to attach current thread\n");
1216 return NULL;
1218 pthread_setspecific(gJVMThreadKey, env);
1220 return env;
1223 /* Automatically called by JNI. */
1224 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1226 void *env;
1227 int err;
1229 gJavaVM = jvm;
1230 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1232 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1233 return JNI_ERR;
1236 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1237 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1239 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1240 ERR("pthread_key_create failed: %d\n", err);
1241 pthread_setspecific(gJVMThreadKey, env);
1242 return JNI_VERSION_1_4;
1245 #endif
1248 /************************************************
1249 * Library deinitialization
1250 ************************************************/
1251 static void alc_cleanup(void)
1253 ALCdevice *dev;
1255 AL_STRING_DEINIT(alcAllDevicesList);
1256 AL_STRING_DEINIT(alcCaptureDeviceList);
1258 free(alcDefaultAllDevicesSpecifier);
1259 alcDefaultAllDevicesSpecifier = NULL;
1260 free(alcCaptureDefaultDeviceSpecifier);
1261 alcCaptureDefaultDeviceSpecifier = NULL;
1263 if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL)
1265 ALCuint num = 0;
1266 do {
1267 num++;
1268 } while((dev=dev->next) != NULL);
1269 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1272 DeinitEffectFactoryMap();
1275 static void alc_deinit_safe(void)
1277 alc_cleanup();
1279 FreeHrtfs();
1280 FreeALConfig();
1282 ThunkExit();
1283 almtx_destroy(&ListLock);
1284 altss_delete(LocalContext);
1286 if(LogFile != stderr)
1287 fclose(LogFile);
1288 LogFile = NULL;
1291 static void alc_deinit(void)
1293 int i;
1295 alc_cleanup();
1297 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1298 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1300 for(i = 0;i < BackendListSize;i++)
1302 if(!BackendList[i].getFactory)
1303 BackendList[i].Deinit();
1304 else
1306 ALCbackendFactory *factory = BackendList[i].getFactory();
1307 V0(factory,deinit)();
1311 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1312 V0(factory,deinit)();
1315 alc_deinit_safe();
1319 /************************************************
1320 * Device enumeration
1321 ************************************************/
1322 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1324 DO_INITCONFIG();
1326 LockLists();
1327 alstr_clear(list);
1329 if(backendinfo->Probe)
1330 backendinfo->Probe(type);
1331 else if(backendinfo->getFactory)
1333 ALCbackendFactory *factory = backendinfo->getFactory();
1334 V(factory,probe)(type);
1336 UnlockLists();
1338 static void ProbeAllDevicesList(void)
1339 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1340 static void ProbeCaptureDeviceList(void)
1341 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1343 static void AppendDevice(const ALCchar *name, al_string *devnames)
1345 size_t len = strlen(name);
1346 if(len > 0)
1347 alstr_append_range(devnames, name, name+len+1);
1349 void AppendAllDevicesList(const ALCchar *name)
1350 { AppendDevice(name, &alcAllDevicesList); }
1351 void AppendCaptureDeviceList(const ALCchar *name)
1352 { AppendDevice(name, &alcCaptureDeviceList); }
1355 /************************************************
1356 * Device format information
1357 ************************************************/
1358 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1360 switch(type)
1362 case DevFmtByte: return "Signed Byte";
1363 case DevFmtUByte: return "Unsigned Byte";
1364 case DevFmtShort: return "Signed Short";
1365 case DevFmtUShort: return "Unsigned Short";
1366 case DevFmtInt: return "Signed Int";
1367 case DevFmtUInt: return "Unsigned Int";
1368 case DevFmtFloat: return "Float";
1370 return "(unknown type)";
1372 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1374 switch(chans)
1376 case DevFmtMono: return "Mono";
1377 case DevFmtStereo: return "Stereo";
1378 case DevFmtQuad: return "Quadraphonic";
1379 case DevFmtX51: return "5.1 Surround";
1380 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1381 case DevFmtX61: return "6.1 Surround";
1382 case DevFmtX71: return "7.1 Surround";
1383 case DevFmtAmbi3D: return "Ambisonic 3D";
1385 return "(unknown channels)";
1388 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder);
1389 ALsizei BytesFromDevFmt(enum DevFmtType type)
1391 switch(type)
1393 case DevFmtByte: return sizeof(ALbyte);
1394 case DevFmtUByte: return sizeof(ALubyte);
1395 case DevFmtShort: return sizeof(ALshort);
1396 case DevFmtUShort: return sizeof(ALushort);
1397 case DevFmtInt: return sizeof(ALint);
1398 case DevFmtUInt: return sizeof(ALuint);
1399 case DevFmtFloat: return sizeof(ALfloat);
1401 return 0;
1403 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder)
1405 switch(chans)
1407 case DevFmtMono: return 1;
1408 case DevFmtStereo: return 2;
1409 case DevFmtQuad: return 4;
1410 case DevFmtX51: return 6;
1411 case DevFmtX51Rear: return 6;
1412 case DevFmtX61: return 7;
1413 case DevFmtX71: return 8;
1414 case DevFmtAmbi3D: return (ambiorder >= 3) ? 16 :
1415 (ambiorder == 2) ? 9 :
1416 (ambiorder == 1) ? 4 : 1;
1418 return 0;
1421 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1422 enum DevFmtType *type)
1424 static const struct {
1425 ALenum format;
1426 enum DevFmtChannels channels;
1427 enum DevFmtType type;
1428 } list[] = {
1429 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1430 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1431 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1433 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1434 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1435 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1437 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1438 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1439 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1441 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1442 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1443 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1445 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1446 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1447 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1449 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1450 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1451 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1453 ALuint i;
1455 for(i = 0;i < COUNTOF(list);i++)
1457 if(list[i].format == format)
1459 *chans = list[i].channels;
1460 *type = list[i].type;
1461 return AL_TRUE;
1465 return AL_FALSE;
1468 static ALCboolean IsValidALCType(ALCenum type)
1470 switch(type)
1472 case ALC_BYTE_SOFT:
1473 case ALC_UNSIGNED_BYTE_SOFT:
1474 case ALC_SHORT_SOFT:
1475 case ALC_UNSIGNED_SHORT_SOFT:
1476 case ALC_INT_SOFT:
1477 case ALC_UNSIGNED_INT_SOFT:
1478 case ALC_FLOAT_SOFT:
1479 return ALC_TRUE;
1481 return ALC_FALSE;
1484 static ALCboolean IsValidALCChannels(ALCenum channels)
1486 switch(channels)
1488 case ALC_MONO_SOFT:
1489 case ALC_STEREO_SOFT:
1490 case ALC_QUAD_SOFT:
1491 case ALC_5POINT1_SOFT:
1492 case ALC_6POINT1_SOFT:
1493 case ALC_7POINT1_SOFT:
1494 case ALC_BFORMAT3D_SOFT:
1495 return ALC_TRUE;
1497 return ALC_FALSE;
1500 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1502 switch(layout)
1504 case ALC_ACN_SOFT:
1505 case ALC_FUMA_SOFT:
1506 return ALC_TRUE;
1508 return ALC_FALSE;
1511 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1513 switch(scaling)
1515 case ALC_N3D_SOFT:
1516 case ALC_SN3D_SOFT:
1517 case ALC_FUMA_SOFT:
1518 return ALC_TRUE;
1520 return ALC_FALSE;
1523 /************************************************
1524 * Miscellaneous ALC helpers
1525 ************************************************/
1527 void ALCdevice_Lock(ALCdevice *device)
1529 V0(device->Backend,lock)();
1532 void ALCdevice_Unlock(ALCdevice *device)
1534 V0(device->Backend,unlock)();
1538 /* SetDefaultWFXChannelOrder
1540 * Sets the default channel order used by WaveFormatEx.
1542 void SetDefaultWFXChannelOrder(ALCdevice *device)
1544 ALsizei i;
1546 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1547 device->RealOut.ChannelName[i] = InvalidChannel;
1549 switch(device->FmtChans)
1551 case DevFmtMono:
1552 device->RealOut.ChannelName[0] = FrontCenter;
1553 break;
1554 case DevFmtStereo:
1555 device->RealOut.ChannelName[0] = FrontLeft;
1556 device->RealOut.ChannelName[1] = FrontRight;
1557 break;
1558 case DevFmtQuad:
1559 device->RealOut.ChannelName[0] = FrontLeft;
1560 device->RealOut.ChannelName[1] = FrontRight;
1561 device->RealOut.ChannelName[2] = BackLeft;
1562 device->RealOut.ChannelName[3] = BackRight;
1563 break;
1564 case DevFmtX51:
1565 device->RealOut.ChannelName[0] = FrontLeft;
1566 device->RealOut.ChannelName[1] = FrontRight;
1567 device->RealOut.ChannelName[2] = FrontCenter;
1568 device->RealOut.ChannelName[3] = LFE;
1569 device->RealOut.ChannelName[4] = SideLeft;
1570 device->RealOut.ChannelName[5] = SideRight;
1571 break;
1572 case DevFmtX51Rear:
1573 device->RealOut.ChannelName[0] = FrontLeft;
1574 device->RealOut.ChannelName[1] = FrontRight;
1575 device->RealOut.ChannelName[2] = FrontCenter;
1576 device->RealOut.ChannelName[3] = LFE;
1577 device->RealOut.ChannelName[4] = BackLeft;
1578 device->RealOut.ChannelName[5] = BackRight;
1579 break;
1580 case DevFmtX61:
1581 device->RealOut.ChannelName[0] = FrontLeft;
1582 device->RealOut.ChannelName[1] = FrontRight;
1583 device->RealOut.ChannelName[2] = FrontCenter;
1584 device->RealOut.ChannelName[3] = LFE;
1585 device->RealOut.ChannelName[4] = BackCenter;
1586 device->RealOut.ChannelName[5] = SideLeft;
1587 device->RealOut.ChannelName[6] = SideRight;
1588 break;
1589 case DevFmtX71:
1590 device->RealOut.ChannelName[0] = FrontLeft;
1591 device->RealOut.ChannelName[1] = FrontRight;
1592 device->RealOut.ChannelName[2] = FrontCenter;
1593 device->RealOut.ChannelName[3] = LFE;
1594 device->RealOut.ChannelName[4] = BackLeft;
1595 device->RealOut.ChannelName[5] = BackRight;
1596 device->RealOut.ChannelName[6] = SideLeft;
1597 device->RealOut.ChannelName[7] = SideRight;
1598 break;
1599 case DevFmtAmbi3D:
1600 device->RealOut.ChannelName[0] = Aux0;
1601 if(device->AmbiOrder > 0)
1603 device->RealOut.ChannelName[1] = Aux1;
1604 device->RealOut.ChannelName[2] = Aux2;
1605 device->RealOut.ChannelName[3] = Aux3;
1607 if(device->AmbiOrder > 1)
1609 device->RealOut.ChannelName[4] = Aux4;
1610 device->RealOut.ChannelName[5] = Aux5;
1611 device->RealOut.ChannelName[6] = Aux6;
1612 device->RealOut.ChannelName[7] = Aux7;
1613 device->RealOut.ChannelName[8] = Aux8;
1615 if(device->AmbiOrder > 2)
1617 device->RealOut.ChannelName[9] = Aux9;
1618 device->RealOut.ChannelName[10] = Aux10;
1619 device->RealOut.ChannelName[11] = Aux11;
1620 device->RealOut.ChannelName[12] = Aux12;
1621 device->RealOut.ChannelName[13] = Aux13;
1622 device->RealOut.ChannelName[14] = Aux14;
1623 device->RealOut.ChannelName[15] = Aux15;
1625 break;
1629 /* SetDefaultChannelOrder
1631 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1633 void SetDefaultChannelOrder(ALCdevice *device)
1635 ALsizei i;
1637 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1638 device->RealOut.ChannelName[i] = InvalidChannel;
1640 switch(device->FmtChans)
1642 case DevFmtX51Rear:
1643 device->RealOut.ChannelName[0] = FrontLeft;
1644 device->RealOut.ChannelName[1] = FrontRight;
1645 device->RealOut.ChannelName[2] = BackLeft;
1646 device->RealOut.ChannelName[3] = BackRight;
1647 device->RealOut.ChannelName[4] = FrontCenter;
1648 device->RealOut.ChannelName[5] = LFE;
1649 return;
1650 case DevFmtX71:
1651 device->RealOut.ChannelName[0] = FrontLeft;
1652 device->RealOut.ChannelName[1] = FrontRight;
1653 device->RealOut.ChannelName[2] = BackLeft;
1654 device->RealOut.ChannelName[3] = BackRight;
1655 device->RealOut.ChannelName[4] = FrontCenter;
1656 device->RealOut.ChannelName[5] = LFE;
1657 device->RealOut.ChannelName[6] = SideLeft;
1658 device->RealOut.ChannelName[7] = SideRight;
1659 return;
1661 /* Same as WFX order */
1662 case DevFmtMono:
1663 case DevFmtStereo:
1664 case DevFmtQuad:
1665 case DevFmtX51:
1666 case DevFmtX61:
1667 case DevFmtAmbi3D:
1668 SetDefaultWFXChannelOrder(device);
1669 break;
1673 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1676 /* ALCcontext_DeferUpdates
1678 * Defers/suspends updates for the given context's listener and sources. This
1679 * does *NOT* stop mixing, but rather prevents certain property changes from
1680 * taking effect.
1682 void ALCcontext_DeferUpdates(ALCcontext *context)
1684 ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE);
1687 /* ALCcontext_ProcessUpdates
1689 * Resumes update processing after being deferred.
1691 void ALCcontext_ProcessUpdates(ALCcontext *context)
1693 ReadLock(&context->PropLock);
1694 if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
1696 /* Tell the mixer to stop applying updates, then wait for any active
1697 * updating to finish, before providing updates.
1699 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1700 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1701 althrd_yield();
1703 UpdateListenerProps(context);
1704 UpdateAllEffectSlotProps(context);
1705 UpdateAllSourceProps(context);
1707 /* Now with all updates declared, let the mixer continue applying them
1708 * so they all happen at once.
1710 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1712 ReadUnlock(&context->PropLock);
1716 /* alcSetError
1718 * Stores the latest ALC device error
1720 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1722 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1723 if(TrapALCError)
1725 #ifdef _WIN32
1726 /* DebugBreak() will cause an exception if there is no debugger */
1727 if(IsDebuggerPresent())
1728 DebugBreak();
1729 #elif defined(SIGTRAP)
1730 raise(SIGTRAP);
1731 #endif
1734 if(device)
1735 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1736 else
1737 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1741 /* UpdateClockBase
1743 * Updates the device's base clock time with however many samples have been
1744 * done. This is used so frequency changes on the device don't cause the time
1745 * to jump forward or back. Must not be called while the device is running/
1746 * mixing.
1748 static inline void UpdateClockBase(ALCdevice *device)
1750 IncrementRef(&device->MixCount);
1751 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1752 device->SamplesDone = 0;
1753 IncrementRef(&device->MixCount);
1756 /* UpdateDeviceParams
1758 * Updates device parameters according to the attribute list (caller is
1759 * responsible for holding the list lock).
1761 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1763 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1764 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1765 ALCenum gainLimiter = !!device->Limiter;
1766 const ALsizei old_sends = device->NumAuxSends;
1767 ALsizei new_sends = device->NumAuxSends;
1768 enum DevFmtChannels oldChans;
1769 enum DevFmtType oldType;
1770 ALboolean update_failed;
1771 ALCsizei hrtf_id = -1;
1772 ALCcontext *context;
1773 ALCuint oldFreq;
1774 FPUCtl oldMode;
1775 size_t size;
1776 ALCsizei i;
1777 int val;
1779 // Check for attributes
1780 if(device->Type == Loopback)
1782 ALCsizei numMono, numStereo, numSends;
1783 ALCenum alayout = AL_NONE;
1784 ALCenum ascale = AL_NONE;
1785 ALCenum schans = AL_NONE;
1786 ALCenum stype = AL_NONE;
1787 ALCsizei attrIdx = 0;
1788 ALCsizei aorder = 0;
1789 ALCuint freq = 0;
1791 if(!attrList)
1793 WARN("Missing attributes for loopback device\n");
1794 return ALC_INVALID_VALUE;
1797 numMono = device->NumMonoSources;
1798 numStereo = device->NumStereoSources;
1799 numSends = old_sends;
1801 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1802 while(attrList[attrIdx])
1804 switch(attrList[attrIdx])
1806 case ALC_FORMAT_CHANNELS_SOFT:
1807 schans = attrList[attrIdx + 1];
1808 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1809 if(!IsValidALCChannels(schans))
1810 return ALC_INVALID_VALUE;
1811 break;
1813 case ALC_FORMAT_TYPE_SOFT:
1814 stype = attrList[attrIdx + 1];
1815 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1816 if(!IsValidALCType(stype))
1817 return ALC_INVALID_VALUE;
1818 break;
1820 case ALC_FREQUENCY:
1821 freq = attrList[attrIdx + 1];
1822 TRACE_ATTR(ALC_FREQUENCY, freq);
1823 if(freq < MIN_OUTPUT_RATE)
1824 return ALC_INVALID_VALUE;
1825 break;
1827 case ALC_AMBISONIC_LAYOUT_SOFT:
1828 alayout = attrList[attrIdx + 1];
1829 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1830 if(!IsValidAmbiLayout(alayout))
1831 return ALC_INVALID_VALUE;
1832 break;
1834 case ALC_AMBISONIC_SCALING_SOFT:
1835 ascale = attrList[attrIdx + 1];
1836 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1837 if(!IsValidAmbiScaling(ascale))
1838 return ALC_INVALID_VALUE;
1839 break;
1841 case ALC_AMBISONIC_ORDER_SOFT:
1842 aorder = attrList[attrIdx + 1];
1843 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1844 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1845 return ALC_INVALID_VALUE;
1846 break;
1848 case ALC_MONO_SOURCES:
1849 numMono = attrList[attrIdx + 1];
1850 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1851 numMono = maxi(numMono, 0);
1852 break;
1854 case ALC_STEREO_SOURCES:
1855 numStereo = attrList[attrIdx + 1];
1856 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1857 numStereo = maxi(numStereo, 0);
1858 break;
1860 case ALC_MAX_AUXILIARY_SENDS:
1861 numSends = attrList[attrIdx + 1];
1862 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1863 numSends = clampi(numSends, 0, MAX_SENDS);
1864 break;
1866 case ALC_HRTF_SOFT:
1867 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1868 if(attrList[attrIdx + 1] == ALC_FALSE)
1869 hrtf_appreq = Hrtf_Disable;
1870 else if(attrList[attrIdx + 1] == ALC_TRUE)
1871 hrtf_appreq = Hrtf_Enable;
1872 else
1873 hrtf_appreq = Hrtf_Default;
1874 break;
1876 case ALC_HRTF_ID_SOFT:
1877 hrtf_id = attrList[attrIdx + 1];
1878 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1879 break;
1881 case ALC_OUTPUT_LIMITER_SOFT:
1882 gainLimiter = attrList[attrIdx + 1];
1883 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1884 break;
1886 default:
1887 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList[attrIdx],
1888 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1889 break;
1892 attrIdx += 2;
1894 #undef TRACE_ATTR
1896 if(!schans || !stype || !freq)
1898 WARN("Missing format for loopback device\n");
1899 return ALC_INVALID_VALUE;
1901 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1903 WARN("Missing ambisonic info for loopback device\n");
1904 return ALC_INVALID_VALUE;
1907 if((device->Flags&DEVICE_RUNNING))
1908 V0(device->Backend,stop)();
1909 device->Flags &= ~DEVICE_RUNNING;
1911 UpdateClockBase(device);
1913 device->Frequency = freq;
1914 device->FmtChans = schans;
1915 device->FmtType = stype;
1916 if(schans == ALC_BFORMAT3D_SOFT)
1918 device->AmbiOrder = aorder;
1919 device->AmbiLayout = alayout;
1920 device->AmbiScale = ascale;
1923 if(numMono > INT_MAX-numStereo)
1924 numMono = INT_MAX-numStereo;
1925 numMono += numStereo;
1926 if(ConfigValueInt(NULL, NULL, "sources", &numMono))
1928 if(numMono <= 0)
1929 numMono = 256;
1931 else
1932 numMono = maxi(numMono, 256);
1933 numStereo = mini(numStereo, numMono);
1934 numMono -= numStereo;
1935 device->SourcesMax = numMono + numStereo;
1937 device->NumMonoSources = numMono;
1938 device->NumStereoSources = numStereo;
1940 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1941 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1942 else
1943 new_sends = numSends;
1945 else if(attrList && attrList[0])
1947 ALCsizei numMono, numStereo, numSends;
1948 ALCsizei attrIdx = 0;
1949 ALCuint freq;
1951 /* If a context is already running on the device, stop playback so the
1952 * device attributes can be updated. */
1953 if((device->Flags&DEVICE_RUNNING))
1954 V0(device->Backend,stop)();
1955 device->Flags &= ~DEVICE_RUNNING;
1957 UpdateClockBase(device);
1959 freq = device->Frequency;
1960 numMono = device->NumMonoSources;
1961 numStereo = device->NumStereoSources;
1962 numSends = old_sends;
1964 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1965 while(attrList[attrIdx])
1967 switch(attrList[attrIdx])
1969 case ALC_FREQUENCY:
1970 freq = attrList[attrIdx + 1];
1971 TRACE_ATTR(ALC_FREQUENCY, freq);
1972 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1973 break;
1975 case ALC_MONO_SOURCES:
1976 numMono = attrList[attrIdx + 1];
1977 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1978 numMono = maxi(numMono, 0);
1979 break;
1981 case ALC_STEREO_SOURCES:
1982 numStereo = attrList[attrIdx + 1];
1983 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1984 numStereo = maxi(numStereo, 0);
1985 break;
1987 case ALC_MAX_AUXILIARY_SENDS:
1988 numSends = attrList[attrIdx + 1];
1989 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1990 numSends = clampi(numSends, 0, MAX_SENDS);
1991 break;
1993 case ALC_HRTF_SOFT:
1994 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1995 if(attrList[attrIdx + 1] == ALC_FALSE)
1996 hrtf_appreq = Hrtf_Disable;
1997 else if(attrList[attrIdx + 1] == ALC_TRUE)
1998 hrtf_appreq = Hrtf_Enable;
1999 else
2000 hrtf_appreq = Hrtf_Default;
2001 break;
2003 case ALC_HRTF_ID_SOFT:
2004 hrtf_id = attrList[attrIdx + 1];
2005 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
2006 break;
2008 case ALC_OUTPUT_LIMITER_SOFT:
2009 gainLimiter = attrList[attrIdx + 1];
2010 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
2011 break;
2013 default:
2014 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
2015 attrList[attrIdx + 1], attrList[attrIdx + 1]);
2016 break;
2019 attrIdx += 2;
2021 #undef TRACE_ATTR
2023 ConfigValueUInt(alstr_get_cstr(device->DeviceName), NULL, "frequency", &freq);
2024 freq = maxu(freq, MIN_OUTPUT_RATE);
2026 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
2027 device->Frequency;
2028 /* SSE and Neon do best with the update size being a multiple of 4 */
2029 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2030 device->UpdateSize = (device->UpdateSize+3)&~3;
2032 device->Frequency = freq;
2034 if(numMono > INT_MAX-numStereo)
2035 numMono = INT_MAX-numStereo;
2036 numMono += numStereo;
2037 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono))
2039 if(numMono <= 0)
2040 numMono = 256;
2042 else
2043 numMono = maxi(numMono, 256);
2044 numStereo = mini(numStereo, numMono);
2045 numMono -= numStereo;
2046 device->SourcesMax = numMono + numStereo;
2048 device->NumMonoSources = numMono;
2049 device->NumStereoSources = numStereo;
2051 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2052 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2053 else
2054 new_sends = numSends;
2057 if((device->Flags&DEVICE_RUNNING))
2058 return ALC_NO_ERROR;
2060 al_free(device->Uhj_Encoder);
2061 device->Uhj_Encoder = NULL;
2063 al_free(device->Bs2b);
2064 device->Bs2b = NULL;
2066 al_free(device->ChannelDelay[0].Buffer);
2067 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2069 device->ChannelDelay[i].Length = 0;
2070 device->ChannelDelay[i].Buffer = NULL;
2073 al_free(device->Dry.Buffer);
2074 device->Dry.Buffer = NULL;
2075 device->Dry.NumChannels = 0;
2076 device->FOAOut.Buffer = NULL;
2077 device->FOAOut.NumChannels = 0;
2078 device->RealOut.Buffer = NULL;
2079 device->RealOut.NumChannels = 0;
2081 UpdateClockBase(device);
2083 /*************************************************************************
2084 * Update device format request if HRTF is requested
2086 device->HrtfStatus = ALC_HRTF_DISABLED_SOFT;
2087 if(device->Type != Loopback)
2089 const char *hrtf;
2090 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2092 if(strcasecmp(hrtf, "true") == 0)
2093 hrtf_userreq = Hrtf_Enable;
2094 else if(strcasecmp(hrtf, "false") == 0)
2095 hrtf_userreq = Hrtf_Disable;
2096 else if(strcasecmp(hrtf, "auto") != 0)
2097 ERR("Unexpected hrtf value: %s\n", hrtf);
2100 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2102 struct Hrtf *hrtf = NULL;
2103 if(VECTOR_SIZE(device->HrtfList) == 0)
2105 VECTOR_DEINIT(device->HrtfList);
2106 device->HrtfList = EnumerateHrtf(device->DeviceName);
2108 if(VECTOR_SIZE(device->HrtfList) > 0)
2110 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
2111 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
2112 else
2113 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
2116 if(hrtf)
2118 device->FmtChans = DevFmtStereo;
2119 device->Frequency = hrtf->sampleRate;
2120 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2121 if(device->HrtfHandle)
2122 Hrtf_DecRef(device->HrtfHandle);
2123 device->HrtfHandle = hrtf;
2125 else
2127 hrtf_userreq = Hrtf_Default;
2128 hrtf_appreq = Hrtf_Disable;
2129 device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2134 oldFreq = device->Frequency;
2135 oldChans = device->FmtChans;
2136 oldType = device->FmtType;
2138 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2139 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2140 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2141 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2142 device->UpdateSize, device->NumUpdates
2145 if(V0(device->Backend,reset)() == ALC_FALSE)
2146 return ALC_INVALID_DEVICE;
2148 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2150 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2151 DevFmtChannelsString(device->FmtChans));
2152 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2154 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2156 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2157 DevFmtTypeString(device->FmtType));
2158 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2160 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2162 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2163 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2166 if((device->UpdateSize&3) != 0)
2168 if((CPUCapFlags&CPU_CAP_SSE))
2169 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2170 if((CPUCapFlags&CPU_CAP_NEON))
2171 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2174 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2175 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2176 device->Frequency, device->UpdateSize, device->NumUpdates
2179 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2180 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2181 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2183 /* Allocate extra channels for any post-filter output. */
2184 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2185 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2187 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2188 device->Dry.Buffer = al_calloc(16, size);
2189 if(!device->Dry.Buffer)
2191 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2192 return ALC_INVALID_DEVICE;
2195 if(device->RealOut.NumChannels != 0)
2196 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2197 device->FOAOut.NumChannels;
2198 else
2200 device->RealOut.Buffer = device->Dry.Buffer;
2201 device->RealOut.NumChannels = device->Dry.NumChannels;
2204 if(device->FOAOut.NumChannels != 0)
2205 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2206 else
2208 device->FOAOut.Buffer = device->Dry.Buffer;
2209 device->FOAOut.NumChannels = device->Dry.NumChannels;
2212 device->NumAuxSends = new_sends;
2213 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2214 device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2215 device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2217 if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
2218 gainLimiter = val;
2219 if(gainLimiter)
2221 if(!device->Limiter)
2222 device->Limiter = alloc_limiter();
2224 else if(device->Limiter)
2226 al_free(device->Limiter);
2227 device->Limiter = NULL;
2230 /* Need to delay returning failure until replacement Send arrays have been
2231 * allocated with the appropriate size.
2233 update_failed = AL_FALSE;
2234 SetMixerFPUMode(&oldMode);
2235 if(device->DefaultSlot)
2237 ALeffectslot *slot = device->DefaultSlot;
2238 ALeffectState *state = slot->Effect.State;
2240 state->OutBuffer = device->Dry.Buffer;
2241 state->OutChannels = device->Dry.NumChannels;
2242 if(V(state,deviceUpdate)(device) == AL_FALSE)
2243 update_failed = AL_TRUE;
2244 else
2245 UpdateEffectSlotProps(slot);
2248 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2249 while(context)
2251 ALsizei pos;
2253 WriteLock(&context->PropLock);
2254 LockUIntMapRead(&context->EffectSlotMap);
2255 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2257 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2258 ALeffectState *state = slot->Effect.State;
2260 state->OutBuffer = device->Dry.Buffer;
2261 state->OutChannels = device->Dry.NumChannels;
2262 if(V(state,deviceUpdate)(device) == AL_FALSE)
2263 update_failed = AL_TRUE;
2264 else
2265 UpdateEffectSlotProps(slot);
2267 UnlockUIntMapRead(&context->EffectSlotMap);
2269 LockUIntMapRead(&context->SourceMap);
2270 RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax);
2271 for(pos = 0;pos < context->SourceMap.size;pos++)
2273 ALsource *source = context->SourceMap.values[pos];
2275 if(old_sends != device->NumAuxSends)
2277 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2278 ALsizei s;
2280 memcpy(sends, source->Send,
2281 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2283 for(s = device->NumAuxSends;s < old_sends;s++)
2285 if(source->Send[s].Slot)
2286 DecrementRef(&source->Send[s].Slot->ref);
2287 source->Send[s].Slot = NULL;
2289 al_free(source->Send);
2290 source->Send = sends;
2291 for(s = old_sends;s < device->NumAuxSends;s++)
2293 source->Send[s].Slot = NULL;
2294 source->Send[s].Gain = 1.0f;
2295 source->Send[s].GainHF = 1.0f;
2296 source->Send[s].HFReference = LOWPASSFREQREF;
2297 source->Send[s].GainLF = 1.0f;
2298 source->Send[s].LFReference = HIGHPASSFREQREF;
2302 ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
2304 AllocateVoices(context, context->MaxVoices, old_sends);
2305 for(pos = 0;pos < context->VoiceCount;pos++)
2307 ALvoice *voice = context->Voices[pos];
2308 struct ALvoiceProps *props;
2310 /* Clear any pre-existing voice property structs, in case the
2311 * number of auxiliary sends changed. Active sources will have
2312 * updates respecified in UpdateAllSourceProps.
2314 props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed);
2315 al_free(props);
2317 props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
2318 while(props)
2320 struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
2321 al_free(props);
2322 props = next;
2325 if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
2326 continue;
2328 if(device->AvgSpeakerDist > 0.0f)
2330 /* Reinitialize the NFC filters for new parameters. */
2331 ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
2332 (device->AvgSpeakerDist * device->Frequency);
2333 for(i = 0;i < voice->NumChannels;i++)
2335 NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1);
2336 NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1);
2337 NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1);
2341 UnlockUIntMapRead(&context->SourceMap);
2343 UpdateListenerProps(context);
2344 UpdateAllSourceProps(context);
2345 WriteUnlock(&context->PropLock);
2347 context = context->next;
2349 RestoreFPUMode(&oldMode);
2350 if(update_failed)
2351 return ALC_INVALID_DEVICE;
2353 if(!(device->Flags&DEVICE_PAUSED))
2355 if(V0(device->Backend,start)() == ALC_FALSE)
2356 return ALC_INVALID_DEVICE;
2357 device->Flags |= DEVICE_RUNNING;
2360 return ALC_NO_ERROR;
2363 /* FreeDevice
2365 * Frees the device structure, and destroys any objects the app failed to
2366 * delete. Called once there's no more references on the device.
2368 static ALCvoid FreeDevice(ALCdevice *device)
2370 ALsizei i;
2372 TRACE("%p\n", device);
2374 V0(device->Backend,close)();
2375 DELETE_OBJ(device->Backend);
2376 device->Backend = NULL;
2378 almtx_destroy(&device->BackendLock);
2380 if(device->DefaultSlot)
2382 DeinitEffectSlot(device->DefaultSlot);
2383 device->DefaultSlot = NULL;
2386 if(device->BufferMap.size > 0)
2388 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2389 (device->BufferMap.size==1)?"":"s");
2390 ReleaseALBuffers(device);
2392 ResetUIntMap(&device->BufferMap);
2394 if(device->EffectMap.size > 0)
2396 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2397 (device->EffectMap.size==1)?"":"s");
2398 ReleaseALEffects(device);
2400 ResetUIntMap(&device->EffectMap);
2402 if(device->FilterMap.size > 0)
2404 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2405 (device->FilterMap.size==1)?"":"s");
2406 ReleaseALFilters(device);
2408 ResetUIntMap(&device->FilterMap);
2410 AL_STRING_DEINIT(device->HrtfName);
2411 FreeHrtfList(&device->HrtfList);
2412 if(device->HrtfHandle)
2413 Hrtf_DecRef(device->HrtfHandle);
2414 device->HrtfHandle = NULL;
2415 al_free(device->Hrtf);
2416 device->Hrtf = NULL;
2418 al_free(device->Bs2b);
2419 device->Bs2b = NULL;
2421 al_free(device->Uhj_Encoder);
2422 device->Uhj_Encoder = NULL;
2424 bformatdec_free(device->AmbiDecoder);
2425 device->AmbiDecoder = NULL;
2427 ambiup_free(device->AmbiUp);
2428 device->AmbiUp = NULL;
2430 al_free(device->Limiter);
2431 device->Limiter = NULL;
2433 al_free(device->ChannelDelay[0].Buffer);
2434 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2436 device->ChannelDelay[i].Gain = 1.0f;
2437 device->ChannelDelay[i].Length = 0;
2438 device->ChannelDelay[i].Buffer = NULL;
2441 AL_STRING_DEINIT(device->DeviceName);
2443 al_free(device->Dry.Buffer);
2444 device->Dry.Buffer = NULL;
2445 device->Dry.NumChannels = 0;
2446 device->FOAOut.Buffer = NULL;
2447 device->FOAOut.NumChannels = 0;
2448 device->RealOut.Buffer = NULL;
2449 device->RealOut.NumChannels = 0;
2451 al_free(device);
2455 void ALCdevice_IncRef(ALCdevice *device)
2457 uint ref;
2458 ref = IncrementRef(&device->ref);
2459 TRACEREF("%p increasing refcount to %u\n", device, ref);
2462 void ALCdevice_DecRef(ALCdevice *device)
2464 uint ref;
2465 ref = DecrementRef(&device->ref);
2466 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2467 if(ref == 0) FreeDevice(device);
2470 /* VerifyDevice
2472 * Checks if the device handle is valid, and increments its ref count if so.
2474 static ALCboolean VerifyDevice(ALCdevice **device)
2476 ALCdevice *tmpDevice;
2478 LockLists();
2479 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2480 while(tmpDevice)
2482 if(tmpDevice == *device)
2484 ALCdevice_IncRef(tmpDevice);
2485 UnlockLists();
2486 return ALC_TRUE;
2488 tmpDevice = tmpDevice->next;
2490 UnlockLists();
2492 *device = NULL;
2493 return ALC_FALSE;
2497 /* InitContext
2499 * Initializes context fields
2501 static ALvoid InitContext(ALCcontext *Context)
2503 ALlistener *listener = Context->Listener;
2504 struct ALeffectslotArray *auxslots;
2506 //Initialise listener
2507 listener->Gain = 1.0f;
2508 listener->MetersPerUnit = 1.0f;
2509 listener->Position[0] = 0.0f;
2510 listener->Position[1] = 0.0f;
2511 listener->Position[2] = 0.0f;
2512 listener->Velocity[0] = 0.0f;
2513 listener->Velocity[1] = 0.0f;
2514 listener->Velocity[2] = 0.0f;
2515 listener->Forward[0] = 0.0f;
2516 listener->Forward[1] = 0.0f;
2517 listener->Forward[2] = -1.0f;
2518 listener->Up[0] = 0.0f;
2519 listener->Up[1] = 1.0f;
2520 listener->Up[2] = 0.0f;
2522 aluMatrixfSet(&listener->Params.Matrix,
2523 1.0f, 0.0f, 0.0f, 0.0f,
2524 0.0f, 1.0f, 0.0f, 0.0f,
2525 0.0f, 0.0f, 1.0f, 0.0f,
2526 0.0f, 0.0f, 0.0f, 1.0f
2528 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2529 listener->Params.Gain = 1.0f;
2530 listener->Params.MetersPerUnit = 1.0f;
2531 listener->Params.DopplerFactor = 1.0f;
2532 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2534 ATOMIC_INIT(&listener->Update, NULL);
2535 ATOMIC_INIT(&listener->FreeList, NULL);
2537 //Validate Context
2538 InitRef(&Context->UpdateCount, 0);
2539 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2540 Context->GainBoost = 1.0f;
2541 RWLockInit(&Context->PropLock);
2542 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2543 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2544 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2546 auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray));
2547 auxslots->count = 0;
2548 ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots);
2550 //Set globals
2551 Context->DistanceModel = DefaultDistanceModel;
2552 Context->SourceDistanceModel = AL_FALSE;
2553 Context->DopplerFactor = 1.0f;
2554 Context->DopplerVelocity = 1.0f;
2555 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2556 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2558 Context->ExtensionList = alExtList;
2562 /* FreeContext
2564 * Cleans up the context, and destroys any remaining objects the app failed to
2565 * delete. Called once there's no more references on the context.
2567 static void FreeContext(ALCcontext *context)
2569 ALlistener *listener = context->Listener;
2570 struct ALeffectslotArray *auxslots;
2571 struct ALlistenerProps *lprops;
2572 size_t count;
2573 ALsizei i;
2575 TRACE("%p\n", context);
2577 auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
2578 al_free(auxslots);
2580 if(context->SourceMap.size > 0)
2582 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2583 (context->SourceMap.size==1)?"":"s");
2584 ReleaseALSources(context);
2586 ResetUIntMap(&context->SourceMap);
2588 if(context->EffectSlotMap.size > 0)
2590 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2591 (context->EffectSlotMap.size==1)?"":"s");
2592 ReleaseALAuxiliaryEffectSlots(context);
2594 ResetUIntMap(&context->EffectSlotMap);
2596 for(i = 0;i < context->VoiceCount;i++)
2597 DeinitVoice(context->Voices[i]);
2598 al_free(context->Voices);
2599 context->Voices = NULL;
2600 context->VoiceCount = 0;
2601 context->MaxVoices = 0;
2603 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2605 TRACE("Freed unapplied listener update %p\n", lprops);
2606 al_free(lprops);
2608 count = 0;
2609 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
2610 while(lprops)
2612 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2613 al_free(lprops);
2614 lprops = next;
2615 ++count;
2617 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2619 ALCdevice_DecRef(context->Device);
2620 context->Device = NULL;
2622 //Invalidate context
2623 memset(context, 0, sizeof(ALCcontext));
2624 al_free(context);
2627 /* ReleaseContext
2629 * Removes the context reference from the given device and removes it from
2630 * being current on the running thread or globally. Returns true if other
2631 * contexts still exist on the device.
2633 static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
2635 ALCcontext *origctx, *newhead;
2636 bool ret = true;
2638 if(altss_get(LocalContext) == context)
2640 WARN("%p released while current on thread\n", context);
2641 altss_set(LocalContext, NULL);
2642 ALCcontext_DecRef(context);
2645 origctx = context;
2646 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
2647 ALCcontext_DecRef(context);
2649 ALCdevice_Lock(device);
2650 origctx = context;
2651 newhead = context->next;
2652 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
2654 ALCcontext *volatile*list = &origctx->next;
2655 while(*list)
2657 if(*list == context)
2659 *list = (*list)->next;
2660 break;
2662 list = &(*list)->next;
2665 else
2666 ret = !!newhead;
2667 ALCdevice_Unlock(device);
2669 ALCcontext_DecRef(context);
2670 return ret;
2673 void ALCcontext_IncRef(ALCcontext *context)
2675 uint ref = IncrementRef(&context->ref);
2676 TRACEREF("%p increasing refcount to %u\n", context, ref);
2679 void ALCcontext_DecRef(ALCcontext *context)
2681 uint ref = DecrementRef(&context->ref);
2682 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2683 if(ref == 0) FreeContext(context);
2686 static void ReleaseThreadCtx(void *ptr)
2688 ALCcontext *context = ptr;
2689 uint ref = DecrementRef(&context->ref);
2690 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2691 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2694 /* VerifyContext
2696 * Checks that the given context is valid, and increments its reference count.
2698 static ALCboolean VerifyContext(ALCcontext **context)
2700 ALCdevice *dev;
2702 LockLists();
2703 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2704 while(dev)
2706 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2707 while(ctx)
2709 if(ctx == *context)
2711 ALCcontext_IncRef(ctx);
2712 UnlockLists();
2713 return ALC_TRUE;
2715 ctx = ctx->next;
2717 dev = dev->next;
2719 UnlockLists();
2721 *context = NULL;
2722 return ALC_FALSE;
2726 /* GetContextRef
2728 * Returns the currently active context for this thread, and adds a reference
2729 * without locking it.
2731 ALCcontext *GetContextRef(void)
2733 ALCcontext *context;
2735 context = altss_get(LocalContext);
2736 if(context)
2737 ALCcontext_IncRef(context);
2738 else
2740 LockLists();
2741 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2742 if(context)
2743 ALCcontext_IncRef(context);
2744 UnlockLists();
2747 return context;
2751 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2753 ALCdevice *device = context->Device;
2754 ALsizei num_sends = device->NumAuxSends;
2755 struct ALvoiceProps *props;
2756 size_t sizeof_props;
2757 size_t sizeof_voice;
2758 ALvoice **voices;
2759 ALvoice *voice;
2760 ALsizei v = 0;
2761 size_t size;
2763 if(num_voices == context->MaxVoices && num_sends == old_sends)
2764 return;
2766 /* Allocate the voice pointers, voices, and the voices' stored source
2767 * property set (including the dynamically-sized Send[] array) in one
2768 * chunk.
2770 sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
2771 sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
2772 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2774 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2775 /* The voice and property objects are stored interleaved since they're
2776 * paired together.
2778 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2779 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2781 if(context->Voices)
2783 const ALsizei v_count = mini(context->VoiceCount, num_voices);
2784 const ALsizei s_count = mini(old_sends, num_sends);
2786 for(;v < v_count;v++)
2788 ALvoice *old_voice = context->Voices[v];
2789 ALsizei i;
2791 /* Copy the old voice data and source property set to the new
2792 * storage.
2794 *voice = *old_voice;
2795 for(i = 0;i < s_count;i++)
2796 voice->Send[i] = old_voice->Send[i];
2797 *props = *(old_voice->Props);
2798 for(i = 0;i < s_count;i++)
2799 props->Send[i] = old_voice->Props->Send[i];
2801 /* Set this voice's property set pointer and voice reference. */
2802 voice->Props = props;
2803 voices[v] = voice;
2805 /* Increment pointers to the next storage space. */
2806 voice = (ALvoice*)((char*)props + sizeof_props);
2807 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2809 /* Deinit any left over voices that weren't copied over to the new
2810 * array. NOTE: If this does anything, v equals num_voices and
2811 * num_voices is less than VoiceCount, so the following loop won't do
2812 * anything.
2814 for(;v < context->VoiceCount;v++)
2815 DeinitVoice(context->Voices[v]);
2817 /* Finish setting the voices' property set pointers and references. */
2818 for(;v < num_voices;v++)
2820 ATOMIC_INIT(&voice->Update, NULL);
2821 ATOMIC_INIT(&voice->FreeList, NULL);
2823 voice->Props = props;
2824 voices[v] = voice;
2826 voice = (ALvoice*)((char*)props + sizeof_props);
2827 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2830 al_free(context->Voices);
2831 context->Voices = voices;
2832 context->MaxVoices = num_voices;
2833 context->VoiceCount = mini(context->VoiceCount, num_voices);
2837 /************************************************
2838 * Standard ALC functions
2839 ************************************************/
2841 /* alcGetError
2843 * Return last ALC generated error code for the given device
2845 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2847 ALCenum errorCode;
2849 if(VerifyDevice(&device))
2851 errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
2852 ALCdevice_DecRef(device);
2854 else
2855 errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
2857 return errorCode;
2861 /* alcSuspendContext
2863 * Suspends updates for the given context
2865 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2867 if(!SuspendDefers)
2868 return;
2870 if(!VerifyContext(&context))
2871 alcSetError(NULL, ALC_INVALID_CONTEXT);
2872 else
2874 ALCcontext_DeferUpdates(context);
2875 ALCcontext_DecRef(context);
2879 /* alcProcessContext
2881 * Resumes processing updates for the given context
2883 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2885 if(!SuspendDefers)
2886 return;
2888 if(!VerifyContext(&context))
2889 alcSetError(NULL, ALC_INVALID_CONTEXT);
2890 else
2892 ALCcontext_ProcessUpdates(context);
2893 ALCcontext_DecRef(context);
2898 /* alcGetString
2900 * Returns information about the device, and error strings
2902 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2904 const ALCchar *value = NULL;
2906 switch(param)
2908 case ALC_NO_ERROR:
2909 value = alcNoError;
2910 break;
2912 case ALC_INVALID_ENUM:
2913 value = alcErrInvalidEnum;
2914 break;
2916 case ALC_INVALID_VALUE:
2917 value = alcErrInvalidValue;
2918 break;
2920 case ALC_INVALID_DEVICE:
2921 value = alcErrInvalidDevice;
2922 break;
2924 case ALC_INVALID_CONTEXT:
2925 value = alcErrInvalidContext;
2926 break;
2928 case ALC_OUT_OF_MEMORY:
2929 value = alcErrOutOfMemory;
2930 break;
2932 case ALC_DEVICE_SPECIFIER:
2933 value = alcDefaultName;
2934 break;
2936 case ALC_ALL_DEVICES_SPECIFIER:
2937 if(VerifyDevice(&Device))
2939 value = alstr_get_cstr(Device->DeviceName);
2940 ALCdevice_DecRef(Device);
2942 else
2944 ProbeAllDevicesList();
2945 value = alstr_get_cstr(alcAllDevicesList);
2947 break;
2949 case ALC_CAPTURE_DEVICE_SPECIFIER:
2950 if(VerifyDevice(&Device))
2952 value = alstr_get_cstr(Device->DeviceName);
2953 ALCdevice_DecRef(Device);
2955 else
2957 ProbeCaptureDeviceList();
2958 value = alstr_get_cstr(alcCaptureDeviceList);
2960 break;
2962 /* Default devices are always first in the list */
2963 case ALC_DEFAULT_DEVICE_SPECIFIER:
2964 value = alcDefaultName;
2965 break;
2967 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2968 if(alstr_empty(alcAllDevicesList))
2969 ProbeAllDevicesList();
2971 VerifyDevice(&Device);
2973 free(alcDefaultAllDevicesSpecifier);
2974 alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
2975 if(!alcDefaultAllDevicesSpecifier)
2976 alcSetError(Device, ALC_OUT_OF_MEMORY);
2978 value = alcDefaultAllDevicesSpecifier;
2979 if(Device) ALCdevice_DecRef(Device);
2980 break;
2982 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2983 if(alstr_empty(alcCaptureDeviceList))
2984 ProbeCaptureDeviceList();
2986 VerifyDevice(&Device);
2988 free(alcCaptureDefaultDeviceSpecifier);
2989 alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
2990 if(!alcCaptureDefaultDeviceSpecifier)
2991 alcSetError(Device, ALC_OUT_OF_MEMORY);
2993 value = alcCaptureDefaultDeviceSpecifier;
2994 if(Device) ALCdevice_DecRef(Device);
2995 break;
2997 case ALC_EXTENSIONS:
2998 if(!VerifyDevice(&Device))
2999 value = alcNoDeviceExtList;
3000 else
3002 value = alcExtensionList;
3003 ALCdevice_DecRef(Device);
3005 break;
3007 case ALC_HRTF_SPECIFIER_SOFT:
3008 if(!VerifyDevice(&Device))
3009 alcSetError(NULL, ALC_INVALID_DEVICE);
3010 else
3012 almtx_lock(&Device->BackendLock);
3013 value = (Device->HrtfHandle ? alstr_get_cstr(Device->HrtfName) : "");
3014 almtx_unlock(&Device->BackendLock);
3015 ALCdevice_DecRef(Device);
3017 break;
3019 default:
3020 VerifyDevice(&Device);
3021 alcSetError(Device, ALC_INVALID_ENUM);
3022 if(Device) ALCdevice_DecRef(Device);
3023 break;
3026 return value;
3030 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
3032 if(device->Type == Loopback && device->FmtChans == DevFmtAmbi3D)
3033 return 25;
3034 return 19;
3037 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3039 ALCsizei i;
3041 if(size <= 0 || values == NULL)
3043 alcSetError(device, ALC_INVALID_VALUE);
3044 return 0;
3047 if(!device)
3049 switch(param)
3051 case ALC_MAJOR_VERSION:
3052 values[0] = alcMajorVersion;
3053 return 1;
3054 case ALC_MINOR_VERSION:
3055 values[0] = alcMinorVersion;
3056 return 1;
3058 case ALC_ATTRIBUTES_SIZE:
3059 case ALC_ALL_ATTRIBUTES:
3060 case ALC_FREQUENCY:
3061 case ALC_REFRESH:
3062 case ALC_SYNC:
3063 case ALC_MONO_SOURCES:
3064 case ALC_STEREO_SOURCES:
3065 case ALC_CAPTURE_SAMPLES:
3066 case ALC_FORMAT_CHANNELS_SOFT:
3067 case ALC_FORMAT_TYPE_SOFT:
3068 case ALC_AMBISONIC_LAYOUT_SOFT:
3069 case ALC_AMBISONIC_SCALING_SOFT:
3070 case ALC_AMBISONIC_ORDER_SOFT:
3071 alcSetError(NULL, ALC_INVALID_DEVICE);
3072 return 0;
3074 default:
3075 alcSetError(NULL, ALC_INVALID_ENUM);
3076 return 0;
3078 return 0;
3081 if(device->Type == Capture)
3083 switch(param)
3085 case ALC_CAPTURE_SAMPLES:
3086 almtx_lock(&device->BackendLock);
3087 values[0] = V0(device->Backend,availableSamples)();
3088 almtx_unlock(&device->BackendLock);
3089 return 1;
3091 case ALC_CONNECTED:
3092 values[0] = device->Connected;
3093 return 1;
3095 default:
3096 alcSetError(device, ALC_INVALID_ENUM);
3097 return 0;
3099 return 0;
3102 /* render device */
3103 switch(param)
3105 case ALC_MAJOR_VERSION:
3106 values[0] = alcMajorVersion;
3107 return 1;
3109 case ALC_MINOR_VERSION:
3110 values[0] = alcMinorVersion;
3111 return 1;
3113 case ALC_EFX_MAJOR_VERSION:
3114 values[0] = alcEFXMajorVersion;
3115 return 1;
3117 case ALC_EFX_MINOR_VERSION:
3118 values[0] = alcEFXMinorVersion;
3119 return 1;
3121 case ALC_ATTRIBUTES_SIZE:
3122 values[0] = NumAttrsForDevice(device);
3123 return 1;
3125 case ALC_ALL_ATTRIBUTES:
3126 if(size < NumAttrsForDevice(device))
3128 alcSetError(device, ALC_INVALID_VALUE);
3129 return 0;
3132 i = 0;
3133 almtx_lock(&device->BackendLock);
3134 values[i++] = ALC_FREQUENCY;
3135 values[i++] = device->Frequency;
3137 if(device->Type != Loopback)
3139 values[i++] = ALC_REFRESH;
3140 values[i++] = device->Frequency / device->UpdateSize;
3142 values[i++] = ALC_SYNC;
3143 values[i++] = ALC_FALSE;
3145 else
3147 if(device->FmtChans == DevFmtAmbi3D)
3149 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3150 values[i++] = device->AmbiLayout;
3152 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3153 values[i++] = device->AmbiScale;
3155 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3156 values[i++] = device->AmbiOrder;
3159 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3160 values[i++] = device->FmtChans;
3162 values[i++] = ALC_FORMAT_TYPE_SOFT;
3163 values[i++] = device->FmtType;
3166 values[i++] = ALC_MONO_SOURCES;
3167 values[i++] = device->NumMonoSources;
3169 values[i++] = ALC_STEREO_SOURCES;
3170 values[i++] = device->NumStereoSources;
3172 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3173 values[i++] = device->NumAuxSends;
3175 values[i++] = ALC_HRTF_SOFT;
3176 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3178 values[i++] = ALC_HRTF_STATUS_SOFT;
3179 values[i++] = device->HrtfStatus;
3181 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3182 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3183 almtx_unlock(&device->BackendLock);
3185 values[i++] = 0;
3186 return i;
3188 case ALC_FREQUENCY:
3189 values[0] = device->Frequency;
3190 return 1;
3192 case ALC_REFRESH:
3193 if(device->Type == Loopback)
3195 alcSetError(device, ALC_INVALID_DEVICE);
3196 return 0;
3198 almtx_lock(&device->BackendLock);
3199 values[0] = device->Frequency / device->UpdateSize;
3200 almtx_unlock(&device->BackendLock);
3201 return 1;
3203 case ALC_SYNC:
3204 if(device->Type == Loopback)
3206 alcSetError(device, ALC_INVALID_DEVICE);
3207 return 0;
3209 values[0] = ALC_FALSE;
3210 return 1;
3212 case ALC_FORMAT_CHANNELS_SOFT:
3213 if(device->Type != Loopback)
3215 alcSetError(device, ALC_INVALID_DEVICE);
3216 return 0;
3218 values[0] = device->FmtChans;
3219 return 1;
3221 case ALC_FORMAT_TYPE_SOFT:
3222 if(device->Type != Loopback)
3224 alcSetError(device, ALC_INVALID_DEVICE);
3225 return 0;
3227 values[0] = device->FmtType;
3228 return 1;
3230 case ALC_AMBISONIC_LAYOUT_SOFT:
3231 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3233 alcSetError(device, ALC_INVALID_DEVICE);
3234 return 0;
3236 values[0] = device->AmbiLayout;
3237 return 1;
3239 case ALC_AMBISONIC_SCALING_SOFT:
3240 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3242 alcSetError(device, ALC_INVALID_DEVICE);
3243 return 0;
3245 values[0] = device->AmbiScale;
3246 return 1;
3248 case ALC_AMBISONIC_ORDER_SOFT:
3249 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3251 alcSetError(device, ALC_INVALID_DEVICE);
3252 return 0;
3254 values[0] = device->AmbiOrder;
3255 return 1;
3257 case ALC_MONO_SOURCES:
3258 values[0] = device->NumMonoSources;
3259 return 1;
3261 case ALC_STEREO_SOURCES:
3262 values[0] = device->NumStereoSources;
3263 return 1;
3265 case ALC_MAX_AUXILIARY_SENDS:
3266 values[0] = device->NumAuxSends;
3267 return 1;
3269 case ALC_CONNECTED:
3270 values[0] = device->Connected;
3271 return 1;
3273 case ALC_HRTF_SOFT:
3274 values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3275 return 1;
3277 case ALC_HRTF_STATUS_SOFT:
3278 values[0] = device->HrtfStatus;
3279 return 1;
3281 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3282 almtx_lock(&device->BackendLock);
3283 FreeHrtfList(&device->HrtfList);
3284 device->HrtfList = EnumerateHrtf(device->DeviceName);
3285 values[0] = (ALCint)VECTOR_SIZE(device->HrtfList);
3286 almtx_unlock(&device->BackendLock);
3287 return 1;
3289 case ALC_OUTPUT_LIMITER_SOFT:
3290 values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3291 return 1;
3293 default:
3294 alcSetError(device, ALC_INVALID_ENUM);
3295 return 0;
3297 return 0;
3300 /* alcGetIntegerv
3302 * Returns information about the device and the version of OpenAL
3304 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3306 VerifyDevice(&device);
3307 if(size <= 0 || values == NULL)
3308 alcSetError(device, ALC_INVALID_VALUE);
3309 else
3310 GetIntegerv(device, param, size, values);
3311 if(device) ALCdevice_DecRef(device);
3314 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3316 ALCint *ivals;
3317 ALsizei i;
3319 VerifyDevice(&device);
3320 if(size <= 0 || values == NULL)
3321 alcSetError(device, ALC_INVALID_VALUE);
3322 else if(!device || device->Type == Capture)
3324 ivals = malloc(size * sizeof(ALCint));
3325 size = GetIntegerv(device, pname, size, ivals);
3326 for(i = 0;i < size;i++)
3327 values[i] = ivals[i];
3328 free(ivals);
3330 else /* render device */
3332 ClockLatency clock;
3333 ALuint64 basecount;
3334 ALuint samplecount;
3335 ALuint refcount;
3337 switch(pname)
3339 case ALC_ATTRIBUTES_SIZE:
3340 *values = NumAttrsForDevice(device)+4;
3341 break;
3343 case ALC_ALL_ATTRIBUTES:
3344 if(size < NumAttrsForDevice(device)+4)
3345 alcSetError(device, ALC_INVALID_VALUE);
3346 else
3348 i = 0;
3349 almtx_lock(&device->BackendLock);
3350 values[i++] = ALC_FREQUENCY;
3351 values[i++] = device->Frequency;
3353 if(device->Type != Loopback)
3355 values[i++] = ALC_REFRESH;
3356 values[i++] = device->Frequency / device->UpdateSize;
3358 values[i++] = ALC_SYNC;
3359 values[i++] = ALC_FALSE;
3361 else
3363 if(device->FmtChans == DevFmtAmbi3D)
3365 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3366 values[i++] = device->AmbiLayout;
3368 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3369 values[i++] = device->AmbiScale;
3371 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3372 values[i++] = device->AmbiOrder;
3375 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3376 values[i++] = device->FmtChans;
3378 values[i++] = ALC_FORMAT_TYPE_SOFT;
3379 values[i++] = device->FmtType;
3382 values[i++] = ALC_MONO_SOURCES;
3383 values[i++] = device->NumMonoSources;
3385 values[i++] = ALC_STEREO_SOURCES;
3386 values[i++] = device->NumStereoSources;
3388 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3389 values[i++] = device->NumAuxSends;
3391 values[i++] = ALC_HRTF_SOFT;
3392 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3394 values[i++] = ALC_HRTF_STATUS_SOFT;
3395 values[i++] = device->HrtfStatus;
3397 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3398 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3400 clock = V0(device->Backend,getClockLatency)();
3401 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3402 values[i++] = clock.ClockTime;
3404 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3405 values[i++] = clock.Latency;
3406 almtx_unlock(&device->BackendLock);
3408 values[i++] = 0;
3410 break;
3412 case ALC_DEVICE_CLOCK_SOFT:
3413 almtx_lock(&device->BackendLock);
3414 do {
3415 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3416 althrd_yield();
3417 basecount = device->ClockBase;
3418 samplecount = device->SamplesDone;
3419 } while(refcount != ReadRef(&device->MixCount));
3420 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3421 almtx_unlock(&device->BackendLock);
3422 break;
3424 case ALC_DEVICE_LATENCY_SOFT:
3425 almtx_lock(&device->BackendLock);
3426 clock = V0(device->Backend,getClockLatency)();
3427 almtx_unlock(&device->BackendLock);
3428 *values = clock.Latency;
3429 break;
3431 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3432 if(size < 2)
3433 alcSetError(device, ALC_INVALID_VALUE);
3434 else
3436 almtx_lock(&device->BackendLock);
3437 clock = V0(device->Backend,getClockLatency)();
3438 almtx_unlock(&device->BackendLock);
3439 values[0] = clock.ClockTime;
3440 values[1] = clock.Latency;
3442 break;
3444 default:
3445 ivals = malloc(size * sizeof(ALCint));
3446 size = GetIntegerv(device, pname, size, ivals);
3447 for(i = 0;i < size;i++)
3448 values[i] = ivals[i];
3449 free(ivals);
3450 break;
3453 if(device)
3454 ALCdevice_DecRef(device);
3458 /* alcIsExtensionPresent
3460 * Determines if there is support for a particular extension
3462 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3464 ALCboolean bResult = ALC_FALSE;
3466 VerifyDevice(&device);
3468 if(!extName)
3469 alcSetError(device, ALC_INVALID_VALUE);
3470 else
3472 size_t len = strlen(extName);
3473 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3474 while(ptr && *ptr)
3476 if(strncasecmp(ptr, extName, len) == 0 &&
3477 (ptr[len] == '\0' || isspace(ptr[len])))
3479 bResult = ALC_TRUE;
3480 break;
3482 if((ptr=strchr(ptr, ' ')) != NULL)
3484 do {
3485 ++ptr;
3486 } while(isspace(*ptr));
3490 if(device)
3491 ALCdevice_DecRef(device);
3492 return bResult;
3496 /* alcGetProcAddress
3498 * Retrieves the function address for a particular extension function
3500 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3502 ALCvoid *ptr = NULL;
3504 if(!funcName)
3506 VerifyDevice(&device);
3507 alcSetError(device, ALC_INVALID_VALUE);
3508 if(device) ALCdevice_DecRef(device);
3510 else
3512 size_t i = 0;
3513 for(i = 0;i < COUNTOF(alcFunctions);i++)
3515 if(strcmp(alcFunctions[i].funcName, funcName) == 0)
3517 ptr = alcFunctions[i].address;
3518 break;
3523 return ptr;
3527 /* alcGetEnumValue
3529 * Get the value for a particular ALC enumeration name
3531 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3533 ALCenum val = 0;
3535 if(!enumName)
3537 VerifyDevice(&device);
3538 alcSetError(device, ALC_INVALID_VALUE);
3539 if(device) ALCdevice_DecRef(device);
3541 else
3543 size_t i = 0;
3544 for(i = 0;i < COUNTOF(alcEnumerations);i++)
3546 if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
3548 val = alcEnumerations[i].value;
3549 break;
3554 return val;
3558 /* alcCreateContext
3560 * Create and attach a context to the given device.
3562 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3564 ALCcontext *ALContext;
3565 ALfloat valf;
3566 ALCenum err;
3568 /* Explicitly hold the list lock while taking the BackendLock in case the
3569 * device is asynchronously destropyed, to ensure this new context is
3570 * properly cleaned up after being made.
3572 LockLists();
3573 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3575 UnlockLists();
3576 alcSetError(device, ALC_INVALID_DEVICE);
3577 if(device) ALCdevice_DecRef(device);
3578 return NULL;
3580 almtx_lock(&device->BackendLock);
3581 UnlockLists();
3583 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3585 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3586 if(!ALContext)
3588 almtx_unlock(&device->BackendLock);
3590 alcSetError(device, ALC_OUT_OF_MEMORY);
3591 ALCdevice_DecRef(device);
3592 return NULL;
3595 InitRef(&ALContext->ref, 1);
3596 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3598 ALContext->Voices = NULL;
3599 ALContext->VoiceCount = 0;
3600 ALContext->MaxVoices = 0;
3601 ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL);
3602 ALContext->Device = device;
3604 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3606 almtx_unlock(&device->BackendLock);
3608 al_free(ALContext->Voices);
3609 ALContext->Voices = NULL;
3611 al_free(ALContext);
3612 ALContext = NULL;
3614 alcSetError(device, err);
3615 if(err == ALC_INVALID_DEVICE)
3617 V0(device->Backend,lock)();
3618 aluHandleDisconnect(device);
3619 V0(device->Backend,unlock)();
3621 ALCdevice_DecRef(device);
3622 return NULL;
3624 AllocateVoices(ALContext, 256, device->NumAuxSends);
3626 ALCdevice_IncRef(ALContext->Device);
3627 InitContext(ALContext);
3629 if(ConfigValueFloat(alstr_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3631 if(!isfinite(valf))
3632 ERR("volume-adjust must be finite: %f\n", valf);
3633 else
3635 ALfloat db = clampf(valf, -24.0f, 24.0f);
3636 if(db != valf)
3637 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3638 ALContext->GainBoost = powf(10.0f, db/20.0f);
3639 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3642 UpdateListenerProps(ALContext);
3645 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3646 do {
3647 ALContext->next = head;
3648 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
3649 ALContext) == 0);
3651 almtx_unlock(&device->BackendLock);
3653 ALCdevice_DecRef(device);
3655 TRACE("Created context %p\n", ALContext);
3656 return ALContext;
3659 /* alcDestroyContext
3661 * Remove a context from its device
3663 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3665 ALCdevice *Device;
3667 LockLists();
3668 if(!VerifyContext(&context))
3670 UnlockLists();
3671 alcSetError(NULL, ALC_INVALID_CONTEXT);
3672 return;
3675 Device = context->Device;
3676 if(Device)
3678 almtx_lock(&Device->BackendLock);
3679 if(!ReleaseContext(context, Device))
3681 V0(Device->Backend,stop)();
3682 Device->Flags &= ~DEVICE_RUNNING;
3684 almtx_unlock(&Device->BackendLock);
3686 UnlockLists();
3688 ALCcontext_DecRef(context);
3692 /* alcGetCurrentContext
3694 * Returns the currently active context on the calling thread
3696 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3698 ALCcontext *Context = altss_get(LocalContext);
3699 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3700 return Context;
3703 /* alcGetThreadContext
3705 * Returns the currently active thread-local context
3707 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3709 return altss_get(LocalContext);
3713 /* alcMakeContextCurrent
3715 * Makes the given context the active process-wide context, and removes the
3716 * thread-local context for the calling thread.
3718 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3720 /* context must be valid or NULL */
3721 if(context && !VerifyContext(&context))
3723 alcSetError(NULL, ALC_INVALID_CONTEXT);
3724 return ALC_FALSE;
3726 /* context's reference count is already incremented */
3727 context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
3728 if(context) ALCcontext_DecRef(context);
3730 if((context=altss_get(LocalContext)) != NULL)
3732 altss_set(LocalContext, NULL);
3733 ALCcontext_DecRef(context);
3736 return ALC_TRUE;
3739 /* alcSetThreadContext
3741 * Makes the given context the active context for the current thread
3743 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3745 ALCcontext *old;
3747 /* context must be valid or NULL */
3748 if(context && !VerifyContext(&context))
3750 alcSetError(NULL, ALC_INVALID_CONTEXT);
3751 return ALC_FALSE;
3753 /* context's reference count is already incremented */
3754 old = altss_get(LocalContext);
3755 altss_set(LocalContext, context);
3756 if(old) ALCcontext_DecRef(old);
3758 return ALC_TRUE;
3762 /* alcGetContextsDevice
3764 * Returns the device that a particular context is attached to
3766 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3768 ALCdevice *Device;
3770 if(!VerifyContext(&Context))
3772 alcSetError(NULL, ALC_INVALID_CONTEXT);
3773 return NULL;
3775 Device = Context->Device;
3776 ALCcontext_DecRef(Context);
3778 return Device;
3782 /* alcOpenDevice
3784 * Opens the named device.
3786 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3788 const ALCchar *fmt;
3789 ALCdevice *device;
3790 ALCenum err;
3791 ALCsizei i;
3793 DO_INITCONFIG();
3795 if(!PlaybackBackend.name)
3797 alcSetError(NULL, ALC_INVALID_VALUE);
3798 return NULL;
3801 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3802 #ifdef _WIN32
3803 /* Some old Windows apps hardcode these expecting OpenAL to use a
3804 * specific audio API, even when they're not enumerated. Creative's
3805 * router effectively ignores them too.
3807 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3808 || strcasecmp(deviceName, "MMSYSTEM") == 0
3809 #endif
3811 deviceName = NULL;
3813 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3814 if(!device)
3816 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3817 return NULL;
3820 //Validate device
3821 InitRef(&device->ref, 1);
3822 device->Connected = ALC_TRUE;
3823 device->Type = Playback;
3824 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3826 device->Flags = 0;
3827 device->Bs2b = NULL;
3828 device->Uhj_Encoder = NULL;
3829 device->Hrtf = NULL;
3830 device->HrtfHandle = NULL;
3831 VECTOR_INIT(device->HrtfList);
3832 AL_STRING_INIT(device->HrtfName);
3833 device->Render_Mode = NormalRender;
3834 AL_STRING_INIT(device->DeviceName);
3835 device->Dry.Buffer = NULL;
3836 device->Dry.NumChannels = 0;
3837 device->FOAOut.Buffer = NULL;
3838 device->FOAOut.NumChannels = 0;
3839 device->RealOut.Buffer = NULL;
3840 device->RealOut.NumChannels = 0;
3841 device->Limiter = alloc_limiter();
3842 device->AvgSpeakerDist = 0.0f;
3844 ATOMIC_INIT(&device->ContextList, NULL);
3846 device->ClockBase = 0;
3847 device->SamplesDone = 0;
3849 device->SourcesMax = 256;
3850 device->AuxiliaryEffectSlotMax = 64;
3851 device->NumAuxSends = DEFAULT_SENDS;
3853 InitUIntMap(&device->BufferMap, INT_MAX);
3854 InitUIntMap(&device->EffectMap, INT_MAX);
3855 InitUIntMap(&device->FilterMap, INT_MAX);
3857 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3859 device->ChannelDelay[i].Gain = 1.0f;
3860 device->ChannelDelay[i].Length = 0;
3861 device->ChannelDelay[i].Buffer = NULL;
3864 //Set output format
3865 device->FmtChans = DevFmtChannelsDefault;
3866 device->FmtType = DevFmtTypeDefault;
3867 device->Frequency = DEFAULT_OUTPUT_RATE;
3868 device->IsHeadphones = AL_FALSE;
3869 device->AmbiLayout = AmbiLayout_Default;
3870 device->AmbiScale = AmbiNorm_Default;
3871 device->NumUpdates = 3;
3872 device->UpdateSize = 1024;
3874 if(!PlaybackBackend.getFactory)
3875 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3876 ALCbackend_Playback);
3877 else
3879 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3880 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3882 if(!device->Backend)
3884 al_free(device);
3885 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3886 return NULL;
3890 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3892 static const struct {
3893 const char name[16];
3894 enum DevFmtChannels chans;
3895 ALsizei order;
3896 } chanlist[] = {
3897 { "mono", DevFmtMono, 0 },
3898 { "stereo", DevFmtStereo, 0 },
3899 { "quad", DevFmtQuad, 0 },
3900 { "surround51", DevFmtX51, 0 },
3901 { "surround61", DevFmtX61, 0 },
3902 { "surround71", DevFmtX71, 0 },
3903 { "surround51rear", DevFmtX51Rear, 0 },
3904 { "ambi1", DevFmtAmbi3D, 1 },
3905 { "ambi2", DevFmtAmbi3D, 2 },
3906 { "ambi3", DevFmtAmbi3D, 3 },
3908 size_t i;
3910 for(i = 0;i < COUNTOF(chanlist);i++)
3912 if(strcasecmp(chanlist[i].name, fmt) == 0)
3914 device->FmtChans = chanlist[i].chans;
3915 device->AmbiOrder = chanlist[i].order;
3916 device->Flags |= DEVICE_CHANNELS_REQUEST;
3917 break;
3920 if(i == COUNTOF(chanlist))
3921 ERR("Unsupported channels: %s\n", fmt);
3923 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3925 static const struct {
3926 const char name[16];
3927 enum DevFmtType type;
3928 } typelist[] = {
3929 { "int8", DevFmtByte },
3930 { "uint8", DevFmtUByte },
3931 { "int16", DevFmtShort },
3932 { "uint16", DevFmtUShort },
3933 { "int32", DevFmtInt },
3934 { "uint32", DevFmtUInt },
3935 { "float32", DevFmtFloat },
3937 size_t i;
3939 for(i = 0;i < COUNTOF(typelist);i++)
3941 if(strcasecmp(typelist[i].name, fmt) == 0)
3943 device->FmtType = typelist[i].type;
3944 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3945 break;
3948 if(i == COUNTOF(typelist))
3949 ERR("Unsupported sample-type: %s\n", fmt);
3952 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3954 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3955 if(device->Frequency < MIN_OUTPUT_RATE)
3956 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3957 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3960 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3961 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3963 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3964 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3965 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3966 device->UpdateSize = (device->UpdateSize+3)&~3;
3968 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
3969 if(device->SourcesMax == 0) device->SourcesMax = 256;
3971 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3972 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
3974 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
3975 device->NumAuxSends = clampi(
3976 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
3979 device->NumStereoSources = 1;
3980 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
3982 // Find a playback device to open
3983 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3985 DELETE_OBJ(device->Backend);
3986 al_free(device);
3987 alcSetError(NULL, err);
3988 return NULL;
3990 almtx_init(&device->BackendLock, almtx_plain);
3992 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
3994 if(strcasecmp(fmt, "fuma") == 0)
3996 device->AmbiLayout = AmbiLayout_FuMa;
3997 device->AmbiScale = AmbiNorm_FuMa;
3999 else if(strcasecmp(fmt, "acn+sn3d") == 0)
4001 device->AmbiLayout = AmbiLayout_ACN;
4002 device->AmbiScale = AmbiNorm_SN3D;
4004 else if(strcasecmp(fmt, "acn+n3d") == 0)
4006 device->AmbiLayout = AmbiLayout_ACN;
4007 device->AmbiScale = AmbiNorm_N3D;
4009 else
4010 ERR("Unsupported ambi-format: %s\n", fmt);
4013 if(DefaultEffect.type != AL_EFFECT_NULL)
4015 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
4016 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
4018 device->DefaultSlot = NULL;
4019 ERR("Failed to initialize the default effect slot\n");
4021 else
4023 aluInitEffectPanning(device->DefaultSlot);
4024 if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
4026 DeinitEffectSlot(device->DefaultSlot);
4027 device->DefaultSlot = NULL;
4028 ERR("Failed to initialize the default effect\n");
4034 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4035 do {
4036 device->next = head;
4037 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4040 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4041 return device;
4044 /* alcCloseDevice
4046 * Closes the given device.
4048 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
4050 ALCdevice *iter, *origdev;
4051 ALCcontext *ctx;
4053 LockLists();
4054 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4055 do {
4056 if(iter == device)
4057 break;
4058 } while((iter=iter->next) != NULL);
4059 if(!iter || iter->Type == Capture)
4061 alcSetError(iter, ALC_INVALID_DEVICE);
4062 UnlockLists();
4063 return ALC_FALSE;
4065 almtx_lock(&device->BackendLock);
4067 origdev = device;
4068 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4070 ALCdevice *volatile*list = &origdev->next;
4071 while(*list)
4073 if(*list == device)
4075 *list = (*list)->next;
4076 break;
4078 list = &(*list)->next;
4081 UnlockLists();
4083 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
4084 while(ctx != NULL)
4086 ALCcontext *next = ctx->next;
4087 WARN("Releasing context %p\n", ctx);
4088 ReleaseContext(ctx, device);
4089 ctx = next;
4091 if((device->Flags&DEVICE_RUNNING))
4092 V0(device->Backend,stop)();
4093 device->Flags &= ~DEVICE_RUNNING;
4094 almtx_unlock(&device->BackendLock);
4096 ALCdevice_DecRef(device);
4098 return ALC_TRUE;
4102 /************************************************
4103 * ALC capture functions
4104 ************************************************/
4105 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4107 ALCdevice *device = NULL;
4108 ALCenum err;
4109 ALCsizei i;
4111 DO_INITCONFIG();
4113 if(!CaptureBackend.name)
4115 alcSetError(NULL, ALC_INVALID_VALUE);
4116 return NULL;
4119 if(samples <= 0)
4121 alcSetError(NULL, ALC_INVALID_VALUE);
4122 return NULL;
4125 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4126 deviceName = NULL;
4128 device = al_calloc(16, sizeof(ALCdevice));
4129 if(!device)
4131 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4132 return NULL;
4135 //Validate device
4136 InitRef(&device->ref, 1);
4137 device->Connected = ALC_TRUE;
4138 device->Type = Capture;
4140 device->Hrtf = NULL;
4141 device->HrtfHandle = NULL;
4142 VECTOR_INIT(device->HrtfList);
4143 AL_STRING_INIT(device->HrtfName);
4145 AL_STRING_INIT(device->DeviceName);
4146 device->Dry.Buffer = NULL;
4147 device->Dry.NumChannels = 0;
4148 device->FOAOut.Buffer = NULL;
4149 device->FOAOut.NumChannels = 0;
4150 device->RealOut.Buffer = NULL;
4151 device->RealOut.NumChannels = 0;
4153 InitUIntMap(&device->BufferMap, INT_MAX);
4154 InitUIntMap(&device->EffectMap, INT_MAX);
4155 InitUIntMap(&device->FilterMap, INT_MAX);
4157 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4159 device->ChannelDelay[i].Gain = 1.0f;
4160 device->ChannelDelay[i].Length = 0;
4161 device->ChannelDelay[i].Buffer = NULL;
4164 if(!CaptureBackend.getFactory)
4165 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
4166 ALCbackend_Capture);
4167 else
4169 ALCbackendFactory *factory = CaptureBackend.getFactory();
4170 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4172 if(!device->Backend)
4174 al_free(device);
4175 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4176 return NULL;
4179 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4180 device->Frequency = frequency;
4182 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4183 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4185 al_free(device);
4186 alcSetError(NULL, ALC_INVALID_ENUM);
4187 return NULL;
4189 device->IsHeadphones = AL_FALSE;
4190 device->AmbiOrder = 0;
4191 device->AmbiLayout = AmbiLayout_Default;
4192 device->AmbiScale = AmbiNorm_Default;
4194 device->UpdateSize = samples;
4195 device->NumUpdates = 1;
4197 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4198 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
4199 device->Frequency, device->UpdateSize, device->NumUpdates
4201 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4203 al_free(device);
4204 alcSetError(NULL, err);
4205 return NULL;
4207 almtx_init(&device->BackendLock, almtx_plain);
4210 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4211 do {
4212 device->next = head;
4213 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4216 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4217 return device;
4220 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4222 ALCdevice *iter, *origdev;
4224 LockLists();
4225 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4226 do {
4227 if(iter == device)
4228 break;
4229 } while((iter=iter->next) != NULL);
4230 if(!iter || iter->Type != Capture)
4232 alcSetError(iter, ALC_INVALID_DEVICE);
4233 UnlockLists();
4234 return ALC_FALSE;
4237 origdev = device;
4238 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4240 ALCdevice *volatile*list = &origdev->next;
4241 while(*list)
4243 if(*list == device)
4245 *list = (*list)->next;
4246 break;
4248 list = &(*list)->next;
4251 UnlockLists();
4253 ALCdevice_DecRef(device);
4255 return ALC_TRUE;
4258 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4260 if(!VerifyDevice(&device) || device->Type != Capture)
4261 alcSetError(device, ALC_INVALID_DEVICE);
4262 else
4264 almtx_lock(&device->BackendLock);
4265 if(!device->Connected)
4266 alcSetError(device, ALC_INVALID_DEVICE);
4267 else if(!(device->Flags&DEVICE_RUNNING))
4269 if(V0(device->Backend,start)())
4270 device->Flags |= DEVICE_RUNNING;
4271 else
4273 aluHandleDisconnect(device);
4274 alcSetError(device, ALC_INVALID_DEVICE);
4277 almtx_unlock(&device->BackendLock);
4280 if(device) ALCdevice_DecRef(device);
4283 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4285 if(!VerifyDevice(&device) || device->Type != Capture)
4286 alcSetError(device, ALC_INVALID_DEVICE);
4287 else
4289 almtx_lock(&device->BackendLock);
4290 if((device->Flags&DEVICE_RUNNING))
4291 V0(device->Backend,stop)();
4292 device->Flags &= ~DEVICE_RUNNING;
4293 almtx_unlock(&device->BackendLock);
4296 if(device) ALCdevice_DecRef(device);
4299 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4301 if(!VerifyDevice(&device) || device->Type != Capture)
4302 alcSetError(device, ALC_INVALID_DEVICE);
4303 else
4305 ALCenum err = ALC_INVALID_VALUE;
4307 almtx_lock(&device->BackendLock);
4308 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4309 err = V(device->Backend,captureSamples)(buffer, samples);
4310 almtx_unlock(&device->BackendLock);
4312 if(err != ALC_NO_ERROR)
4313 alcSetError(device, err);
4315 if(device) ALCdevice_DecRef(device);
4319 /************************************************
4320 * ALC loopback functions
4321 ************************************************/
4323 /* alcLoopbackOpenDeviceSOFT
4325 * Open a loopback device, for manual rendering.
4327 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4329 ALCbackendFactory *factory;
4330 ALCdevice *device;
4331 ALCsizei i;
4333 DO_INITCONFIG();
4335 /* Make sure the device name, if specified, is us. */
4336 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4338 alcSetError(NULL, ALC_INVALID_VALUE);
4339 return NULL;
4342 device = al_calloc(16, sizeof(ALCdevice));
4343 if(!device)
4345 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4346 return NULL;
4349 //Validate device
4350 InitRef(&device->ref, 1);
4351 device->Connected = ALC_TRUE;
4352 device->Type = Loopback;
4353 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4355 device->Flags = 0;
4356 device->Hrtf = NULL;
4357 device->HrtfHandle = NULL;
4358 VECTOR_INIT(device->HrtfList);
4359 AL_STRING_INIT(device->HrtfName);
4360 device->Bs2b = NULL;
4361 device->Uhj_Encoder = NULL;
4362 device->Render_Mode = NormalRender;
4363 AL_STRING_INIT(device->DeviceName);
4364 device->Dry.Buffer = NULL;
4365 device->Dry.NumChannels = 0;
4366 device->FOAOut.Buffer = NULL;
4367 device->FOAOut.NumChannels = 0;
4368 device->RealOut.Buffer = NULL;
4369 device->RealOut.NumChannels = 0;
4370 device->Limiter = alloc_limiter();
4371 device->AvgSpeakerDist = 0.0f;
4373 ATOMIC_INIT(&device->ContextList, NULL);
4375 device->ClockBase = 0;
4376 device->SamplesDone = 0;
4378 device->SourcesMax = 256;
4379 device->AuxiliaryEffectSlotMax = 64;
4380 device->NumAuxSends = DEFAULT_SENDS;
4382 InitUIntMap(&device->BufferMap, INT_MAX);
4383 InitUIntMap(&device->EffectMap, INT_MAX);
4384 InitUIntMap(&device->FilterMap, INT_MAX);
4386 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4388 device->ChannelDelay[i].Gain = 1.0f;
4389 device->ChannelDelay[i].Length = 0;
4390 device->ChannelDelay[i].Buffer = NULL;
4393 factory = ALCloopbackFactory_getFactory();
4394 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4395 if(!device->Backend)
4397 al_free(device);
4398 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4399 return NULL;
4401 almtx_init(&device->BackendLock, almtx_plain);
4403 //Set output format
4404 device->NumUpdates = 0;
4405 device->UpdateSize = 0;
4407 device->Frequency = DEFAULT_OUTPUT_RATE;
4408 device->FmtChans = DevFmtChannelsDefault;
4409 device->FmtType = DevFmtTypeDefault;
4410 device->IsHeadphones = AL_FALSE;
4411 device->AmbiLayout = AmbiLayout_Default;
4412 device->AmbiScale = AmbiNorm_Default;
4414 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4415 if(device->SourcesMax == 0) device->SourcesMax = 256;
4417 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4418 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4420 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4421 device->NumAuxSends = clampi(
4422 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4425 device->NumStereoSources = 1;
4426 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4428 // Open the "backend"
4429 V(device->Backend,open)("Loopback");
4432 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4433 do {
4434 device->next = head;
4435 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4438 TRACE("Created device %p\n", device);
4439 return device;
4442 /* alcIsRenderFormatSupportedSOFT
4444 * Determines if the loopback device supports the given format for rendering.
4446 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4448 ALCboolean ret = ALC_FALSE;
4450 if(!VerifyDevice(&device) || device->Type != Loopback)
4451 alcSetError(device, ALC_INVALID_DEVICE);
4452 else if(freq <= 0)
4453 alcSetError(device, ALC_INVALID_VALUE);
4454 else
4456 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4457 ret = ALC_TRUE;
4459 if(device) ALCdevice_DecRef(device);
4461 return ret;
4464 /* alcRenderSamplesSOFT
4466 * Renders some samples into a buffer, using the format last set by the
4467 * attributes given to alcCreateContext.
4469 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4471 if(!VerifyDevice(&device) || device->Type != Loopback)
4472 alcSetError(device, ALC_INVALID_DEVICE);
4473 else if(samples < 0 || (samples > 0 && buffer == NULL))
4474 alcSetError(device, ALC_INVALID_VALUE);
4475 else
4477 V0(device->Backend,lock)();
4478 aluMixData(device, buffer, samples);
4479 V0(device->Backend,unlock)();
4481 if(device) ALCdevice_DecRef(device);
4485 /************************************************
4486 * ALC loopback2 functions
4487 ************************************************/
4489 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4491 ALCboolean ret = ALC_FALSE;
4493 if(!VerifyDevice(&device) || device->Type != Loopback)
4494 alcSetError(device, ALC_INVALID_DEVICE);
4495 else if(order <= 0)
4496 alcSetError(device, ALC_INVALID_VALUE);
4497 else
4499 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4500 ret = ALC_TRUE;
4502 if(device) ALCdevice_DecRef(device);
4504 return ret;
4507 /************************************************
4508 * ALC DSP pause/resume functions
4509 ************************************************/
4511 /* alcDevicePauseSOFT
4513 * Pause the DSP to stop audio processing.
4515 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4517 if(!VerifyDevice(&device) || device->Type != Playback)
4518 alcSetError(device, ALC_INVALID_DEVICE);
4519 else
4521 almtx_lock(&device->BackendLock);
4522 if((device->Flags&DEVICE_RUNNING))
4523 V0(device->Backend,stop)();
4524 device->Flags &= ~DEVICE_RUNNING;
4525 device->Flags |= DEVICE_PAUSED;
4526 almtx_unlock(&device->BackendLock);
4528 if(device) ALCdevice_DecRef(device);
4531 /* alcDeviceResumeSOFT
4533 * Resume the DSP to restart audio processing.
4535 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4537 if(!VerifyDevice(&device) || device->Type != Playback)
4538 alcSetError(device, ALC_INVALID_DEVICE);
4539 else
4541 almtx_lock(&device->BackendLock);
4542 if((device->Flags&DEVICE_PAUSED))
4544 device->Flags &= ~DEVICE_PAUSED;
4545 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4547 if(V0(device->Backend,start)() != ALC_FALSE)
4548 device->Flags |= DEVICE_RUNNING;
4549 else
4551 alcSetError(device, ALC_INVALID_DEVICE);
4552 V0(device->Backend,lock)();
4553 aluHandleDisconnect(device);
4554 V0(device->Backend,unlock)();
4558 almtx_unlock(&device->BackendLock);
4560 if(device) ALCdevice_DecRef(device);
4564 /************************************************
4565 * ALC HRTF functions
4566 ************************************************/
4568 /* alcGetStringiSOFT
4570 * Gets a string parameter at the given index.
4572 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4574 const ALCchar *str = NULL;
4576 if(!VerifyDevice(&device) || device->Type == Capture)
4577 alcSetError(device, ALC_INVALID_DEVICE);
4578 else switch(paramName)
4580 case ALC_HRTF_SPECIFIER_SOFT:
4581 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList))
4582 str = alstr_get_cstr(VECTOR_ELEM(device->HrtfList, index).name);
4583 else
4584 alcSetError(device, ALC_INVALID_VALUE);
4585 break;
4587 default:
4588 alcSetError(device, ALC_INVALID_ENUM);
4589 break;
4591 if(device) ALCdevice_DecRef(device);
4593 return str;
4596 /* alcResetDeviceSOFT
4598 * Resets the given device output, using the specified attribute list.
4600 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4602 ALCenum err;
4604 LockLists();
4605 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4607 UnlockLists();
4608 alcSetError(device, ALC_INVALID_DEVICE);
4609 if(device) ALCdevice_DecRef(device);
4610 return ALC_FALSE;
4612 almtx_lock(&device->BackendLock);
4613 UnlockLists();
4615 err = UpdateDeviceParams(device, attribs);
4616 almtx_unlock(&device->BackendLock);
4618 if(err != ALC_NO_ERROR)
4620 alcSetError(device, err);
4621 if(err == ALC_INVALID_DEVICE)
4623 V0(device->Backend,lock)();
4624 aluHandleDisconnect(device);
4625 V0(device->Backend,unlock)();
4627 ALCdevice_DecRef(device);
4628 return ALC_FALSE;
4630 ALCdevice_DecRef(device);
4632 return ALC_TRUE;