Use sqrtf for single-precision square roots
[openal-soft.git] / Alc / ALc.c
blob8983025a7acbfc0ef2fe1ce8a10ed7611d2146a7
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);
59 static struct BackendInfo BackendList[] = {
60 #ifdef HAVE_JACK
61 { "jack", ALCjackBackendFactory_getFactory },
62 #endif
63 #ifdef HAVE_PULSEAUDIO
64 { "pulse", ALCpulseBackendFactory_getFactory },
65 #endif
66 #ifdef HAVE_ALSA
67 { "alsa", ALCalsaBackendFactory_getFactory },
68 #endif
69 #ifdef HAVE_COREAUDIO
70 { "core", ALCcoreAudioBackendFactory_getFactory },
71 #endif
72 #ifdef HAVE_OSS
73 { "oss", ALCossBackendFactory_getFactory },
74 #endif
75 #ifdef HAVE_SOLARIS
76 { "solaris", ALCsolarisBackendFactory_getFactory },
77 #endif
78 #ifdef HAVE_SNDIO
79 { "sndio", ALCsndioBackendFactory_getFactory },
80 #endif
81 #ifdef HAVE_QSA
82 { "qsa", ALCqsaBackendFactory_getFactory },
83 #endif
84 #ifdef HAVE_MMDEVAPI
85 { "mmdevapi", ALCmmdevBackendFactory_getFactory },
86 #endif
87 #ifdef HAVE_DSOUND
88 { "dsound", ALCdsoundBackendFactory_getFactory },
89 #endif
90 #ifdef HAVE_WINMM
91 { "winmm", ALCwinmmBackendFactory_getFactory },
92 #endif
93 #ifdef HAVE_PORTAUDIO
94 { "port", ALCportBackendFactory_getFactory },
95 #endif
96 #ifdef HAVE_OPENSL
97 { "opensl", ALCopenslBackendFactory_getFactory },
98 #endif
100 { "null", ALCnullBackendFactory_getFactory },
101 #ifdef HAVE_WAVE
102 { "wave", ALCwaveBackendFactory_getFactory },
103 #endif
105 static ALsizei BackendListSize = COUNTOF(BackendList);
106 #undef EmptyFuncs
108 static struct BackendInfo PlaybackBackend;
109 static struct BackendInfo CaptureBackend;
112 /************************************************
113 * Functions, enums, and errors
114 ************************************************/
115 #define DECL(x) { #x, (ALCvoid*)(x) }
116 static const struct {
117 const ALCchar *funcName;
118 ALCvoid *address;
119 } alcFunctions[] = {
120 DECL(alcCreateContext),
121 DECL(alcMakeContextCurrent),
122 DECL(alcProcessContext),
123 DECL(alcSuspendContext),
124 DECL(alcDestroyContext),
125 DECL(alcGetCurrentContext),
126 DECL(alcGetContextsDevice),
127 DECL(alcOpenDevice),
128 DECL(alcCloseDevice),
129 DECL(alcGetError),
130 DECL(alcIsExtensionPresent),
131 DECL(alcGetProcAddress),
132 DECL(alcGetEnumValue),
133 DECL(alcGetString),
134 DECL(alcGetIntegerv),
135 DECL(alcCaptureOpenDevice),
136 DECL(alcCaptureCloseDevice),
137 DECL(alcCaptureStart),
138 DECL(alcCaptureStop),
139 DECL(alcCaptureSamples),
141 DECL(alcSetThreadContext),
142 DECL(alcGetThreadContext),
144 DECL(alcLoopbackOpenDeviceSOFT),
145 DECL(alcIsRenderFormatSupportedSOFT),
146 DECL(alcRenderSamplesSOFT),
148 DECL(alcIsAmbisonicFormatSupportedSOFT),
150 DECL(alcDevicePauseSOFT),
151 DECL(alcDeviceResumeSOFT),
153 DECL(alcGetStringiSOFT),
154 DECL(alcResetDeviceSOFT),
156 DECL(alcGetInteger64vSOFT),
158 DECL(alEnable),
159 DECL(alDisable),
160 DECL(alIsEnabled),
161 DECL(alGetString),
162 DECL(alGetBooleanv),
163 DECL(alGetIntegerv),
164 DECL(alGetFloatv),
165 DECL(alGetDoublev),
166 DECL(alGetBoolean),
167 DECL(alGetInteger),
168 DECL(alGetFloat),
169 DECL(alGetDouble),
170 DECL(alGetError),
171 DECL(alIsExtensionPresent),
172 DECL(alGetProcAddress),
173 DECL(alGetEnumValue),
174 DECL(alListenerf),
175 DECL(alListener3f),
176 DECL(alListenerfv),
177 DECL(alListeneri),
178 DECL(alListener3i),
179 DECL(alListeneriv),
180 DECL(alGetListenerf),
181 DECL(alGetListener3f),
182 DECL(alGetListenerfv),
183 DECL(alGetListeneri),
184 DECL(alGetListener3i),
185 DECL(alGetListeneriv),
186 DECL(alGenSources),
187 DECL(alDeleteSources),
188 DECL(alIsSource),
189 DECL(alSourcef),
190 DECL(alSource3f),
191 DECL(alSourcefv),
192 DECL(alSourcei),
193 DECL(alSource3i),
194 DECL(alSourceiv),
195 DECL(alGetSourcef),
196 DECL(alGetSource3f),
197 DECL(alGetSourcefv),
198 DECL(alGetSourcei),
199 DECL(alGetSource3i),
200 DECL(alGetSourceiv),
201 DECL(alSourcePlayv),
202 DECL(alSourceStopv),
203 DECL(alSourceRewindv),
204 DECL(alSourcePausev),
205 DECL(alSourcePlay),
206 DECL(alSourceStop),
207 DECL(alSourceRewind),
208 DECL(alSourcePause),
209 DECL(alSourceQueueBuffers),
210 DECL(alSourceUnqueueBuffers),
211 DECL(alGenBuffers),
212 DECL(alDeleteBuffers),
213 DECL(alIsBuffer),
214 DECL(alBufferData),
215 DECL(alBufferf),
216 DECL(alBuffer3f),
217 DECL(alBufferfv),
218 DECL(alBufferi),
219 DECL(alBuffer3i),
220 DECL(alBufferiv),
221 DECL(alGetBufferf),
222 DECL(alGetBuffer3f),
223 DECL(alGetBufferfv),
224 DECL(alGetBufferi),
225 DECL(alGetBuffer3i),
226 DECL(alGetBufferiv),
227 DECL(alDopplerFactor),
228 DECL(alDopplerVelocity),
229 DECL(alSpeedOfSound),
230 DECL(alDistanceModel),
232 DECL(alGenFilters),
233 DECL(alDeleteFilters),
234 DECL(alIsFilter),
235 DECL(alFilteri),
236 DECL(alFilteriv),
237 DECL(alFilterf),
238 DECL(alFilterfv),
239 DECL(alGetFilteri),
240 DECL(alGetFilteriv),
241 DECL(alGetFilterf),
242 DECL(alGetFilterfv),
243 DECL(alGenEffects),
244 DECL(alDeleteEffects),
245 DECL(alIsEffect),
246 DECL(alEffecti),
247 DECL(alEffectiv),
248 DECL(alEffectf),
249 DECL(alEffectfv),
250 DECL(alGetEffecti),
251 DECL(alGetEffectiv),
252 DECL(alGetEffectf),
253 DECL(alGetEffectfv),
254 DECL(alGenAuxiliaryEffectSlots),
255 DECL(alDeleteAuxiliaryEffectSlots),
256 DECL(alIsAuxiliaryEffectSlot),
257 DECL(alAuxiliaryEffectSloti),
258 DECL(alAuxiliaryEffectSlotiv),
259 DECL(alAuxiliaryEffectSlotf),
260 DECL(alAuxiliaryEffectSlotfv),
261 DECL(alGetAuxiliaryEffectSloti),
262 DECL(alGetAuxiliaryEffectSlotiv),
263 DECL(alGetAuxiliaryEffectSlotf),
264 DECL(alGetAuxiliaryEffectSlotfv),
266 DECL(alDeferUpdatesSOFT),
267 DECL(alProcessUpdatesSOFT),
269 DECL(alSourcedSOFT),
270 DECL(alSource3dSOFT),
271 DECL(alSourcedvSOFT),
272 DECL(alGetSourcedSOFT),
273 DECL(alGetSource3dSOFT),
274 DECL(alGetSourcedvSOFT),
275 DECL(alSourcei64SOFT),
276 DECL(alSource3i64SOFT),
277 DECL(alSourcei64vSOFT),
278 DECL(alGetSourcei64SOFT),
279 DECL(alGetSource3i64SOFT),
280 DECL(alGetSourcei64vSOFT),
282 DECL(alBufferSamplesSOFT),
283 DECL(alGetBufferSamplesSOFT),
284 DECL(alIsBufferFormatSupportedSOFT),
286 DECL(alGetStringiSOFT),
288 #undef DECL
290 #define DECL(x) { #x, (x) }
291 static const struct {
292 const ALCchar *enumName;
293 ALCenum value;
294 } alcEnumerations[] = {
295 DECL(ALC_INVALID),
296 DECL(ALC_FALSE),
297 DECL(ALC_TRUE),
299 DECL(ALC_MAJOR_VERSION),
300 DECL(ALC_MINOR_VERSION),
301 DECL(ALC_ATTRIBUTES_SIZE),
302 DECL(ALC_ALL_ATTRIBUTES),
303 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
304 DECL(ALC_DEVICE_SPECIFIER),
305 DECL(ALC_ALL_DEVICES_SPECIFIER),
306 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
307 DECL(ALC_EXTENSIONS),
308 DECL(ALC_FREQUENCY),
309 DECL(ALC_REFRESH),
310 DECL(ALC_SYNC),
311 DECL(ALC_MONO_SOURCES),
312 DECL(ALC_STEREO_SOURCES),
313 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
314 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
315 DECL(ALC_CAPTURE_SAMPLES),
316 DECL(ALC_CONNECTED),
318 DECL(ALC_EFX_MAJOR_VERSION),
319 DECL(ALC_EFX_MINOR_VERSION),
320 DECL(ALC_MAX_AUXILIARY_SENDS),
322 DECL(ALC_FORMAT_CHANNELS_SOFT),
323 DECL(ALC_FORMAT_TYPE_SOFT),
325 DECL(ALC_MONO_SOFT),
326 DECL(ALC_STEREO_SOFT),
327 DECL(ALC_QUAD_SOFT),
328 DECL(ALC_5POINT1_SOFT),
329 DECL(ALC_6POINT1_SOFT),
330 DECL(ALC_7POINT1_SOFT),
331 DECL(ALC_BFORMAT3D_SOFT),
333 DECL(ALC_BYTE_SOFT),
334 DECL(ALC_UNSIGNED_BYTE_SOFT),
335 DECL(ALC_SHORT_SOFT),
336 DECL(ALC_UNSIGNED_SHORT_SOFT),
337 DECL(ALC_INT_SOFT),
338 DECL(ALC_UNSIGNED_INT_SOFT),
339 DECL(ALC_FLOAT_SOFT),
341 DECL(ALC_HRTF_SOFT),
342 DECL(ALC_DONT_CARE_SOFT),
343 DECL(ALC_HRTF_STATUS_SOFT),
344 DECL(ALC_HRTF_DISABLED_SOFT),
345 DECL(ALC_HRTF_ENABLED_SOFT),
346 DECL(ALC_HRTF_DENIED_SOFT),
347 DECL(ALC_HRTF_REQUIRED_SOFT),
348 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
349 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
350 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
351 DECL(ALC_HRTF_SPECIFIER_SOFT),
352 DECL(ALC_HRTF_ID_SOFT),
354 DECL(ALC_AMBISONIC_LAYOUT_SOFT),
355 DECL(ALC_AMBISONIC_SCALING_SOFT),
356 DECL(ALC_AMBISONIC_ORDER_SOFT),
357 DECL(ALC_ACN_SOFT),
358 DECL(ALC_FUMA_SOFT),
359 DECL(ALC_N3D_SOFT),
360 DECL(ALC_SN3D_SOFT),
362 DECL(ALC_OUTPUT_LIMITER_SOFT),
364 DECL(ALC_NO_ERROR),
365 DECL(ALC_INVALID_DEVICE),
366 DECL(ALC_INVALID_CONTEXT),
367 DECL(ALC_INVALID_ENUM),
368 DECL(ALC_INVALID_VALUE),
369 DECL(ALC_OUT_OF_MEMORY),
372 DECL(AL_INVALID),
373 DECL(AL_NONE),
374 DECL(AL_FALSE),
375 DECL(AL_TRUE),
377 DECL(AL_SOURCE_RELATIVE),
378 DECL(AL_CONE_INNER_ANGLE),
379 DECL(AL_CONE_OUTER_ANGLE),
380 DECL(AL_PITCH),
381 DECL(AL_POSITION),
382 DECL(AL_DIRECTION),
383 DECL(AL_VELOCITY),
384 DECL(AL_LOOPING),
385 DECL(AL_BUFFER),
386 DECL(AL_GAIN),
387 DECL(AL_MIN_GAIN),
388 DECL(AL_MAX_GAIN),
389 DECL(AL_ORIENTATION),
390 DECL(AL_REFERENCE_DISTANCE),
391 DECL(AL_ROLLOFF_FACTOR),
392 DECL(AL_CONE_OUTER_GAIN),
393 DECL(AL_MAX_DISTANCE),
394 DECL(AL_SEC_OFFSET),
395 DECL(AL_SAMPLE_OFFSET),
396 DECL(AL_BYTE_OFFSET),
397 DECL(AL_SOURCE_TYPE),
398 DECL(AL_STATIC),
399 DECL(AL_STREAMING),
400 DECL(AL_UNDETERMINED),
401 DECL(AL_METERS_PER_UNIT),
402 DECL(AL_LOOP_POINTS_SOFT),
403 DECL(AL_DIRECT_CHANNELS_SOFT),
405 DECL(AL_DIRECT_FILTER),
406 DECL(AL_AUXILIARY_SEND_FILTER),
407 DECL(AL_AIR_ABSORPTION_FACTOR),
408 DECL(AL_ROOM_ROLLOFF_FACTOR),
409 DECL(AL_CONE_OUTER_GAINHF),
410 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
412 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
414 DECL(AL_SOURCE_STATE),
415 DECL(AL_INITIAL),
416 DECL(AL_PLAYING),
417 DECL(AL_PAUSED),
418 DECL(AL_STOPPED),
420 DECL(AL_BUFFERS_QUEUED),
421 DECL(AL_BUFFERS_PROCESSED),
423 DECL(AL_FORMAT_MONO8),
424 DECL(AL_FORMAT_MONO16),
425 DECL(AL_FORMAT_MONO_FLOAT32),
426 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
427 DECL(AL_FORMAT_STEREO8),
428 DECL(AL_FORMAT_STEREO16),
429 DECL(AL_FORMAT_STEREO_FLOAT32),
430 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
431 DECL(AL_FORMAT_MONO_IMA4),
432 DECL(AL_FORMAT_STEREO_IMA4),
433 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
434 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
435 DECL(AL_FORMAT_QUAD8_LOKI),
436 DECL(AL_FORMAT_QUAD16_LOKI),
437 DECL(AL_FORMAT_QUAD8),
438 DECL(AL_FORMAT_QUAD16),
439 DECL(AL_FORMAT_QUAD32),
440 DECL(AL_FORMAT_51CHN8),
441 DECL(AL_FORMAT_51CHN16),
442 DECL(AL_FORMAT_51CHN32),
443 DECL(AL_FORMAT_61CHN8),
444 DECL(AL_FORMAT_61CHN16),
445 DECL(AL_FORMAT_61CHN32),
446 DECL(AL_FORMAT_71CHN8),
447 DECL(AL_FORMAT_71CHN16),
448 DECL(AL_FORMAT_71CHN32),
449 DECL(AL_FORMAT_REAR8),
450 DECL(AL_FORMAT_REAR16),
451 DECL(AL_FORMAT_REAR32),
452 DECL(AL_FORMAT_MONO_MULAW),
453 DECL(AL_FORMAT_MONO_MULAW_EXT),
454 DECL(AL_FORMAT_STEREO_MULAW),
455 DECL(AL_FORMAT_STEREO_MULAW_EXT),
456 DECL(AL_FORMAT_QUAD_MULAW),
457 DECL(AL_FORMAT_51CHN_MULAW),
458 DECL(AL_FORMAT_61CHN_MULAW),
459 DECL(AL_FORMAT_71CHN_MULAW),
460 DECL(AL_FORMAT_REAR_MULAW),
461 DECL(AL_FORMAT_MONO_ALAW_EXT),
462 DECL(AL_FORMAT_STEREO_ALAW_EXT),
464 DECL(AL_FORMAT_BFORMAT2D_8),
465 DECL(AL_FORMAT_BFORMAT2D_16),
466 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
467 DECL(AL_FORMAT_BFORMAT2D_MULAW),
468 DECL(AL_FORMAT_BFORMAT3D_8),
469 DECL(AL_FORMAT_BFORMAT3D_16),
470 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
471 DECL(AL_FORMAT_BFORMAT3D_MULAW),
473 DECL(AL_MONO8_SOFT),
474 DECL(AL_MONO16_SOFT),
475 DECL(AL_MONO32F_SOFT),
476 DECL(AL_STEREO8_SOFT),
477 DECL(AL_STEREO16_SOFT),
478 DECL(AL_STEREO32F_SOFT),
479 DECL(AL_QUAD8_SOFT),
480 DECL(AL_QUAD16_SOFT),
481 DECL(AL_QUAD32F_SOFT),
482 DECL(AL_REAR8_SOFT),
483 DECL(AL_REAR16_SOFT),
484 DECL(AL_REAR32F_SOFT),
485 DECL(AL_5POINT1_8_SOFT),
486 DECL(AL_5POINT1_16_SOFT),
487 DECL(AL_5POINT1_32F_SOFT),
488 DECL(AL_6POINT1_8_SOFT),
489 DECL(AL_6POINT1_16_SOFT),
490 DECL(AL_6POINT1_32F_SOFT),
491 DECL(AL_7POINT1_8_SOFT),
492 DECL(AL_7POINT1_16_SOFT),
493 DECL(AL_7POINT1_32F_SOFT),
494 DECL(AL_BFORMAT2D_8_SOFT),
495 DECL(AL_BFORMAT2D_16_SOFT),
496 DECL(AL_BFORMAT2D_32F_SOFT),
497 DECL(AL_BFORMAT3D_8_SOFT),
498 DECL(AL_BFORMAT3D_16_SOFT),
499 DECL(AL_BFORMAT3D_32F_SOFT),
501 DECL(AL_MONO_SOFT),
502 DECL(AL_STEREO_SOFT),
503 DECL(AL_QUAD_SOFT),
504 DECL(AL_REAR_SOFT),
505 DECL(AL_5POINT1_SOFT),
506 DECL(AL_6POINT1_SOFT),
507 DECL(AL_7POINT1_SOFT),
508 DECL(AL_BFORMAT2D_SOFT),
509 DECL(AL_BFORMAT3D_SOFT),
511 DECL(AL_BYTE_SOFT),
512 DECL(AL_UNSIGNED_BYTE_SOFT),
513 DECL(AL_SHORT_SOFT),
514 DECL(AL_UNSIGNED_SHORT_SOFT),
515 DECL(AL_INT_SOFT),
516 DECL(AL_UNSIGNED_INT_SOFT),
517 DECL(AL_FLOAT_SOFT),
518 DECL(AL_DOUBLE_SOFT),
519 DECL(AL_BYTE3_SOFT),
520 DECL(AL_UNSIGNED_BYTE3_SOFT),
521 DECL(AL_MULAW_SOFT),
523 DECL(AL_FREQUENCY),
524 DECL(AL_BITS),
525 DECL(AL_CHANNELS),
526 DECL(AL_SIZE),
527 DECL(AL_INTERNAL_FORMAT_SOFT),
528 DECL(AL_BYTE_LENGTH_SOFT),
529 DECL(AL_SAMPLE_LENGTH_SOFT),
530 DECL(AL_SEC_LENGTH_SOFT),
531 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
532 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
534 DECL(AL_SOURCE_RADIUS),
536 DECL(AL_STEREO_ANGLES),
538 DECL(AL_UNUSED),
539 DECL(AL_PENDING),
540 DECL(AL_PROCESSED),
542 DECL(AL_NO_ERROR),
543 DECL(AL_INVALID_NAME),
544 DECL(AL_INVALID_ENUM),
545 DECL(AL_INVALID_VALUE),
546 DECL(AL_INVALID_OPERATION),
547 DECL(AL_OUT_OF_MEMORY),
549 DECL(AL_VENDOR),
550 DECL(AL_VERSION),
551 DECL(AL_RENDERER),
552 DECL(AL_EXTENSIONS),
554 DECL(AL_DOPPLER_FACTOR),
555 DECL(AL_DOPPLER_VELOCITY),
556 DECL(AL_DISTANCE_MODEL),
557 DECL(AL_SPEED_OF_SOUND),
558 DECL(AL_SOURCE_DISTANCE_MODEL),
559 DECL(AL_DEFERRED_UPDATES_SOFT),
560 DECL(AL_GAIN_LIMIT_SOFT),
562 DECL(AL_INVERSE_DISTANCE),
563 DECL(AL_INVERSE_DISTANCE_CLAMPED),
564 DECL(AL_LINEAR_DISTANCE),
565 DECL(AL_LINEAR_DISTANCE_CLAMPED),
566 DECL(AL_EXPONENT_DISTANCE),
567 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
569 DECL(AL_FILTER_TYPE),
570 DECL(AL_FILTER_NULL),
571 DECL(AL_FILTER_LOWPASS),
572 DECL(AL_FILTER_HIGHPASS),
573 DECL(AL_FILTER_BANDPASS),
575 DECL(AL_LOWPASS_GAIN),
576 DECL(AL_LOWPASS_GAINHF),
578 DECL(AL_HIGHPASS_GAIN),
579 DECL(AL_HIGHPASS_GAINLF),
581 DECL(AL_BANDPASS_GAIN),
582 DECL(AL_BANDPASS_GAINHF),
583 DECL(AL_BANDPASS_GAINLF),
585 DECL(AL_EFFECT_TYPE),
586 DECL(AL_EFFECT_NULL),
587 DECL(AL_EFFECT_REVERB),
588 DECL(AL_EFFECT_EAXREVERB),
589 DECL(AL_EFFECT_CHORUS),
590 DECL(AL_EFFECT_DISTORTION),
591 DECL(AL_EFFECT_ECHO),
592 DECL(AL_EFFECT_FLANGER),
593 #if 0
594 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
595 DECL(AL_EFFECT_VOCAL_MORPHER),
596 DECL(AL_EFFECT_PITCH_SHIFTER),
597 #endif
598 DECL(AL_EFFECT_RING_MODULATOR),
599 #if 0
600 DECL(AL_EFFECT_AUTOWAH),
601 #endif
602 DECL(AL_EFFECT_COMPRESSOR),
603 DECL(AL_EFFECT_EQUALIZER),
604 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
605 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
607 DECL(AL_EFFECTSLOT_EFFECT),
608 DECL(AL_EFFECTSLOT_GAIN),
609 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
610 DECL(AL_EFFECTSLOT_NULL),
612 DECL(AL_EAXREVERB_DENSITY),
613 DECL(AL_EAXREVERB_DIFFUSION),
614 DECL(AL_EAXREVERB_GAIN),
615 DECL(AL_EAXREVERB_GAINHF),
616 DECL(AL_EAXREVERB_GAINLF),
617 DECL(AL_EAXREVERB_DECAY_TIME),
618 DECL(AL_EAXREVERB_DECAY_HFRATIO),
619 DECL(AL_EAXREVERB_DECAY_LFRATIO),
620 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
621 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
622 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
623 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
624 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
625 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
626 DECL(AL_EAXREVERB_ECHO_TIME),
627 DECL(AL_EAXREVERB_ECHO_DEPTH),
628 DECL(AL_EAXREVERB_MODULATION_TIME),
629 DECL(AL_EAXREVERB_MODULATION_DEPTH),
630 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
631 DECL(AL_EAXREVERB_HFREFERENCE),
632 DECL(AL_EAXREVERB_LFREFERENCE),
633 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
634 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
636 DECL(AL_REVERB_DENSITY),
637 DECL(AL_REVERB_DIFFUSION),
638 DECL(AL_REVERB_GAIN),
639 DECL(AL_REVERB_GAINHF),
640 DECL(AL_REVERB_DECAY_TIME),
641 DECL(AL_REVERB_DECAY_HFRATIO),
642 DECL(AL_REVERB_REFLECTIONS_GAIN),
643 DECL(AL_REVERB_REFLECTIONS_DELAY),
644 DECL(AL_REVERB_LATE_REVERB_GAIN),
645 DECL(AL_REVERB_LATE_REVERB_DELAY),
646 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
647 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
648 DECL(AL_REVERB_DECAY_HFLIMIT),
650 DECL(AL_CHORUS_WAVEFORM),
651 DECL(AL_CHORUS_PHASE),
652 DECL(AL_CHORUS_RATE),
653 DECL(AL_CHORUS_DEPTH),
654 DECL(AL_CHORUS_FEEDBACK),
655 DECL(AL_CHORUS_DELAY),
657 DECL(AL_DISTORTION_EDGE),
658 DECL(AL_DISTORTION_GAIN),
659 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
660 DECL(AL_DISTORTION_EQCENTER),
661 DECL(AL_DISTORTION_EQBANDWIDTH),
663 DECL(AL_ECHO_DELAY),
664 DECL(AL_ECHO_LRDELAY),
665 DECL(AL_ECHO_DAMPING),
666 DECL(AL_ECHO_FEEDBACK),
667 DECL(AL_ECHO_SPREAD),
669 DECL(AL_FLANGER_WAVEFORM),
670 DECL(AL_FLANGER_PHASE),
671 DECL(AL_FLANGER_RATE),
672 DECL(AL_FLANGER_DEPTH),
673 DECL(AL_FLANGER_FEEDBACK),
674 DECL(AL_FLANGER_DELAY),
676 DECL(AL_RING_MODULATOR_FREQUENCY),
677 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
678 DECL(AL_RING_MODULATOR_WAVEFORM),
680 DECL(AL_COMPRESSOR_ONOFF),
682 DECL(AL_EQUALIZER_LOW_GAIN),
683 DECL(AL_EQUALIZER_LOW_CUTOFF),
684 DECL(AL_EQUALIZER_MID1_GAIN),
685 DECL(AL_EQUALIZER_MID1_CENTER),
686 DECL(AL_EQUALIZER_MID1_WIDTH),
687 DECL(AL_EQUALIZER_MID2_GAIN),
688 DECL(AL_EQUALIZER_MID2_CENTER),
689 DECL(AL_EQUALIZER_MID2_WIDTH),
690 DECL(AL_EQUALIZER_HIGH_GAIN),
691 DECL(AL_EQUALIZER_HIGH_CUTOFF),
693 DECL(AL_DEDICATED_GAIN),
695 DECL(AL_NUM_RESAMPLERS_SOFT),
696 DECL(AL_DEFAULT_RESAMPLER_SOFT),
697 DECL(AL_SOURCE_RESAMPLER_SOFT),
698 DECL(AL_RESAMPLER_NAME_SOFT),
700 DECL(AL_SOURCE_SPATIALIZE_SOFT),
701 DECL(AL_AUTO_SOFT),
703 #undef DECL
705 static const ALCchar alcNoError[] = "No Error";
706 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
707 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
708 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
709 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
710 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
713 /************************************************
714 * Global variables
715 ************************************************/
717 /* Enumerated device names */
718 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
720 static al_string alcAllDevicesList;
721 static al_string alcCaptureDeviceList;
723 /* Default is always the first in the list */
724 static ALCchar *alcDefaultAllDevicesSpecifier;
725 static ALCchar *alcCaptureDefaultDeviceSpecifier;
727 /* Default context extensions */
728 static const ALchar alExtList[] =
729 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
730 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
731 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
732 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
733 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
734 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
735 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length "
736 "AL_SOFT_source_resampler AL_SOFT_source_spatialize";
738 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
740 /* Thread-local current context */
741 static altss_t LocalContext;
742 /* Process-wide current context */
743 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
745 /* Mixing thread piority level */
746 ALint RTPrioLevel;
748 FILE *LogFile;
749 #ifdef _DEBUG
750 enum LogLevel LogLevel = LogWarning;
751 #else
752 enum LogLevel LogLevel = LogError;
753 #endif
755 /* Flag to trap ALC device errors */
756 static ALCboolean TrapALCError = ALC_FALSE;
758 /* One-time configuration init control */
759 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
761 /* Default effect that applies to sources that don't have an effect on send 0 */
762 static ALeffect DefaultEffect;
764 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
765 * updates.
767 static ALCboolean SuspendDefers = ALC_TRUE;
770 /************************************************
771 * ALC information
772 ************************************************/
773 static const ALCchar alcNoDeviceExtList[] =
774 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
775 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
776 static const ALCchar alcExtensionList[] =
777 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
778 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
779 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
780 "ALC_SOFT_loopback ALC_SOFT_output_limiter ALC_SOFT_pause_device";
781 static const ALCint alcMajorVersion = 1;
782 static const ALCint alcMinorVersion = 1;
784 static const ALCint alcEFXMajorVersion = 1;
785 static const ALCint alcEFXMinorVersion = 0;
788 /************************************************
789 * Device lists
790 ************************************************/
791 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
793 static almtx_t ListLock;
794 static inline void LockLists(void)
796 int ret = almtx_lock(&ListLock);
797 assert(ret == althrd_success);
799 static inline void UnlockLists(void)
801 int ret = almtx_unlock(&ListLock);
802 assert(ret == althrd_success);
805 /************************************************
806 * Library initialization
807 ************************************************/
808 #if defined(_WIN32)
809 static void alc_init(void);
810 static void alc_deinit(void);
811 static void alc_deinit_safe(void);
813 #ifndef AL_LIBTYPE_STATIC
814 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
816 switch(reason)
818 case DLL_PROCESS_ATTACH:
819 /* Pin the DLL so we won't get unloaded until the process terminates */
820 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
821 (WCHAR*)hModule, &hModule);
822 alc_init();
823 break;
825 case DLL_THREAD_DETACH:
826 break;
828 case DLL_PROCESS_DETACH:
829 if(!lpReserved)
830 alc_deinit();
831 else
832 alc_deinit_safe();
833 break;
835 return TRUE;
837 #elif defined(_MSC_VER)
838 #pragma section(".CRT$XCU",read)
839 static void alc_constructor(void);
840 static void alc_destructor(void);
841 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
843 static void alc_constructor(void)
845 atexit(alc_destructor);
846 alc_init();
849 static void alc_destructor(void)
851 alc_deinit();
853 #elif defined(HAVE_GCC_DESTRUCTOR)
854 static void alc_init(void) __attribute__((constructor));
855 static void alc_deinit(void) __attribute__((destructor));
856 #else
857 #error "No static initialization available on this platform!"
858 #endif
860 #elif defined(HAVE_GCC_DESTRUCTOR)
862 static void alc_init(void) __attribute__((constructor));
863 static void alc_deinit(void) __attribute__((destructor));
865 #else
866 #error "No global initialization available on this platform!"
867 #endif
869 static void ReleaseThreadCtx(void *ptr);
870 static void alc_init(void)
872 const char *str;
873 int ret;
875 LogFile = stderr;
877 AL_STRING_INIT(alcAllDevicesList);
878 AL_STRING_INIT(alcCaptureDeviceList);
880 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
881 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
882 ConeScale *= 0.5f;
884 str = getenv("__ALSOFT_REVERSE_Z");
885 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
886 ZScale *= -1.0f;
888 ret = altss_create(&LocalContext, ReleaseThreadCtx);
889 assert(ret == althrd_success);
891 ret = almtx_init(&ListLock, almtx_recursive);
892 assert(ret == althrd_success);
894 ThunkInit();
897 static void alc_initconfig(void)
899 const char *devs, *str;
900 ALuint capfilter;
901 float valf;
902 int i, n;
904 str = getenv("ALSOFT_LOGLEVEL");
905 if(str)
907 long lvl = strtol(str, NULL, 0);
908 if(lvl >= NoLog && lvl <= LogRef)
909 LogLevel = lvl;
912 str = getenv("ALSOFT_LOGFILE");
913 if(str && str[0])
915 FILE *logfile = al_fopen(str, "wt");
916 if(logfile) LogFile = logfile;
917 else ERR("Failed to open log file '%s'\n", str);
920 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION,
921 ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
923 char buf[1024] = "";
924 int len = 0;
926 if(BackendListSize > 0)
927 len += snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
928 for(i = 1;i < BackendListSize;i++)
929 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
930 TRACE("Supported backends: %s\n", buf);
932 ReadALConfig();
934 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
935 if(str && *str)
937 if(strcasecmp(str, "ignore") == 0)
939 SuspendDefers = ALC_FALSE;
940 TRACE("Selected context suspend behavior, \"ignore\"\n");
942 else
943 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
946 capfilter = 0;
947 #if defined(HAVE_SSE4_1)
948 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
949 #elif defined(HAVE_SSE3)
950 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
951 #elif defined(HAVE_SSE2)
952 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
953 #elif defined(HAVE_SSE)
954 capfilter |= CPU_CAP_SSE;
955 #endif
956 #ifdef HAVE_NEON
957 capfilter |= CPU_CAP_NEON;
958 #endif
959 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
961 if(strcasecmp(str, "all") == 0)
962 capfilter = 0;
963 else
965 size_t len;
966 const char *next = str;
968 do {
969 str = next;
970 while(isspace(str[0]))
971 str++;
972 next = strchr(str, ',');
974 if(!str[0] || str[0] == ',')
975 continue;
977 len = (next ? ((size_t)(next-str)) : strlen(str));
978 while(len > 0 && isspace(str[len-1]))
979 len--;
980 if(len == 3 && strncasecmp(str, "sse", len) == 0)
981 capfilter &= ~CPU_CAP_SSE;
982 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
983 capfilter &= ~CPU_CAP_SSE2;
984 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
985 capfilter &= ~CPU_CAP_SSE3;
986 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
987 capfilter &= ~CPU_CAP_SSE4_1;
988 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
989 capfilter &= ~CPU_CAP_NEON;
990 else
991 WARN("Invalid CPU extension \"%s\"\n", str);
992 } while(next++);
995 FillCPUCaps(capfilter);
997 #ifdef _WIN32
998 RTPrioLevel = 1;
999 #else
1000 RTPrioLevel = 0;
1001 #endif
1002 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
1004 aluInitMixer();
1006 str = getenv("ALSOFT_TRAP_ERROR");
1007 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1009 TrapALError = AL_TRUE;
1010 TrapALCError = AL_TRUE;
1012 else
1014 str = getenv("ALSOFT_TRAP_AL_ERROR");
1015 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1016 TrapALError = AL_TRUE;
1017 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1019 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1020 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1021 TrapALCError = ALC_TRUE;
1022 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1025 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1026 ReverbBoost *= powf(10.0f, valf / 20.0f);
1028 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1030 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1031 ConfigValueStr(NULL, NULL, "drivers", &devs))
1033 int n;
1034 size_t len;
1035 const char *next = devs;
1036 int endlist, delitem;
1038 i = 0;
1039 do {
1040 devs = next;
1041 while(isspace(devs[0]))
1042 devs++;
1043 next = strchr(devs, ',');
1045 delitem = (devs[0] == '-');
1046 if(devs[0] == '-') devs++;
1048 if(!devs[0] || devs[0] == ',')
1050 endlist = 0;
1051 continue;
1053 endlist = 1;
1055 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1056 while(len > 0 && isspace(devs[len-1]))
1057 len--;
1058 for(n = i;n < BackendListSize;n++)
1060 if(len == strlen(BackendList[n].name) &&
1061 strncmp(BackendList[n].name, devs, len) == 0)
1063 if(delitem)
1065 for(;n+1 < BackendListSize;n++)
1066 BackendList[n] = BackendList[n+1];
1067 BackendListSize--;
1069 else
1071 struct BackendInfo Bkp = BackendList[n];
1072 for(;n > i;n--)
1073 BackendList[n] = BackendList[n-1];
1074 BackendList[n] = Bkp;
1076 i++;
1078 break;
1081 } while(next++);
1083 if(endlist)
1084 BackendListSize = i;
1087 for(i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1089 ALCbackendFactory *factory = BackendList[i].getFactory();
1090 if(!V0(factory,init)())
1092 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1093 continue;
1096 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1097 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1099 PlaybackBackend = BackendList[i];
1100 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1102 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1104 CaptureBackend = BackendList[i];
1105 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1109 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1110 V0(factory,init)();
1113 if(!PlaybackBackend.name)
1114 WARN("No playback backend available!\n");
1115 if(!CaptureBackend.name)
1116 WARN("No capture backend available!\n");
1118 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1120 size_t len;
1121 const char *next = str;
1123 do {
1124 str = next;
1125 next = strchr(str, ',');
1127 if(!str[0] || next == str)
1128 continue;
1130 len = (next ? ((size_t)(next-str)) : strlen(str));
1131 for(n = 0;EffectList[n].name;n++)
1133 if(len == strlen(EffectList[n].name) &&
1134 strncmp(EffectList[n].name, str, len) == 0)
1135 DisabledEffects[EffectList[n].type] = AL_TRUE;
1137 } while(next++);
1140 InitEffectFactoryMap();
1142 InitEffect(&DefaultEffect);
1143 str = getenv("ALSOFT_DEFAULT_REVERB");
1144 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1145 LoadReverbPreset(str, &DefaultEffect);
1147 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1149 #ifdef __ANDROID__
1150 #include <jni.h>
1152 static JavaVM *gJavaVM;
1153 static pthread_key_t gJVMThreadKey;
1155 static void CleanupJNIEnv(void* UNUSED(ptr))
1157 JCALL0(gJavaVM,DetachCurrentThread)();
1160 void *Android_GetJNIEnv(void)
1162 if(!gJavaVM)
1164 WARN("gJavaVM is NULL!\n");
1165 return NULL;
1168 /* http://developer.android.com/guide/practices/jni.html
1170 * All threads are Linux threads, scheduled by the kernel. They're usually
1171 * started from managed code (using Thread.start), but they can also be
1172 * created elsewhere and then attached to the JavaVM. For example, a thread
1173 * started with pthread_create can be attached with the JNI
1174 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1175 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1176 * Attaching a natively-created thread causes a java.lang.Thread object to
1177 * be constructed and added to the "main" ThreadGroup, making it visible to
1178 * the debugger. Calling AttachCurrentThread on an already-attached thread
1179 * is a no-op.
1181 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1182 if(!env)
1184 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1185 if(status < 0)
1187 ERR("Failed to attach current thread\n");
1188 return NULL;
1190 pthread_setspecific(gJVMThreadKey, env);
1192 return env;
1195 /* Automatically called by JNI. */
1196 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1198 void *env;
1199 int err;
1201 gJavaVM = jvm;
1202 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1204 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1205 return JNI_ERR;
1208 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1209 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1211 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1212 ERR("pthread_key_create failed: %d\n", err);
1213 pthread_setspecific(gJVMThreadKey, env);
1214 return JNI_VERSION_1_4;
1216 #endif
1219 /************************************************
1220 * Library deinitialization
1221 ************************************************/
1222 static void alc_cleanup(void)
1224 ALCdevice *dev;
1226 AL_STRING_DEINIT(alcAllDevicesList);
1227 AL_STRING_DEINIT(alcCaptureDeviceList);
1229 free(alcDefaultAllDevicesSpecifier);
1230 alcDefaultAllDevicesSpecifier = NULL;
1231 free(alcCaptureDefaultDeviceSpecifier);
1232 alcCaptureDefaultDeviceSpecifier = NULL;
1234 if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL)
1236 ALCuint num = 0;
1237 do {
1238 num++;
1239 } while((dev=dev->next) != NULL);
1240 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1243 DeinitEffectFactoryMap();
1246 static void alc_deinit_safe(void)
1248 alc_cleanup();
1250 FreeHrtfs();
1251 FreeALConfig();
1253 ThunkExit();
1254 almtx_destroy(&ListLock);
1255 altss_delete(LocalContext);
1257 if(LogFile != stderr)
1258 fclose(LogFile);
1259 LogFile = NULL;
1262 static void alc_deinit(void)
1264 int i;
1266 alc_cleanup();
1268 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1269 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1271 for(i = 0;i < BackendListSize;i++)
1273 ALCbackendFactory *factory = BackendList[i].getFactory();
1274 V0(factory,deinit)();
1277 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1278 V0(factory,deinit)();
1281 alc_deinit_safe();
1285 /************************************************
1286 * Device enumeration
1287 ************************************************/
1288 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1290 ALCbackendFactory *factory;
1292 DO_INITCONFIG();
1294 LockLists();
1295 alstr_clear(list);
1297 factory = backendinfo->getFactory();
1298 V(factory,probe)(type);
1300 UnlockLists();
1302 static void ProbeAllDevicesList(void)
1303 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1304 static void ProbeCaptureDeviceList(void)
1305 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1307 static void AppendDevice(const ALCchar *name, al_string *devnames)
1309 size_t len = strlen(name);
1310 if(len > 0)
1311 alstr_append_range(devnames, name, name+len+1);
1313 void AppendAllDevicesList(const ALCchar *name)
1314 { AppendDevice(name, &alcAllDevicesList); }
1315 void AppendCaptureDeviceList(const ALCchar *name)
1316 { AppendDevice(name, &alcCaptureDeviceList); }
1319 /************************************************
1320 * Device format information
1321 ************************************************/
1322 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1324 switch(type)
1326 case DevFmtByte: return "Signed Byte";
1327 case DevFmtUByte: return "Unsigned Byte";
1328 case DevFmtShort: return "Signed Short";
1329 case DevFmtUShort: return "Unsigned Short";
1330 case DevFmtInt: return "Signed Int";
1331 case DevFmtUInt: return "Unsigned Int";
1332 case DevFmtFloat: return "Float";
1334 return "(unknown type)";
1336 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1338 switch(chans)
1340 case DevFmtMono: return "Mono";
1341 case DevFmtStereo: return "Stereo";
1342 case DevFmtQuad: return "Quadraphonic";
1343 case DevFmtX51: return "5.1 Surround";
1344 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1345 case DevFmtX61: return "6.1 Surround";
1346 case DevFmtX71: return "7.1 Surround";
1347 case DevFmtAmbi3D: return "Ambisonic 3D";
1349 return "(unknown channels)";
1352 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder);
1353 ALsizei BytesFromDevFmt(enum DevFmtType type)
1355 switch(type)
1357 case DevFmtByte: return sizeof(ALbyte);
1358 case DevFmtUByte: return sizeof(ALubyte);
1359 case DevFmtShort: return sizeof(ALshort);
1360 case DevFmtUShort: return sizeof(ALushort);
1361 case DevFmtInt: return sizeof(ALint);
1362 case DevFmtUInt: return sizeof(ALuint);
1363 case DevFmtFloat: return sizeof(ALfloat);
1365 return 0;
1367 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder)
1369 switch(chans)
1371 case DevFmtMono: return 1;
1372 case DevFmtStereo: return 2;
1373 case DevFmtQuad: return 4;
1374 case DevFmtX51: return 6;
1375 case DevFmtX51Rear: return 6;
1376 case DevFmtX61: return 7;
1377 case DevFmtX71: return 8;
1378 case DevFmtAmbi3D: return (ambiorder >= 3) ? 16 :
1379 (ambiorder == 2) ? 9 :
1380 (ambiorder == 1) ? 4 : 1;
1382 return 0;
1385 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1386 enum DevFmtType *type)
1388 static const struct {
1389 ALenum format;
1390 enum DevFmtChannels channels;
1391 enum DevFmtType type;
1392 } list[] = {
1393 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1394 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1395 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1397 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1398 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1399 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1401 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1402 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1403 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1405 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1406 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1407 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1409 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1410 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1411 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1413 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1414 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1415 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1417 ALuint i;
1419 for(i = 0;i < COUNTOF(list);i++)
1421 if(list[i].format == format)
1423 *chans = list[i].channels;
1424 *type = list[i].type;
1425 return AL_TRUE;
1429 return AL_FALSE;
1432 static ALCboolean IsValidALCType(ALCenum type)
1434 switch(type)
1436 case ALC_BYTE_SOFT:
1437 case ALC_UNSIGNED_BYTE_SOFT:
1438 case ALC_SHORT_SOFT:
1439 case ALC_UNSIGNED_SHORT_SOFT:
1440 case ALC_INT_SOFT:
1441 case ALC_UNSIGNED_INT_SOFT:
1442 case ALC_FLOAT_SOFT:
1443 return ALC_TRUE;
1445 return ALC_FALSE;
1448 static ALCboolean IsValidALCChannels(ALCenum channels)
1450 switch(channels)
1452 case ALC_MONO_SOFT:
1453 case ALC_STEREO_SOFT:
1454 case ALC_QUAD_SOFT:
1455 case ALC_5POINT1_SOFT:
1456 case ALC_6POINT1_SOFT:
1457 case ALC_7POINT1_SOFT:
1458 case ALC_BFORMAT3D_SOFT:
1459 return ALC_TRUE;
1461 return ALC_FALSE;
1464 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1466 switch(layout)
1468 case ALC_ACN_SOFT:
1469 case ALC_FUMA_SOFT:
1470 return ALC_TRUE;
1472 return ALC_FALSE;
1475 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1477 switch(scaling)
1479 case ALC_N3D_SOFT:
1480 case ALC_SN3D_SOFT:
1481 case ALC_FUMA_SOFT:
1482 return ALC_TRUE;
1484 return ALC_FALSE;
1487 /************************************************
1488 * Miscellaneous ALC helpers
1489 ************************************************/
1491 void ALCdevice_Lock(ALCdevice *device)
1493 V0(device->Backend,lock)();
1496 void ALCdevice_Unlock(ALCdevice *device)
1498 V0(device->Backend,unlock)();
1502 /* SetDefaultWFXChannelOrder
1504 * Sets the default channel order used by WaveFormatEx.
1506 void SetDefaultWFXChannelOrder(ALCdevice *device)
1508 ALsizei i;
1510 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1511 device->RealOut.ChannelName[i] = InvalidChannel;
1513 switch(device->FmtChans)
1515 case DevFmtMono:
1516 device->RealOut.ChannelName[0] = FrontCenter;
1517 break;
1518 case DevFmtStereo:
1519 device->RealOut.ChannelName[0] = FrontLeft;
1520 device->RealOut.ChannelName[1] = FrontRight;
1521 break;
1522 case DevFmtQuad:
1523 device->RealOut.ChannelName[0] = FrontLeft;
1524 device->RealOut.ChannelName[1] = FrontRight;
1525 device->RealOut.ChannelName[2] = BackLeft;
1526 device->RealOut.ChannelName[3] = BackRight;
1527 break;
1528 case DevFmtX51:
1529 device->RealOut.ChannelName[0] = FrontLeft;
1530 device->RealOut.ChannelName[1] = FrontRight;
1531 device->RealOut.ChannelName[2] = FrontCenter;
1532 device->RealOut.ChannelName[3] = LFE;
1533 device->RealOut.ChannelName[4] = SideLeft;
1534 device->RealOut.ChannelName[5] = SideRight;
1535 break;
1536 case DevFmtX51Rear:
1537 device->RealOut.ChannelName[0] = FrontLeft;
1538 device->RealOut.ChannelName[1] = FrontRight;
1539 device->RealOut.ChannelName[2] = FrontCenter;
1540 device->RealOut.ChannelName[3] = LFE;
1541 device->RealOut.ChannelName[4] = BackLeft;
1542 device->RealOut.ChannelName[5] = BackRight;
1543 break;
1544 case DevFmtX61:
1545 device->RealOut.ChannelName[0] = FrontLeft;
1546 device->RealOut.ChannelName[1] = FrontRight;
1547 device->RealOut.ChannelName[2] = FrontCenter;
1548 device->RealOut.ChannelName[3] = LFE;
1549 device->RealOut.ChannelName[4] = BackCenter;
1550 device->RealOut.ChannelName[5] = SideLeft;
1551 device->RealOut.ChannelName[6] = SideRight;
1552 break;
1553 case DevFmtX71:
1554 device->RealOut.ChannelName[0] = FrontLeft;
1555 device->RealOut.ChannelName[1] = FrontRight;
1556 device->RealOut.ChannelName[2] = FrontCenter;
1557 device->RealOut.ChannelName[3] = LFE;
1558 device->RealOut.ChannelName[4] = BackLeft;
1559 device->RealOut.ChannelName[5] = BackRight;
1560 device->RealOut.ChannelName[6] = SideLeft;
1561 device->RealOut.ChannelName[7] = SideRight;
1562 break;
1563 case DevFmtAmbi3D:
1564 device->RealOut.ChannelName[0] = Aux0;
1565 if(device->AmbiOrder > 0)
1567 device->RealOut.ChannelName[1] = Aux1;
1568 device->RealOut.ChannelName[2] = Aux2;
1569 device->RealOut.ChannelName[3] = Aux3;
1571 if(device->AmbiOrder > 1)
1573 device->RealOut.ChannelName[4] = Aux4;
1574 device->RealOut.ChannelName[5] = Aux5;
1575 device->RealOut.ChannelName[6] = Aux6;
1576 device->RealOut.ChannelName[7] = Aux7;
1577 device->RealOut.ChannelName[8] = Aux8;
1579 if(device->AmbiOrder > 2)
1581 device->RealOut.ChannelName[9] = Aux9;
1582 device->RealOut.ChannelName[10] = Aux10;
1583 device->RealOut.ChannelName[11] = Aux11;
1584 device->RealOut.ChannelName[12] = Aux12;
1585 device->RealOut.ChannelName[13] = Aux13;
1586 device->RealOut.ChannelName[14] = Aux14;
1587 device->RealOut.ChannelName[15] = Aux15;
1589 break;
1593 /* SetDefaultChannelOrder
1595 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1597 void SetDefaultChannelOrder(ALCdevice *device)
1599 ALsizei i;
1601 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1602 device->RealOut.ChannelName[i] = InvalidChannel;
1604 switch(device->FmtChans)
1606 case DevFmtX51Rear:
1607 device->RealOut.ChannelName[0] = FrontLeft;
1608 device->RealOut.ChannelName[1] = FrontRight;
1609 device->RealOut.ChannelName[2] = BackLeft;
1610 device->RealOut.ChannelName[3] = BackRight;
1611 device->RealOut.ChannelName[4] = FrontCenter;
1612 device->RealOut.ChannelName[5] = LFE;
1613 return;
1614 case DevFmtX71:
1615 device->RealOut.ChannelName[0] = FrontLeft;
1616 device->RealOut.ChannelName[1] = FrontRight;
1617 device->RealOut.ChannelName[2] = BackLeft;
1618 device->RealOut.ChannelName[3] = BackRight;
1619 device->RealOut.ChannelName[4] = FrontCenter;
1620 device->RealOut.ChannelName[5] = LFE;
1621 device->RealOut.ChannelName[6] = SideLeft;
1622 device->RealOut.ChannelName[7] = SideRight;
1623 return;
1625 /* Same as WFX order */
1626 case DevFmtMono:
1627 case DevFmtStereo:
1628 case DevFmtQuad:
1629 case DevFmtX51:
1630 case DevFmtX61:
1631 case DevFmtAmbi3D:
1632 SetDefaultWFXChannelOrder(device);
1633 break;
1637 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1640 /* ALCcontext_DeferUpdates
1642 * Defers/suspends updates for the given context's listener and sources. This
1643 * does *NOT* stop mixing, but rather prevents certain property changes from
1644 * taking effect.
1646 void ALCcontext_DeferUpdates(ALCcontext *context)
1648 ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE);
1651 /* ALCcontext_ProcessUpdates
1653 * Resumes update processing after being deferred.
1655 void ALCcontext_ProcessUpdates(ALCcontext *context)
1657 ReadLock(&context->PropLock);
1658 if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
1660 /* Tell the mixer to stop applying updates, then wait for any active
1661 * updating to finish, before providing updates.
1663 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1664 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1665 althrd_yield();
1667 UpdateListenerProps(context);
1668 UpdateAllEffectSlotProps(context);
1669 UpdateAllSourceProps(context);
1671 /* Now with all updates declared, let the mixer continue applying them
1672 * so they all happen at once.
1674 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1676 ReadUnlock(&context->PropLock);
1680 /* alcSetError
1682 * Stores the latest ALC device error
1684 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1686 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1687 if(TrapALCError)
1689 #ifdef _WIN32
1690 /* DebugBreak() will cause an exception if there is no debugger */
1691 if(IsDebuggerPresent())
1692 DebugBreak();
1693 #elif defined(SIGTRAP)
1694 raise(SIGTRAP);
1695 #endif
1698 if(device)
1699 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1700 else
1701 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1705 struct Compressor *CreateDeviceLimiter(const ALCdevice *device)
1707 return CompressorInit(0.0f, 0.0f, AL_FALSE, AL_TRUE, 0.0f, 0.0f, 0.5f, 2.0f,
1708 0.0f, -3.0f, 3.0f, device->Frequency);
1711 /* UpdateClockBase
1713 * Updates the device's base clock time with however many samples have been
1714 * done. This is used so frequency changes on the device don't cause the time
1715 * to jump forward or back. Must not be called while the device is running/
1716 * mixing.
1718 static inline void UpdateClockBase(ALCdevice *device)
1720 IncrementRef(&device->MixCount);
1721 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1722 device->SamplesDone = 0;
1723 IncrementRef(&device->MixCount);
1726 /* UpdateDeviceParams
1728 * Updates device parameters according to the attribute list (caller is
1729 * responsible for holding the list lock).
1731 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1733 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1734 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1735 ALCenum gainLimiter = device->Limiter ? ALC_TRUE : ALC_FALSE;
1736 const ALsizei old_sends = device->NumAuxSends;
1737 ALsizei new_sends = device->NumAuxSends;
1738 enum DevFmtChannels oldChans;
1739 enum DevFmtType oldType;
1740 ALboolean update_failed;
1741 ALCsizei hrtf_id = -1;
1742 ALCcontext *context;
1743 ALCuint oldFreq;
1744 FPUCtl oldMode;
1745 size_t size;
1746 ALCsizei i;
1747 int val;
1749 // Check for attributes
1750 if(device->Type == Loopback)
1752 ALCsizei numMono, numStereo, numSends;
1753 ALCenum alayout = AL_NONE;
1754 ALCenum ascale = AL_NONE;
1755 ALCenum schans = AL_NONE;
1756 ALCenum stype = AL_NONE;
1757 ALCsizei attrIdx = 0;
1758 ALCsizei aorder = 0;
1759 ALCuint freq = 0;
1761 if(!attrList)
1763 WARN("Missing attributes for loopback device\n");
1764 return ALC_INVALID_VALUE;
1767 numMono = device->NumMonoSources;
1768 numStereo = device->NumStereoSources;
1769 numSends = old_sends;
1771 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1772 while(attrList[attrIdx])
1774 switch(attrList[attrIdx])
1776 case ALC_FORMAT_CHANNELS_SOFT:
1777 schans = attrList[attrIdx + 1];
1778 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1779 if(!IsValidALCChannels(schans))
1780 return ALC_INVALID_VALUE;
1781 break;
1783 case ALC_FORMAT_TYPE_SOFT:
1784 stype = attrList[attrIdx + 1];
1785 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1786 if(!IsValidALCType(stype))
1787 return ALC_INVALID_VALUE;
1788 break;
1790 case ALC_FREQUENCY:
1791 freq = attrList[attrIdx + 1];
1792 TRACE_ATTR(ALC_FREQUENCY, freq);
1793 if(freq < MIN_OUTPUT_RATE)
1794 return ALC_INVALID_VALUE;
1795 break;
1797 case ALC_AMBISONIC_LAYOUT_SOFT:
1798 alayout = attrList[attrIdx + 1];
1799 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1800 if(!IsValidAmbiLayout(alayout))
1801 return ALC_INVALID_VALUE;
1802 break;
1804 case ALC_AMBISONIC_SCALING_SOFT:
1805 ascale = attrList[attrIdx + 1];
1806 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1807 if(!IsValidAmbiScaling(ascale))
1808 return ALC_INVALID_VALUE;
1809 break;
1811 case ALC_AMBISONIC_ORDER_SOFT:
1812 aorder = attrList[attrIdx + 1];
1813 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1814 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1815 return ALC_INVALID_VALUE;
1816 break;
1818 case ALC_MONO_SOURCES:
1819 numMono = attrList[attrIdx + 1];
1820 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1821 numMono = maxi(numMono, 0);
1822 break;
1824 case ALC_STEREO_SOURCES:
1825 numStereo = attrList[attrIdx + 1];
1826 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1827 numStereo = maxi(numStereo, 0);
1828 break;
1830 case ALC_MAX_AUXILIARY_SENDS:
1831 numSends = attrList[attrIdx + 1];
1832 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1833 numSends = clampi(numSends, 0, MAX_SENDS);
1834 break;
1836 case ALC_HRTF_SOFT:
1837 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1838 if(attrList[attrIdx + 1] == ALC_FALSE)
1839 hrtf_appreq = Hrtf_Disable;
1840 else if(attrList[attrIdx + 1] == ALC_TRUE)
1841 hrtf_appreq = Hrtf_Enable;
1842 else
1843 hrtf_appreq = Hrtf_Default;
1844 break;
1846 case ALC_HRTF_ID_SOFT:
1847 hrtf_id = attrList[attrIdx + 1];
1848 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1849 break;
1851 case ALC_OUTPUT_LIMITER_SOFT:
1852 gainLimiter = attrList[attrIdx + 1];
1853 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1854 break;
1856 default:
1857 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList[attrIdx],
1858 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1859 break;
1862 attrIdx += 2;
1864 #undef TRACE_ATTR
1866 if(!schans || !stype || !freq)
1868 WARN("Missing format for loopback device\n");
1869 return ALC_INVALID_VALUE;
1871 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1873 WARN("Missing ambisonic info for loopback device\n");
1874 return ALC_INVALID_VALUE;
1877 if((device->Flags&DEVICE_RUNNING))
1878 V0(device->Backend,stop)();
1879 device->Flags &= ~DEVICE_RUNNING;
1881 UpdateClockBase(device);
1883 device->Frequency = freq;
1884 device->FmtChans = schans;
1885 device->FmtType = stype;
1886 if(schans == ALC_BFORMAT3D_SOFT)
1888 device->AmbiOrder = aorder;
1889 device->AmbiLayout = alayout;
1890 device->AmbiScale = ascale;
1893 if(numMono > INT_MAX-numStereo)
1894 numMono = INT_MAX-numStereo;
1895 numMono += numStereo;
1896 if(ConfigValueInt(NULL, NULL, "sources", &numMono))
1898 if(numMono <= 0)
1899 numMono = 256;
1901 else
1902 numMono = maxi(numMono, 256);
1903 numStereo = mini(numStereo, numMono);
1904 numMono -= numStereo;
1905 device->SourcesMax = numMono + numStereo;
1907 device->NumMonoSources = numMono;
1908 device->NumStereoSources = numStereo;
1910 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1911 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1912 else
1913 new_sends = numSends;
1915 else if(attrList && attrList[0])
1917 ALCsizei numMono, numStereo, numSends;
1918 ALCsizei attrIdx = 0;
1919 ALCuint freq;
1921 /* If a context is already running on the device, stop playback so the
1922 * device attributes can be updated. */
1923 if((device->Flags&DEVICE_RUNNING))
1924 V0(device->Backend,stop)();
1925 device->Flags &= ~DEVICE_RUNNING;
1927 UpdateClockBase(device);
1929 freq = device->Frequency;
1930 numMono = device->NumMonoSources;
1931 numStereo = device->NumStereoSources;
1932 numSends = old_sends;
1934 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1935 while(attrList[attrIdx])
1937 switch(attrList[attrIdx])
1939 case ALC_FREQUENCY:
1940 freq = attrList[attrIdx + 1];
1941 TRACE_ATTR(ALC_FREQUENCY, freq);
1942 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1943 break;
1945 case ALC_MONO_SOURCES:
1946 numMono = attrList[attrIdx + 1];
1947 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1948 numMono = maxi(numMono, 0);
1949 break;
1951 case ALC_STEREO_SOURCES:
1952 numStereo = attrList[attrIdx + 1];
1953 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1954 numStereo = maxi(numStereo, 0);
1955 break;
1957 case ALC_MAX_AUXILIARY_SENDS:
1958 numSends = attrList[attrIdx + 1];
1959 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1960 numSends = clampi(numSends, 0, MAX_SENDS);
1961 break;
1963 case ALC_HRTF_SOFT:
1964 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1965 if(attrList[attrIdx + 1] == ALC_FALSE)
1966 hrtf_appreq = Hrtf_Disable;
1967 else if(attrList[attrIdx + 1] == ALC_TRUE)
1968 hrtf_appreq = Hrtf_Enable;
1969 else
1970 hrtf_appreq = Hrtf_Default;
1971 break;
1973 case ALC_HRTF_ID_SOFT:
1974 hrtf_id = attrList[attrIdx + 1];
1975 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1976 break;
1978 case ALC_OUTPUT_LIMITER_SOFT:
1979 gainLimiter = attrList[attrIdx + 1];
1980 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1981 break;
1983 default:
1984 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
1985 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1986 break;
1989 attrIdx += 2;
1991 #undef TRACE_ATTR
1993 ConfigValueUInt(alstr_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1994 freq = maxu(freq, MIN_OUTPUT_RATE);
1996 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1997 device->Frequency;
1998 /* SSE and Neon do best with the update size being a multiple of 4 */
1999 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2000 device->UpdateSize = (device->UpdateSize+3)&~3;
2002 device->Frequency = freq;
2004 if(numMono > INT_MAX-numStereo)
2005 numMono = INT_MAX-numStereo;
2006 numMono += numStereo;
2007 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono))
2009 if(numMono <= 0)
2010 numMono = 256;
2012 else
2013 numMono = maxi(numMono, 256);
2014 numStereo = mini(numStereo, numMono);
2015 numMono -= numStereo;
2016 device->SourcesMax = numMono + numStereo;
2018 device->NumMonoSources = numMono;
2019 device->NumStereoSources = numStereo;
2021 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2022 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2023 else
2024 new_sends = numSends;
2027 if((device->Flags&DEVICE_RUNNING))
2028 return ALC_NO_ERROR;
2030 al_free(device->Uhj_Encoder);
2031 device->Uhj_Encoder = NULL;
2033 al_free(device->Bs2b);
2034 device->Bs2b = NULL;
2036 al_free(device->ChannelDelay[0].Buffer);
2037 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2039 device->ChannelDelay[i].Length = 0;
2040 device->ChannelDelay[i].Buffer = NULL;
2043 al_free(device->Dry.Buffer);
2044 device->Dry.Buffer = NULL;
2045 device->Dry.NumChannels = 0;
2046 device->FOAOut.Buffer = NULL;
2047 device->FOAOut.NumChannels = 0;
2048 device->RealOut.Buffer = NULL;
2049 device->RealOut.NumChannels = 0;
2051 UpdateClockBase(device);
2053 device->DitherSeed = DITHER_RNG_SEED;
2055 /*************************************************************************
2056 * Update device format request if HRTF is requested
2058 device->HrtfStatus = ALC_HRTF_DISABLED_SOFT;
2059 if(device->Type != Loopback)
2061 const char *hrtf;
2062 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2064 if(strcasecmp(hrtf, "true") == 0)
2065 hrtf_userreq = Hrtf_Enable;
2066 else if(strcasecmp(hrtf, "false") == 0)
2067 hrtf_userreq = Hrtf_Disable;
2068 else if(strcasecmp(hrtf, "auto") != 0)
2069 ERR("Unexpected hrtf value: %s\n", hrtf);
2072 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2074 struct Hrtf *hrtf = NULL;
2075 if(VECTOR_SIZE(device->HrtfList) == 0)
2077 VECTOR_DEINIT(device->HrtfList);
2078 device->HrtfList = EnumerateHrtf(device->DeviceName);
2080 if(VECTOR_SIZE(device->HrtfList) > 0)
2082 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
2083 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
2084 else
2085 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
2088 if(hrtf)
2090 device->FmtChans = DevFmtStereo;
2091 device->Frequency = hrtf->sampleRate;
2092 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2093 if(device->HrtfHandle)
2094 Hrtf_DecRef(device->HrtfHandle);
2095 device->HrtfHandle = hrtf;
2097 else
2099 hrtf_userreq = Hrtf_Default;
2100 hrtf_appreq = Hrtf_Disable;
2101 device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2106 oldFreq = device->Frequency;
2107 oldChans = device->FmtChans;
2108 oldType = device->FmtType;
2110 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2111 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2112 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2113 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2114 device->UpdateSize, device->NumUpdates
2117 if(V0(device->Backend,reset)() == ALC_FALSE)
2118 return ALC_INVALID_DEVICE;
2120 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2122 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2123 DevFmtChannelsString(device->FmtChans));
2124 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2126 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2128 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2129 DevFmtTypeString(device->FmtType));
2130 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2132 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2134 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2135 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2138 if((device->UpdateSize&3) != 0)
2140 if((CPUCapFlags&CPU_CAP_SSE))
2141 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2142 if((CPUCapFlags&CPU_CAP_NEON))
2143 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2146 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2147 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2148 device->Frequency, device->UpdateSize, device->NumUpdates
2151 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2152 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2153 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2155 /* Allocate extra channels for any post-filter output. */
2156 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2157 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2159 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2160 device->Dry.Buffer = al_calloc(16, size);
2161 if(!device->Dry.Buffer)
2163 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2164 return ALC_INVALID_DEVICE;
2167 if(device->RealOut.NumChannels != 0)
2168 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2169 device->FOAOut.NumChannels;
2170 else
2172 device->RealOut.Buffer = device->Dry.Buffer;
2173 device->RealOut.NumChannels = device->Dry.NumChannels;
2176 if(device->FOAOut.NumChannels != 0)
2177 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2178 else
2180 device->FOAOut.Buffer = device->Dry.Buffer;
2181 device->FOAOut.NumChannels = device->Dry.NumChannels;
2184 device->NumAuxSends = new_sends;
2185 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2186 device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2187 device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2189 device->DitherDepth = 0.0f;
2190 if(GetConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "dither", 1))
2192 ALint depth = 0;
2193 ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "dither-depth", &depth);
2194 if(depth <= 0)
2196 switch(device->FmtType)
2198 case DevFmtByte:
2199 case DevFmtUByte:
2200 depth = 8;
2201 break;
2202 case DevFmtShort:
2203 case DevFmtUShort:
2204 depth = 16;
2205 break;
2206 case DevFmtInt:
2207 case DevFmtUInt:
2208 case DevFmtFloat:
2209 break;
2212 else if(depth > 24)
2213 depth = 24;
2214 device->DitherDepth = (depth > 0) ? powf(2.0f, (ALfloat)(depth-1)) : 0.0f;
2216 if(!(device->DitherDepth > 0.0f))
2217 TRACE("Dithering disabled\n");
2218 else
2219 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device->DitherDepth)+1.0f,
2220 device->DitherDepth);
2222 if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
2223 gainLimiter = val ? ALC_TRUE : ALC_FALSE;
2224 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2225 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2226 * ALC_TRUE.
2228 if(gainLimiter != ALC_FALSE)
2230 if(!device->Limiter || device->Frequency != GetCompressorSampleRate(device->Limiter))
2232 al_free(device->Limiter);
2233 device->Limiter = CreateDeviceLimiter(device);
2236 else
2238 al_free(device->Limiter);
2239 device->Limiter = NULL;
2241 TRACE("Output limiter %s\n", device->Limiter ? "enabled" : "disabled");
2243 /* Need to delay returning failure until replacement Send arrays have been
2244 * allocated with the appropriate size.
2246 update_failed = AL_FALSE;
2247 SetMixerFPUMode(&oldMode);
2248 if(device->DefaultSlot)
2250 ALeffectslot *slot = device->DefaultSlot;
2251 ALeffectState *state = slot->Effect.State;
2253 state->OutBuffer = device->Dry.Buffer;
2254 state->OutChannels = device->Dry.NumChannels;
2255 if(V(state,deviceUpdate)(device) == AL_FALSE)
2256 update_failed = AL_TRUE;
2257 else
2258 UpdateEffectSlotProps(slot);
2261 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2262 while(context)
2264 ALsizei pos;
2266 WriteLock(&context->PropLock);
2267 LockUIntMapRead(&context->EffectSlotMap);
2268 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2270 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2271 ALeffectState *state = slot->Effect.State;
2273 state->OutBuffer = device->Dry.Buffer;
2274 state->OutChannels = device->Dry.NumChannels;
2275 if(V(state,deviceUpdate)(device) == AL_FALSE)
2276 update_failed = AL_TRUE;
2277 else
2278 UpdateEffectSlotProps(slot);
2280 UnlockUIntMapRead(&context->EffectSlotMap);
2282 LockUIntMapRead(&context->SourceMap);
2283 RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax);
2284 for(pos = 0;pos < context->SourceMap.size;pos++)
2286 ALsource *source = context->SourceMap.values[pos];
2288 if(old_sends != device->NumAuxSends)
2290 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2291 ALsizei s;
2293 memcpy(sends, source->Send,
2294 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2296 for(s = device->NumAuxSends;s < old_sends;s++)
2298 if(source->Send[s].Slot)
2299 DecrementRef(&source->Send[s].Slot->ref);
2300 source->Send[s].Slot = NULL;
2302 al_free(source->Send);
2303 source->Send = sends;
2304 for(s = old_sends;s < device->NumAuxSends;s++)
2306 source->Send[s].Slot = NULL;
2307 source->Send[s].Gain = 1.0f;
2308 source->Send[s].GainHF = 1.0f;
2309 source->Send[s].HFReference = LOWPASSFREQREF;
2310 source->Send[s].GainLF = 1.0f;
2311 source->Send[s].LFReference = HIGHPASSFREQREF;
2315 ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
2317 AllocateVoices(context, context->MaxVoices, old_sends);
2318 for(pos = 0;pos < context->VoiceCount;pos++)
2320 ALvoice *voice = context->Voices[pos];
2321 struct ALvoiceProps *props;
2323 /* Clear any pre-existing voice property structs, in case the
2324 * number of auxiliary sends changed. Active sources will have
2325 * updates respecified in UpdateAllSourceProps.
2327 props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed);
2328 al_free(props);
2330 props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
2331 while(props)
2333 struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
2334 al_free(props);
2335 props = next;
2338 if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
2339 continue;
2341 if(device->AvgSpeakerDist > 0.0f)
2343 /* Reinitialize the NFC filters for new parameters. */
2344 ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
2345 (device->AvgSpeakerDist * device->Frequency);
2346 for(i = 0;i < voice->NumChannels;i++)
2348 NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1);
2349 NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1);
2350 NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1);
2354 UnlockUIntMapRead(&context->SourceMap);
2356 UpdateListenerProps(context);
2357 UpdateAllSourceProps(context);
2358 WriteUnlock(&context->PropLock);
2360 context = context->next;
2362 RestoreFPUMode(&oldMode);
2363 if(update_failed)
2364 return ALC_INVALID_DEVICE;
2366 if(!(device->Flags&DEVICE_PAUSED))
2368 if(V0(device->Backend,start)() == ALC_FALSE)
2369 return ALC_INVALID_DEVICE;
2370 device->Flags |= DEVICE_RUNNING;
2373 return ALC_NO_ERROR;
2376 /* FreeDevice
2378 * Frees the device structure, and destroys any objects the app failed to
2379 * delete. Called once there's no more references on the device.
2381 static ALCvoid FreeDevice(ALCdevice *device)
2383 ALsizei i;
2385 TRACE("%p\n", device);
2387 V0(device->Backend,close)();
2388 DELETE_OBJ(device->Backend);
2389 device->Backend = NULL;
2391 almtx_destroy(&device->BackendLock);
2393 if(device->DefaultSlot)
2395 DeinitEffectSlot(device->DefaultSlot);
2396 device->DefaultSlot = NULL;
2399 if(device->BufferMap.size > 0)
2401 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2402 (device->BufferMap.size==1)?"":"s");
2403 ReleaseALBuffers(device);
2405 ResetUIntMap(&device->BufferMap);
2407 if(device->EffectMap.size > 0)
2409 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2410 (device->EffectMap.size==1)?"":"s");
2411 ReleaseALEffects(device);
2413 ResetUIntMap(&device->EffectMap);
2415 if(device->FilterMap.size > 0)
2417 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2418 (device->FilterMap.size==1)?"":"s");
2419 ReleaseALFilters(device);
2421 ResetUIntMap(&device->FilterMap);
2423 AL_STRING_DEINIT(device->HrtfName);
2424 FreeHrtfList(&device->HrtfList);
2425 if(device->HrtfHandle)
2426 Hrtf_DecRef(device->HrtfHandle);
2427 device->HrtfHandle = NULL;
2428 al_free(device->Hrtf);
2429 device->Hrtf = NULL;
2431 al_free(device->Bs2b);
2432 device->Bs2b = NULL;
2434 al_free(device->Uhj_Encoder);
2435 device->Uhj_Encoder = NULL;
2437 bformatdec_free(device->AmbiDecoder);
2438 device->AmbiDecoder = NULL;
2440 ambiup_free(device->AmbiUp);
2441 device->AmbiUp = NULL;
2443 al_free(device->Limiter);
2444 device->Limiter = NULL;
2446 al_free(device->ChannelDelay[0].Buffer);
2447 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2449 device->ChannelDelay[i].Gain = 1.0f;
2450 device->ChannelDelay[i].Length = 0;
2451 device->ChannelDelay[i].Buffer = NULL;
2454 AL_STRING_DEINIT(device->DeviceName);
2456 al_free(device->Dry.Buffer);
2457 device->Dry.Buffer = NULL;
2458 device->Dry.NumChannels = 0;
2459 device->FOAOut.Buffer = NULL;
2460 device->FOAOut.NumChannels = 0;
2461 device->RealOut.Buffer = NULL;
2462 device->RealOut.NumChannels = 0;
2464 al_free(device);
2468 void ALCdevice_IncRef(ALCdevice *device)
2470 uint ref;
2471 ref = IncrementRef(&device->ref);
2472 TRACEREF("%p increasing refcount to %u\n", device, ref);
2475 void ALCdevice_DecRef(ALCdevice *device)
2477 uint ref;
2478 ref = DecrementRef(&device->ref);
2479 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2480 if(ref == 0) FreeDevice(device);
2483 /* VerifyDevice
2485 * Checks if the device handle is valid, and increments its ref count if so.
2487 static ALCboolean VerifyDevice(ALCdevice **device)
2489 ALCdevice *tmpDevice;
2491 LockLists();
2492 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2493 while(tmpDevice)
2495 if(tmpDevice == *device)
2497 ALCdevice_IncRef(tmpDevice);
2498 UnlockLists();
2499 return ALC_TRUE;
2501 tmpDevice = tmpDevice->next;
2503 UnlockLists();
2505 *device = NULL;
2506 return ALC_FALSE;
2510 /* InitContext
2512 * Initializes context fields
2514 static ALvoid InitContext(ALCcontext *Context)
2516 ALlistener *listener = Context->Listener;
2517 struct ALeffectslotArray *auxslots;
2519 //Initialise listener
2520 listener->Gain = 1.0f;
2521 listener->MetersPerUnit = 1.0f;
2522 listener->Position[0] = 0.0f;
2523 listener->Position[1] = 0.0f;
2524 listener->Position[2] = 0.0f;
2525 listener->Velocity[0] = 0.0f;
2526 listener->Velocity[1] = 0.0f;
2527 listener->Velocity[2] = 0.0f;
2528 listener->Forward[0] = 0.0f;
2529 listener->Forward[1] = 0.0f;
2530 listener->Forward[2] = -1.0f;
2531 listener->Up[0] = 0.0f;
2532 listener->Up[1] = 1.0f;
2533 listener->Up[2] = 0.0f;
2535 aluMatrixfSet(&listener->Params.Matrix,
2536 1.0f, 0.0f, 0.0f, 0.0f,
2537 0.0f, 1.0f, 0.0f, 0.0f,
2538 0.0f, 0.0f, 1.0f, 0.0f,
2539 0.0f, 0.0f, 0.0f, 1.0f
2541 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2542 listener->Params.Gain = 1.0f;
2543 listener->Params.MetersPerUnit = 1.0f;
2544 listener->Params.DopplerFactor = 1.0f;
2545 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2547 ATOMIC_INIT(&listener->Update, NULL);
2548 ATOMIC_INIT(&listener->FreeList, NULL);
2550 //Validate Context
2551 InitRef(&Context->UpdateCount, 0);
2552 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2553 Context->GainBoost = 1.0f;
2554 RWLockInit(&Context->PropLock);
2555 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2556 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2557 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2559 auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray));
2560 auxslots->count = 0;
2561 ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots);
2563 //Set globals
2564 Context->DistanceModel = DefaultDistanceModel;
2565 Context->SourceDistanceModel = AL_FALSE;
2566 Context->DopplerFactor = 1.0f;
2567 Context->DopplerVelocity = 1.0f;
2568 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2569 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2571 Context->ExtensionList = alExtList;
2575 /* FreeContext
2577 * Cleans up the context, and destroys any remaining objects the app failed to
2578 * delete. Called once there's no more references on the context.
2580 static void FreeContext(ALCcontext *context)
2582 ALlistener *listener = context->Listener;
2583 struct ALeffectslotArray *auxslots;
2584 struct ALlistenerProps *lprops;
2585 size_t count;
2586 ALsizei i;
2588 TRACE("%p\n", context);
2590 auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
2591 al_free(auxslots);
2593 if(context->SourceMap.size > 0)
2595 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2596 (context->SourceMap.size==1)?"":"s");
2597 ReleaseALSources(context);
2599 ResetUIntMap(&context->SourceMap);
2601 if(context->EffectSlotMap.size > 0)
2603 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2604 (context->EffectSlotMap.size==1)?"":"s");
2605 ReleaseALAuxiliaryEffectSlots(context);
2607 ResetUIntMap(&context->EffectSlotMap);
2609 for(i = 0;i < context->VoiceCount;i++)
2610 DeinitVoice(context->Voices[i]);
2611 al_free(context->Voices);
2612 context->Voices = NULL;
2613 context->VoiceCount = 0;
2614 context->MaxVoices = 0;
2616 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2618 TRACE("Freed unapplied listener update %p\n", lprops);
2619 al_free(lprops);
2621 count = 0;
2622 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
2623 while(lprops)
2625 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2626 al_free(lprops);
2627 lprops = next;
2628 ++count;
2630 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2632 ALCdevice_DecRef(context->Device);
2633 context->Device = NULL;
2635 //Invalidate context
2636 memset(context, 0, sizeof(ALCcontext));
2637 al_free(context);
2640 /* ReleaseContext
2642 * Removes the context reference from the given device and removes it from
2643 * being current on the running thread or globally. Returns true if other
2644 * contexts still exist on the device.
2646 static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
2648 ALCcontext *origctx, *newhead;
2649 bool ret = true;
2651 if(altss_get(LocalContext) == context)
2653 WARN("%p released while current on thread\n", context);
2654 altss_set(LocalContext, NULL);
2655 ALCcontext_DecRef(context);
2658 origctx = context;
2659 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
2660 ALCcontext_DecRef(context);
2662 ALCdevice_Lock(device);
2663 origctx = context;
2664 newhead = context->next;
2665 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
2667 ALCcontext *volatile*list = &origctx->next;
2668 while(*list)
2670 if(*list == context)
2672 *list = (*list)->next;
2673 break;
2675 list = &(*list)->next;
2678 else
2679 ret = !!newhead;
2680 ALCdevice_Unlock(device);
2682 ALCcontext_DecRef(context);
2683 return ret;
2686 void ALCcontext_IncRef(ALCcontext *context)
2688 uint ref = IncrementRef(&context->ref);
2689 TRACEREF("%p increasing refcount to %u\n", context, ref);
2692 void ALCcontext_DecRef(ALCcontext *context)
2694 uint ref = DecrementRef(&context->ref);
2695 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2696 if(ref == 0) FreeContext(context);
2699 static void ReleaseThreadCtx(void *ptr)
2701 ALCcontext *context = ptr;
2702 uint ref = DecrementRef(&context->ref);
2703 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2704 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2707 /* VerifyContext
2709 * Checks that the given context is valid, and increments its reference count.
2711 static ALCboolean VerifyContext(ALCcontext **context)
2713 ALCdevice *dev;
2715 LockLists();
2716 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2717 while(dev)
2719 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2720 while(ctx)
2722 if(ctx == *context)
2724 ALCcontext_IncRef(ctx);
2725 UnlockLists();
2726 return ALC_TRUE;
2728 ctx = ctx->next;
2730 dev = dev->next;
2732 UnlockLists();
2734 *context = NULL;
2735 return ALC_FALSE;
2739 /* GetContextRef
2741 * Returns the currently active context for this thread, and adds a reference
2742 * without locking it.
2744 ALCcontext *GetContextRef(void)
2746 ALCcontext *context;
2748 context = altss_get(LocalContext);
2749 if(context)
2750 ALCcontext_IncRef(context);
2751 else
2753 LockLists();
2754 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2755 if(context)
2756 ALCcontext_IncRef(context);
2757 UnlockLists();
2760 return context;
2764 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2766 ALCdevice *device = context->Device;
2767 ALsizei num_sends = device->NumAuxSends;
2768 struct ALvoiceProps *props;
2769 size_t sizeof_props;
2770 size_t sizeof_voice;
2771 ALvoice **voices;
2772 ALvoice *voice;
2773 ALsizei v = 0;
2774 size_t size;
2776 if(num_voices == context->MaxVoices && num_sends == old_sends)
2777 return;
2779 /* Allocate the voice pointers, voices, and the voices' stored source
2780 * property set (including the dynamically-sized Send[] array) in one
2781 * chunk.
2783 sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
2784 sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
2785 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2787 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2788 /* The voice and property objects are stored interleaved since they're
2789 * paired together.
2791 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2792 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2794 if(context->Voices)
2796 const ALsizei v_count = mini(context->VoiceCount, num_voices);
2797 const ALsizei s_count = mini(old_sends, num_sends);
2799 for(;v < v_count;v++)
2801 ALvoice *old_voice = context->Voices[v];
2802 ALsizei i;
2804 /* Copy the old voice data and source property set to the new
2805 * storage.
2807 *voice = *old_voice;
2808 for(i = 0;i < s_count;i++)
2809 voice->Send[i] = old_voice->Send[i];
2810 *props = *(old_voice->Props);
2811 for(i = 0;i < s_count;i++)
2812 props->Send[i] = old_voice->Props->Send[i];
2814 /* Set this voice's property set pointer and voice reference. */
2815 voice->Props = props;
2816 voices[v] = voice;
2818 /* Increment pointers to the next storage space. */
2819 voice = (ALvoice*)((char*)props + sizeof_props);
2820 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2822 /* Deinit any left over voices that weren't copied over to the new
2823 * array. NOTE: If this does anything, v equals num_voices and
2824 * num_voices is less than VoiceCount, so the following loop won't do
2825 * anything.
2827 for(;v < context->VoiceCount;v++)
2828 DeinitVoice(context->Voices[v]);
2830 /* Finish setting the voices' property set pointers and references. */
2831 for(;v < num_voices;v++)
2833 ATOMIC_INIT(&voice->Update, NULL);
2834 ATOMIC_INIT(&voice->FreeList, NULL);
2836 voice->Props = props;
2837 voices[v] = voice;
2839 voice = (ALvoice*)((char*)props + sizeof_props);
2840 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2843 al_free(context->Voices);
2844 context->Voices = voices;
2845 context->MaxVoices = num_voices;
2846 context->VoiceCount = mini(context->VoiceCount, num_voices);
2850 /************************************************
2851 * Standard ALC functions
2852 ************************************************/
2854 /* alcGetError
2856 * Return last ALC generated error code for the given device
2858 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2860 ALCenum errorCode;
2862 if(VerifyDevice(&device))
2864 errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
2865 ALCdevice_DecRef(device);
2867 else
2868 errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
2870 return errorCode;
2874 /* alcSuspendContext
2876 * Suspends updates for the given context
2878 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2880 if(!SuspendDefers)
2881 return;
2883 if(!VerifyContext(&context))
2884 alcSetError(NULL, ALC_INVALID_CONTEXT);
2885 else
2887 ALCcontext_DeferUpdates(context);
2888 ALCcontext_DecRef(context);
2892 /* alcProcessContext
2894 * Resumes processing updates for the given context
2896 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2898 if(!SuspendDefers)
2899 return;
2901 if(!VerifyContext(&context))
2902 alcSetError(NULL, ALC_INVALID_CONTEXT);
2903 else
2905 ALCcontext_ProcessUpdates(context);
2906 ALCcontext_DecRef(context);
2911 /* alcGetString
2913 * Returns information about the device, and error strings
2915 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2917 const ALCchar *value = NULL;
2919 switch(param)
2921 case ALC_NO_ERROR:
2922 value = alcNoError;
2923 break;
2925 case ALC_INVALID_ENUM:
2926 value = alcErrInvalidEnum;
2927 break;
2929 case ALC_INVALID_VALUE:
2930 value = alcErrInvalidValue;
2931 break;
2933 case ALC_INVALID_DEVICE:
2934 value = alcErrInvalidDevice;
2935 break;
2937 case ALC_INVALID_CONTEXT:
2938 value = alcErrInvalidContext;
2939 break;
2941 case ALC_OUT_OF_MEMORY:
2942 value = alcErrOutOfMemory;
2943 break;
2945 case ALC_DEVICE_SPECIFIER:
2946 value = alcDefaultName;
2947 break;
2949 case ALC_ALL_DEVICES_SPECIFIER:
2950 if(VerifyDevice(&Device))
2952 value = alstr_get_cstr(Device->DeviceName);
2953 ALCdevice_DecRef(Device);
2955 else
2957 ProbeAllDevicesList();
2958 value = alstr_get_cstr(alcAllDevicesList);
2960 break;
2962 case ALC_CAPTURE_DEVICE_SPECIFIER:
2963 if(VerifyDevice(&Device))
2965 value = alstr_get_cstr(Device->DeviceName);
2966 ALCdevice_DecRef(Device);
2968 else
2970 ProbeCaptureDeviceList();
2971 value = alstr_get_cstr(alcCaptureDeviceList);
2973 break;
2975 /* Default devices are always first in the list */
2976 case ALC_DEFAULT_DEVICE_SPECIFIER:
2977 value = alcDefaultName;
2978 break;
2980 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2981 if(alstr_empty(alcAllDevicesList))
2982 ProbeAllDevicesList();
2984 VerifyDevice(&Device);
2986 free(alcDefaultAllDevicesSpecifier);
2987 alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
2988 if(!alcDefaultAllDevicesSpecifier)
2989 alcSetError(Device, ALC_OUT_OF_MEMORY);
2991 value = alcDefaultAllDevicesSpecifier;
2992 if(Device) ALCdevice_DecRef(Device);
2993 break;
2995 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2996 if(alstr_empty(alcCaptureDeviceList))
2997 ProbeCaptureDeviceList();
2999 VerifyDevice(&Device);
3001 free(alcCaptureDefaultDeviceSpecifier);
3002 alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
3003 if(!alcCaptureDefaultDeviceSpecifier)
3004 alcSetError(Device, ALC_OUT_OF_MEMORY);
3006 value = alcCaptureDefaultDeviceSpecifier;
3007 if(Device) ALCdevice_DecRef(Device);
3008 break;
3010 case ALC_EXTENSIONS:
3011 if(!VerifyDevice(&Device))
3012 value = alcNoDeviceExtList;
3013 else
3015 value = alcExtensionList;
3016 ALCdevice_DecRef(Device);
3018 break;
3020 case ALC_HRTF_SPECIFIER_SOFT:
3021 if(!VerifyDevice(&Device))
3022 alcSetError(NULL, ALC_INVALID_DEVICE);
3023 else
3025 almtx_lock(&Device->BackendLock);
3026 value = (Device->HrtfHandle ? alstr_get_cstr(Device->HrtfName) : "");
3027 almtx_unlock(&Device->BackendLock);
3028 ALCdevice_DecRef(Device);
3030 break;
3032 default:
3033 VerifyDevice(&Device);
3034 alcSetError(Device, ALC_INVALID_ENUM);
3035 if(Device) ALCdevice_DecRef(Device);
3036 break;
3039 return value;
3043 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
3045 if(device->Type == Loopback && device->FmtChans == DevFmtAmbi3D)
3046 return 25;
3047 return 19;
3050 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3052 ALCsizei i;
3054 if(size <= 0 || values == NULL)
3056 alcSetError(device, ALC_INVALID_VALUE);
3057 return 0;
3060 if(!device)
3062 switch(param)
3064 case ALC_MAJOR_VERSION:
3065 values[0] = alcMajorVersion;
3066 return 1;
3067 case ALC_MINOR_VERSION:
3068 values[0] = alcMinorVersion;
3069 return 1;
3071 case ALC_ATTRIBUTES_SIZE:
3072 case ALC_ALL_ATTRIBUTES:
3073 case ALC_FREQUENCY:
3074 case ALC_REFRESH:
3075 case ALC_SYNC:
3076 case ALC_MONO_SOURCES:
3077 case ALC_STEREO_SOURCES:
3078 case ALC_CAPTURE_SAMPLES:
3079 case ALC_FORMAT_CHANNELS_SOFT:
3080 case ALC_FORMAT_TYPE_SOFT:
3081 case ALC_AMBISONIC_LAYOUT_SOFT:
3082 case ALC_AMBISONIC_SCALING_SOFT:
3083 case ALC_AMBISONIC_ORDER_SOFT:
3084 alcSetError(NULL, ALC_INVALID_DEVICE);
3085 return 0;
3087 default:
3088 alcSetError(NULL, ALC_INVALID_ENUM);
3089 return 0;
3091 return 0;
3094 if(device->Type == Capture)
3096 switch(param)
3098 case ALC_CAPTURE_SAMPLES:
3099 almtx_lock(&device->BackendLock);
3100 values[0] = V0(device->Backend,availableSamples)();
3101 almtx_unlock(&device->BackendLock);
3102 return 1;
3104 case ALC_CONNECTED:
3105 values[0] = device->Connected;
3106 return 1;
3108 default:
3109 alcSetError(device, ALC_INVALID_ENUM);
3110 return 0;
3112 return 0;
3115 /* render device */
3116 switch(param)
3118 case ALC_MAJOR_VERSION:
3119 values[0] = alcMajorVersion;
3120 return 1;
3122 case ALC_MINOR_VERSION:
3123 values[0] = alcMinorVersion;
3124 return 1;
3126 case ALC_EFX_MAJOR_VERSION:
3127 values[0] = alcEFXMajorVersion;
3128 return 1;
3130 case ALC_EFX_MINOR_VERSION:
3131 values[0] = alcEFXMinorVersion;
3132 return 1;
3134 case ALC_ATTRIBUTES_SIZE:
3135 values[0] = NumAttrsForDevice(device);
3136 return 1;
3138 case ALC_ALL_ATTRIBUTES:
3139 if(size < NumAttrsForDevice(device))
3141 alcSetError(device, ALC_INVALID_VALUE);
3142 return 0;
3145 i = 0;
3146 almtx_lock(&device->BackendLock);
3147 values[i++] = ALC_FREQUENCY;
3148 values[i++] = device->Frequency;
3150 if(device->Type != Loopback)
3152 values[i++] = ALC_REFRESH;
3153 values[i++] = device->Frequency / device->UpdateSize;
3155 values[i++] = ALC_SYNC;
3156 values[i++] = ALC_FALSE;
3158 else
3160 if(device->FmtChans == DevFmtAmbi3D)
3162 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3163 values[i++] = device->AmbiLayout;
3165 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3166 values[i++] = device->AmbiScale;
3168 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3169 values[i++] = device->AmbiOrder;
3172 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3173 values[i++] = device->FmtChans;
3175 values[i++] = ALC_FORMAT_TYPE_SOFT;
3176 values[i++] = device->FmtType;
3179 values[i++] = ALC_MONO_SOURCES;
3180 values[i++] = device->NumMonoSources;
3182 values[i++] = ALC_STEREO_SOURCES;
3183 values[i++] = device->NumStereoSources;
3185 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3186 values[i++] = device->NumAuxSends;
3188 values[i++] = ALC_HRTF_SOFT;
3189 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3191 values[i++] = ALC_HRTF_STATUS_SOFT;
3192 values[i++] = device->HrtfStatus;
3194 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3195 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3196 almtx_unlock(&device->BackendLock);
3198 values[i++] = 0;
3199 return i;
3201 case ALC_FREQUENCY:
3202 values[0] = device->Frequency;
3203 return 1;
3205 case ALC_REFRESH:
3206 if(device->Type == Loopback)
3208 alcSetError(device, ALC_INVALID_DEVICE);
3209 return 0;
3211 almtx_lock(&device->BackendLock);
3212 values[0] = device->Frequency / device->UpdateSize;
3213 almtx_unlock(&device->BackendLock);
3214 return 1;
3216 case ALC_SYNC:
3217 if(device->Type == Loopback)
3219 alcSetError(device, ALC_INVALID_DEVICE);
3220 return 0;
3222 values[0] = ALC_FALSE;
3223 return 1;
3225 case ALC_FORMAT_CHANNELS_SOFT:
3226 if(device->Type != Loopback)
3228 alcSetError(device, ALC_INVALID_DEVICE);
3229 return 0;
3231 values[0] = device->FmtChans;
3232 return 1;
3234 case ALC_FORMAT_TYPE_SOFT:
3235 if(device->Type != Loopback)
3237 alcSetError(device, ALC_INVALID_DEVICE);
3238 return 0;
3240 values[0] = device->FmtType;
3241 return 1;
3243 case ALC_AMBISONIC_LAYOUT_SOFT:
3244 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3246 alcSetError(device, ALC_INVALID_DEVICE);
3247 return 0;
3249 values[0] = device->AmbiLayout;
3250 return 1;
3252 case ALC_AMBISONIC_SCALING_SOFT:
3253 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3255 alcSetError(device, ALC_INVALID_DEVICE);
3256 return 0;
3258 values[0] = device->AmbiScale;
3259 return 1;
3261 case ALC_AMBISONIC_ORDER_SOFT:
3262 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3264 alcSetError(device, ALC_INVALID_DEVICE);
3265 return 0;
3267 values[0] = device->AmbiOrder;
3268 return 1;
3270 case ALC_MONO_SOURCES:
3271 values[0] = device->NumMonoSources;
3272 return 1;
3274 case ALC_STEREO_SOURCES:
3275 values[0] = device->NumStereoSources;
3276 return 1;
3278 case ALC_MAX_AUXILIARY_SENDS:
3279 values[0] = device->NumAuxSends;
3280 return 1;
3282 case ALC_CONNECTED:
3283 values[0] = device->Connected;
3284 return 1;
3286 case ALC_HRTF_SOFT:
3287 values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3288 return 1;
3290 case ALC_HRTF_STATUS_SOFT:
3291 values[0] = device->HrtfStatus;
3292 return 1;
3294 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3295 almtx_lock(&device->BackendLock);
3296 FreeHrtfList(&device->HrtfList);
3297 device->HrtfList = EnumerateHrtf(device->DeviceName);
3298 values[0] = (ALCint)VECTOR_SIZE(device->HrtfList);
3299 almtx_unlock(&device->BackendLock);
3300 return 1;
3302 case ALC_OUTPUT_LIMITER_SOFT:
3303 values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3304 return 1;
3306 default:
3307 alcSetError(device, ALC_INVALID_ENUM);
3308 return 0;
3310 return 0;
3313 /* alcGetIntegerv
3315 * Returns information about the device and the version of OpenAL
3317 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3319 VerifyDevice(&device);
3320 if(size <= 0 || values == NULL)
3321 alcSetError(device, ALC_INVALID_VALUE);
3322 else
3323 GetIntegerv(device, param, size, values);
3324 if(device) ALCdevice_DecRef(device);
3327 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3329 ALCint *ivals;
3330 ALsizei i;
3332 VerifyDevice(&device);
3333 if(size <= 0 || values == NULL)
3334 alcSetError(device, ALC_INVALID_VALUE);
3335 else if(!device || device->Type == Capture)
3337 ivals = malloc(size * sizeof(ALCint));
3338 size = GetIntegerv(device, pname, size, ivals);
3339 for(i = 0;i < size;i++)
3340 values[i] = ivals[i];
3341 free(ivals);
3343 else /* render device */
3345 ClockLatency clock;
3346 ALuint64 basecount;
3347 ALuint samplecount;
3348 ALuint refcount;
3350 switch(pname)
3352 case ALC_ATTRIBUTES_SIZE:
3353 *values = NumAttrsForDevice(device)+4;
3354 break;
3356 case ALC_ALL_ATTRIBUTES:
3357 if(size < NumAttrsForDevice(device)+4)
3358 alcSetError(device, ALC_INVALID_VALUE);
3359 else
3361 i = 0;
3362 almtx_lock(&device->BackendLock);
3363 values[i++] = ALC_FREQUENCY;
3364 values[i++] = device->Frequency;
3366 if(device->Type != Loopback)
3368 values[i++] = ALC_REFRESH;
3369 values[i++] = device->Frequency / device->UpdateSize;
3371 values[i++] = ALC_SYNC;
3372 values[i++] = ALC_FALSE;
3374 else
3376 if(device->FmtChans == DevFmtAmbi3D)
3378 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3379 values[i++] = device->AmbiLayout;
3381 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3382 values[i++] = device->AmbiScale;
3384 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3385 values[i++] = device->AmbiOrder;
3388 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3389 values[i++] = device->FmtChans;
3391 values[i++] = ALC_FORMAT_TYPE_SOFT;
3392 values[i++] = device->FmtType;
3395 values[i++] = ALC_MONO_SOURCES;
3396 values[i++] = device->NumMonoSources;
3398 values[i++] = ALC_STEREO_SOURCES;
3399 values[i++] = device->NumStereoSources;
3401 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3402 values[i++] = device->NumAuxSends;
3404 values[i++] = ALC_HRTF_SOFT;
3405 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3407 values[i++] = ALC_HRTF_STATUS_SOFT;
3408 values[i++] = device->HrtfStatus;
3410 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3411 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3413 clock = V0(device->Backend,getClockLatency)();
3414 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3415 values[i++] = clock.ClockTime;
3417 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3418 values[i++] = clock.Latency;
3419 almtx_unlock(&device->BackendLock);
3421 values[i++] = 0;
3423 break;
3425 case ALC_DEVICE_CLOCK_SOFT:
3426 almtx_lock(&device->BackendLock);
3427 do {
3428 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3429 althrd_yield();
3430 basecount = device->ClockBase;
3431 samplecount = device->SamplesDone;
3432 } while(refcount != ReadRef(&device->MixCount));
3433 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3434 almtx_unlock(&device->BackendLock);
3435 break;
3437 case ALC_DEVICE_LATENCY_SOFT:
3438 almtx_lock(&device->BackendLock);
3439 clock = V0(device->Backend,getClockLatency)();
3440 almtx_unlock(&device->BackendLock);
3441 *values = clock.Latency;
3442 break;
3444 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3445 if(size < 2)
3446 alcSetError(device, ALC_INVALID_VALUE);
3447 else
3449 almtx_lock(&device->BackendLock);
3450 clock = V0(device->Backend,getClockLatency)();
3451 almtx_unlock(&device->BackendLock);
3452 values[0] = clock.ClockTime;
3453 values[1] = clock.Latency;
3455 break;
3457 default:
3458 ivals = malloc(size * sizeof(ALCint));
3459 size = GetIntegerv(device, pname, size, ivals);
3460 for(i = 0;i < size;i++)
3461 values[i] = ivals[i];
3462 free(ivals);
3463 break;
3466 if(device)
3467 ALCdevice_DecRef(device);
3471 /* alcIsExtensionPresent
3473 * Determines if there is support for a particular extension
3475 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3477 ALCboolean bResult = ALC_FALSE;
3479 VerifyDevice(&device);
3481 if(!extName)
3482 alcSetError(device, ALC_INVALID_VALUE);
3483 else
3485 size_t len = strlen(extName);
3486 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3487 while(ptr && *ptr)
3489 if(strncasecmp(ptr, extName, len) == 0 &&
3490 (ptr[len] == '\0' || isspace(ptr[len])))
3492 bResult = ALC_TRUE;
3493 break;
3495 if((ptr=strchr(ptr, ' ')) != NULL)
3497 do {
3498 ++ptr;
3499 } while(isspace(*ptr));
3503 if(device)
3504 ALCdevice_DecRef(device);
3505 return bResult;
3509 /* alcGetProcAddress
3511 * Retrieves the function address for a particular extension function
3513 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3515 ALCvoid *ptr = NULL;
3517 if(!funcName)
3519 VerifyDevice(&device);
3520 alcSetError(device, ALC_INVALID_VALUE);
3521 if(device) ALCdevice_DecRef(device);
3523 else
3525 size_t i = 0;
3526 for(i = 0;i < COUNTOF(alcFunctions);i++)
3528 if(strcmp(alcFunctions[i].funcName, funcName) == 0)
3530 ptr = alcFunctions[i].address;
3531 break;
3536 return ptr;
3540 /* alcGetEnumValue
3542 * Get the value for a particular ALC enumeration name
3544 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3546 ALCenum val = 0;
3548 if(!enumName)
3550 VerifyDevice(&device);
3551 alcSetError(device, ALC_INVALID_VALUE);
3552 if(device) ALCdevice_DecRef(device);
3554 else
3556 size_t i = 0;
3557 for(i = 0;i < COUNTOF(alcEnumerations);i++)
3559 if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
3561 val = alcEnumerations[i].value;
3562 break;
3567 return val;
3571 /* alcCreateContext
3573 * Create and attach a context to the given device.
3575 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3577 ALCcontext *ALContext;
3578 ALfloat valf;
3579 ALCenum err;
3581 /* Explicitly hold the list lock while taking the BackendLock in case the
3582 * device is asynchronously destropyed, to ensure this new context is
3583 * properly cleaned up after being made.
3585 LockLists();
3586 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3588 UnlockLists();
3589 alcSetError(device, ALC_INVALID_DEVICE);
3590 if(device) ALCdevice_DecRef(device);
3591 return NULL;
3593 almtx_lock(&device->BackendLock);
3594 UnlockLists();
3596 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3598 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3599 if(!ALContext)
3601 almtx_unlock(&device->BackendLock);
3603 alcSetError(device, ALC_OUT_OF_MEMORY);
3604 ALCdevice_DecRef(device);
3605 return NULL;
3608 InitRef(&ALContext->ref, 1);
3609 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3611 ALContext->Voices = NULL;
3612 ALContext->VoiceCount = 0;
3613 ALContext->MaxVoices = 0;
3614 ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL);
3615 ALContext->Device = device;
3617 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3619 almtx_unlock(&device->BackendLock);
3621 al_free(ALContext->Voices);
3622 ALContext->Voices = NULL;
3624 al_free(ALContext);
3625 ALContext = NULL;
3627 alcSetError(device, err);
3628 if(err == ALC_INVALID_DEVICE)
3630 V0(device->Backend,lock)();
3631 aluHandleDisconnect(device);
3632 V0(device->Backend,unlock)();
3634 ALCdevice_DecRef(device);
3635 return NULL;
3637 AllocateVoices(ALContext, 256, device->NumAuxSends);
3639 ALCdevice_IncRef(ALContext->Device);
3640 InitContext(ALContext);
3642 if(ConfigValueFloat(alstr_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3644 if(!isfinite(valf))
3645 ERR("volume-adjust must be finite: %f\n", valf);
3646 else
3648 ALfloat db = clampf(valf, -24.0f, 24.0f);
3649 if(db != valf)
3650 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3651 ALContext->GainBoost = powf(10.0f, db/20.0f);
3652 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3655 UpdateListenerProps(ALContext);
3658 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3659 do {
3660 ALContext->next = head;
3661 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
3662 ALContext) == 0);
3664 almtx_unlock(&device->BackendLock);
3666 ALCdevice_DecRef(device);
3668 TRACE("Created context %p\n", ALContext);
3669 return ALContext;
3672 /* alcDestroyContext
3674 * Remove a context from its device
3676 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3678 ALCdevice *Device;
3680 LockLists();
3681 if(!VerifyContext(&context))
3683 UnlockLists();
3684 alcSetError(NULL, ALC_INVALID_CONTEXT);
3685 return;
3688 Device = context->Device;
3689 if(Device)
3691 almtx_lock(&Device->BackendLock);
3692 if(!ReleaseContext(context, Device))
3694 V0(Device->Backend,stop)();
3695 Device->Flags &= ~DEVICE_RUNNING;
3697 almtx_unlock(&Device->BackendLock);
3699 UnlockLists();
3701 ALCcontext_DecRef(context);
3705 /* alcGetCurrentContext
3707 * Returns the currently active context on the calling thread
3709 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3711 ALCcontext *Context = altss_get(LocalContext);
3712 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3713 return Context;
3716 /* alcGetThreadContext
3718 * Returns the currently active thread-local context
3720 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3722 return altss_get(LocalContext);
3726 /* alcMakeContextCurrent
3728 * Makes the given context the active process-wide context, and removes the
3729 * thread-local context for the calling thread.
3731 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3733 /* context must be valid or NULL */
3734 if(context && !VerifyContext(&context))
3736 alcSetError(NULL, ALC_INVALID_CONTEXT);
3737 return ALC_FALSE;
3739 /* context's reference count is already incremented */
3740 context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
3741 if(context) ALCcontext_DecRef(context);
3743 if((context=altss_get(LocalContext)) != NULL)
3745 altss_set(LocalContext, NULL);
3746 ALCcontext_DecRef(context);
3749 return ALC_TRUE;
3752 /* alcSetThreadContext
3754 * Makes the given context the active context for the current thread
3756 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3758 ALCcontext *old;
3760 /* context must be valid or NULL */
3761 if(context && !VerifyContext(&context))
3763 alcSetError(NULL, ALC_INVALID_CONTEXT);
3764 return ALC_FALSE;
3766 /* context's reference count is already incremented */
3767 old = altss_get(LocalContext);
3768 altss_set(LocalContext, context);
3769 if(old) ALCcontext_DecRef(old);
3771 return ALC_TRUE;
3775 /* alcGetContextsDevice
3777 * Returns the device that a particular context is attached to
3779 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3781 ALCdevice *Device;
3783 if(!VerifyContext(&Context))
3785 alcSetError(NULL, ALC_INVALID_CONTEXT);
3786 return NULL;
3788 Device = Context->Device;
3789 ALCcontext_DecRef(Context);
3791 return Device;
3795 /* alcOpenDevice
3797 * Opens the named device.
3799 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3801 ALCbackendFactory *factory;
3802 const ALCchar *fmt;
3803 ALCdevice *device;
3804 ALCenum err;
3805 ALCsizei i;
3807 DO_INITCONFIG();
3809 if(!PlaybackBackend.name)
3811 alcSetError(NULL, ALC_INVALID_VALUE);
3812 return NULL;
3815 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3816 #ifdef _WIN32
3817 /* Some old Windows apps hardcode these expecting OpenAL to use a
3818 * specific audio API, even when they're not enumerated. Creative's
3819 * router effectively ignores them too.
3821 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3822 || strcasecmp(deviceName, "MMSYSTEM") == 0
3823 #endif
3825 deviceName = NULL;
3827 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3828 if(!device)
3830 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3831 return NULL;
3834 //Validate device
3835 InitRef(&device->ref, 1);
3836 device->Connected = ALC_TRUE;
3837 device->Type = Playback;
3838 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3840 device->Flags = 0;
3841 device->Bs2b = NULL;
3842 device->Uhj_Encoder = NULL;
3843 device->Hrtf = NULL;
3844 device->HrtfHandle = NULL;
3845 VECTOR_INIT(device->HrtfList);
3846 AL_STRING_INIT(device->HrtfName);
3847 device->Render_Mode = NormalRender;
3848 AL_STRING_INIT(device->DeviceName);
3849 device->Dry.Buffer = NULL;
3850 device->Dry.NumChannels = 0;
3851 device->FOAOut.Buffer = NULL;
3852 device->FOAOut.NumChannels = 0;
3853 device->RealOut.Buffer = NULL;
3854 device->RealOut.NumChannels = 0;
3855 device->Limiter = NULL;
3856 device->AvgSpeakerDist = 0.0f;
3858 ATOMIC_INIT(&device->ContextList, NULL);
3860 device->ClockBase = 0;
3861 device->SamplesDone = 0;
3863 device->SourcesMax = 256;
3864 device->AuxiliaryEffectSlotMax = 64;
3865 device->NumAuxSends = DEFAULT_SENDS;
3867 InitUIntMap(&device->BufferMap, INT_MAX);
3868 InitUIntMap(&device->EffectMap, INT_MAX);
3869 InitUIntMap(&device->FilterMap, INT_MAX);
3871 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3873 device->ChannelDelay[i].Gain = 1.0f;
3874 device->ChannelDelay[i].Length = 0;
3875 device->ChannelDelay[i].Buffer = NULL;
3878 //Set output format
3879 device->FmtChans = DevFmtChannelsDefault;
3880 device->FmtType = DevFmtTypeDefault;
3881 device->Frequency = DEFAULT_OUTPUT_RATE;
3882 device->IsHeadphones = AL_FALSE;
3883 device->AmbiLayout = AmbiLayout_Default;
3884 device->AmbiScale = AmbiNorm_Default;
3885 device->NumUpdates = 3;
3886 device->UpdateSize = 1024;
3888 factory = PlaybackBackend.getFactory();
3889 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3890 if(!device->Backend)
3892 al_free(device);
3893 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3894 return NULL;
3898 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3900 static const struct {
3901 const char name[16];
3902 enum DevFmtChannels chans;
3903 ALsizei order;
3904 } chanlist[] = {
3905 { "mono", DevFmtMono, 0 },
3906 { "stereo", DevFmtStereo, 0 },
3907 { "quad", DevFmtQuad, 0 },
3908 { "surround51", DevFmtX51, 0 },
3909 { "surround61", DevFmtX61, 0 },
3910 { "surround71", DevFmtX71, 0 },
3911 { "surround51rear", DevFmtX51Rear, 0 },
3912 { "ambi1", DevFmtAmbi3D, 1 },
3913 { "ambi2", DevFmtAmbi3D, 2 },
3914 { "ambi3", DevFmtAmbi3D, 3 },
3916 size_t i;
3918 for(i = 0;i < COUNTOF(chanlist);i++)
3920 if(strcasecmp(chanlist[i].name, fmt) == 0)
3922 device->FmtChans = chanlist[i].chans;
3923 device->AmbiOrder = chanlist[i].order;
3924 device->Flags |= DEVICE_CHANNELS_REQUEST;
3925 break;
3928 if(i == COUNTOF(chanlist))
3929 ERR("Unsupported channels: %s\n", fmt);
3931 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3933 static const struct {
3934 const char name[16];
3935 enum DevFmtType type;
3936 } typelist[] = {
3937 { "int8", DevFmtByte },
3938 { "uint8", DevFmtUByte },
3939 { "int16", DevFmtShort },
3940 { "uint16", DevFmtUShort },
3941 { "int32", DevFmtInt },
3942 { "uint32", DevFmtUInt },
3943 { "float32", DevFmtFloat },
3945 size_t i;
3947 for(i = 0;i < COUNTOF(typelist);i++)
3949 if(strcasecmp(typelist[i].name, fmt) == 0)
3951 device->FmtType = typelist[i].type;
3952 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3953 break;
3956 if(i == COUNTOF(typelist))
3957 ERR("Unsupported sample-type: %s\n", fmt);
3960 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3962 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3963 if(device->Frequency < MIN_OUTPUT_RATE)
3964 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3965 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3968 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3969 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3971 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3972 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3973 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3974 device->UpdateSize = (device->UpdateSize+3)&~3;
3976 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
3977 if(device->SourcesMax == 0) device->SourcesMax = 256;
3979 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3980 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
3982 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
3983 device->NumAuxSends = clampi(
3984 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
3987 device->NumStereoSources = 1;
3988 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
3990 // Find a playback device to open
3991 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3993 DELETE_OBJ(device->Backend);
3994 al_free(device);
3995 alcSetError(NULL, err);
3996 return NULL;
3998 almtx_init(&device->BackendLock, almtx_plain);
4000 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
4002 if(strcasecmp(fmt, "fuma") == 0)
4004 device->AmbiLayout = AmbiLayout_FuMa;
4005 device->AmbiScale = AmbiNorm_FuMa;
4007 else if(strcasecmp(fmt, "acn+sn3d") == 0)
4009 device->AmbiLayout = AmbiLayout_ACN;
4010 device->AmbiScale = AmbiNorm_SN3D;
4012 else if(strcasecmp(fmt, "acn+n3d") == 0)
4014 device->AmbiLayout = AmbiLayout_ACN;
4015 device->AmbiScale = AmbiNorm_N3D;
4017 else
4018 ERR("Unsupported ambi-format: %s\n", fmt);
4021 device->Limiter = CreateDeviceLimiter(device);
4023 if(DefaultEffect.type != AL_EFFECT_NULL)
4025 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
4026 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
4028 device->DefaultSlot = NULL;
4029 ERR("Failed to initialize the default effect slot\n");
4031 else
4033 aluInitEffectPanning(device->DefaultSlot);
4034 if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
4036 DeinitEffectSlot(device->DefaultSlot);
4037 device->DefaultSlot = NULL;
4038 ERR("Failed to initialize the default effect\n");
4044 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4045 do {
4046 device->next = head;
4047 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4050 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4051 return device;
4054 /* alcCloseDevice
4056 * Closes the given device.
4058 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
4060 ALCdevice *iter, *origdev;
4061 ALCcontext *ctx;
4063 LockLists();
4064 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4065 do {
4066 if(iter == device)
4067 break;
4068 } while((iter=iter->next) != NULL);
4069 if(!iter || iter->Type == Capture)
4071 alcSetError(iter, ALC_INVALID_DEVICE);
4072 UnlockLists();
4073 return ALC_FALSE;
4075 almtx_lock(&device->BackendLock);
4077 origdev = device;
4078 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4080 ALCdevice *volatile*list = &origdev->next;
4081 while(*list)
4083 if(*list == device)
4085 *list = (*list)->next;
4086 break;
4088 list = &(*list)->next;
4091 UnlockLists();
4093 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
4094 while(ctx != NULL)
4096 ALCcontext *next = ctx->next;
4097 WARN("Releasing context %p\n", ctx);
4098 ReleaseContext(ctx, device);
4099 ctx = next;
4101 if((device->Flags&DEVICE_RUNNING))
4102 V0(device->Backend,stop)();
4103 device->Flags &= ~DEVICE_RUNNING;
4104 almtx_unlock(&device->BackendLock);
4106 ALCdevice_DecRef(device);
4108 return ALC_TRUE;
4112 /************************************************
4113 * ALC capture functions
4114 ************************************************/
4115 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4117 ALCbackendFactory *factory;
4118 ALCdevice *device = NULL;
4119 ALCenum err;
4120 ALCsizei i;
4122 DO_INITCONFIG();
4124 if(!CaptureBackend.name)
4126 alcSetError(NULL, ALC_INVALID_VALUE);
4127 return NULL;
4130 if(samples <= 0)
4132 alcSetError(NULL, ALC_INVALID_VALUE);
4133 return NULL;
4136 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4137 deviceName = NULL;
4139 device = al_calloc(16, sizeof(ALCdevice));
4140 if(!device)
4142 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4143 return NULL;
4146 //Validate device
4147 InitRef(&device->ref, 1);
4148 device->Connected = ALC_TRUE;
4149 device->Type = Capture;
4151 device->Hrtf = NULL;
4152 device->HrtfHandle = NULL;
4153 VECTOR_INIT(device->HrtfList);
4154 AL_STRING_INIT(device->HrtfName);
4156 AL_STRING_INIT(device->DeviceName);
4157 device->Dry.Buffer = NULL;
4158 device->Dry.NumChannels = 0;
4159 device->FOAOut.Buffer = NULL;
4160 device->FOAOut.NumChannels = 0;
4161 device->RealOut.Buffer = NULL;
4162 device->RealOut.NumChannels = 0;
4164 InitUIntMap(&device->BufferMap, INT_MAX);
4165 InitUIntMap(&device->EffectMap, INT_MAX);
4166 InitUIntMap(&device->FilterMap, INT_MAX);
4168 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4170 device->ChannelDelay[i].Gain = 1.0f;
4171 device->ChannelDelay[i].Length = 0;
4172 device->ChannelDelay[i].Buffer = NULL;
4175 factory = CaptureBackend.getFactory();
4176 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4177 if(!device->Backend)
4179 al_free(device);
4180 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4181 return NULL;
4184 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4185 device->Frequency = frequency;
4187 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4188 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4190 al_free(device);
4191 alcSetError(NULL, ALC_INVALID_ENUM);
4192 return NULL;
4194 device->IsHeadphones = AL_FALSE;
4195 device->AmbiOrder = 0;
4196 device->AmbiLayout = AmbiLayout_Default;
4197 device->AmbiScale = AmbiNorm_Default;
4199 device->UpdateSize = samples;
4200 device->NumUpdates = 1;
4202 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4203 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
4204 device->Frequency, device->UpdateSize, device->NumUpdates
4206 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4208 al_free(device);
4209 alcSetError(NULL, err);
4210 return NULL;
4212 almtx_init(&device->BackendLock, almtx_plain);
4215 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4216 do {
4217 device->next = head;
4218 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4221 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4222 return device;
4225 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4227 ALCdevice *iter, *origdev;
4229 LockLists();
4230 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4231 do {
4232 if(iter == device)
4233 break;
4234 } while((iter=iter->next) != NULL);
4235 if(!iter || iter->Type != Capture)
4237 alcSetError(iter, ALC_INVALID_DEVICE);
4238 UnlockLists();
4239 return ALC_FALSE;
4242 origdev = device;
4243 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4245 ALCdevice *volatile*list = &origdev->next;
4246 while(*list)
4248 if(*list == device)
4250 *list = (*list)->next;
4251 break;
4253 list = &(*list)->next;
4256 UnlockLists();
4258 ALCdevice_DecRef(device);
4260 return ALC_TRUE;
4263 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4265 if(!VerifyDevice(&device) || device->Type != Capture)
4266 alcSetError(device, ALC_INVALID_DEVICE);
4267 else
4269 almtx_lock(&device->BackendLock);
4270 if(!device->Connected)
4271 alcSetError(device, ALC_INVALID_DEVICE);
4272 else if(!(device->Flags&DEVICE_RUNNING))
4274 if(V0(device->Backend,start)())
4275 device->Flags |= DEVICE_RUNNING;
4276 else
4278 aluHandleDisconnect(device);
4279 alcSetError(device, ALC_INVALID_DEVICE);
4282 almtx_unlock(&device->BackendLock);
4285 if(device) ALCdevice_DecRef(device);
4288 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4290 if(!VerifyDevice(&device) || device->Type != Capture)
4291 alcSetError(device, ALC_INVALID_DEVICE);
4292 else
4294 almtx_lock(&device->BackendLock);
4295 if((device->Flags&DEVICE_RUNNING))
4296 V0(device->Backend,stop)();
4297 device->Flags &= ~DEVICE_RUNNING;
4298 almtx_unlock(&device->BackendLock);
4301 if(device) ALCdevice_DecRef(device);
4304 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4306 if(!VerifyDevice(&device) || device->Type != Capture)
4307 alcSetError(device, ALC_INVALID_DEVICE);
4308 else
4310 ALCenum err = ALC_INVALID_VALUE;
4312 almtx_lock(&device->BackendLock);
4313 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4314 err = V(device->Backend,captureSamples)(buffer, samples);
4315 almtx_unlock(&device->BackendLock);
4317 if(err != ALC_NO_ERROR)
4318 alcSetError(device, err);
4320 if(device) ALCdevice_DecRef(device);
4324 /************************************************
4325 * ALC loopback functions
4326 ************************************************/
4328 /* alcLoopbackOpenDeviceSOFT
4330 * Open a loopback device, for manual rendering.
4332 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4334 ALCbackendFactory *factory;
4335 ALCdevice *device;
4336 ALCsizei i;
4338 DO_INITCONFIG();
4340 /* Make sure the device name, if specified, is us. */
4341 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4343 alcSetError(NULL, ALC_INVALID_VALUE);
4344 return NULL;
4347 device = al_calloc(16, sizeof(ALCdevice));
4348 if(!device)
4350 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4351 return NULL;
4354 //Validate device
4355 InitRef(&device->ref, 1);
4356 device->Connected = ALC_TRUE;
4357 device->Type = Loopback;
4358 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4360 device->Flags = 0;
4361 device->Hrtf = NULL;
4362 device->HrtfHandle = NULL;
4363 VECTOR_INIT(device->HrtfList);
4364 AL_STRING_INIT(device->HrtfName);
4365 device->Bs2b = NULL;
4366 device->Uhj_Encoder = NULL;
4367 device->Render_Mode = NormalRender;
4368 AL_STRING_INIT(device->DeviceName);
4369 device->Dry.Buffer = NULL;
4370 device->Dry.NumChannels = 0;
4371 device->FOAOut.Buffer = NULL;
4372 device->FOAOut.NumChannels = 0;
4373 device->RealOut.Buffer = NULL;
4374 device->RealOut.NumChannels = 0;
4375 device->Limiter = NULL;
4376 device->AvgSpeakerDist = 0.0f;
4378 ATOMIC_INIT(&device->ContextList, NULL);
4380 device->ClockBase = 0;
4381 device->SamplesDone = 0;
4383 device->SourcesMax = 256;
4384 device->AuxiliaryEffectSlotMax = 64;
4385 device->NumAuxSends = DEFAULT_SENDS;
4387 InitUIntMap(&device->BufferMap, INT_MAX);
4388 InitUIntMap(&device->EffectMap, INT_MAX);
4389 InitUIntMap(&device->FilterMap, INT_MAX);
4391 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4393 device->ChannelDelay[i].Gain = 1.0f;
4394 device->ChannelDelay[i].Length = 0;
4395 device->ChannelDelay[i].Buffer = NULL;
4398 factory = ALCloopbackFactory_getFactory();
4399 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4400 if(!device->Backend)
4402 al_free(device);
4403 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4404 return NULL;
4406 almtx_init(&device->BackendLock, almtx_plain);
4408 //Set output format
4409 device->NumUpdates = 0;
4410 device->UpdateSize = 0;
4412 device->Frequency = DEFAULT_OUTPUT_RATE;
4413 device->FmtChans = DevFmtChannelsDefault;
4414 device->FmtType = DevFmtTypeDefault;
4415 device->IsHeadphones = AL_FALSE;
4416 device->AmbiLayout = AmbiLayout_Default;
4417 device->AmbiScale = AmbiNorm_Default;
4419 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4420 if(device->SourcesMax == 0) device->SourcesMax = 256;
4422 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4423 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4425 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4426 device->NumAuxSends = clampi(
4427 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4430 device->NumStereoSources = 1;
4431 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4433 // Open the "backend"
4434 V(device->Backend,open)("Loopback");
4436 device->Limiter = CreateDeviceLimiter(device);
4439 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4440 do {
4441 device->next = head;
4442 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4445 TRACE("Created device %p\n", device);
4446 return device;
4449 /* alcIsRenderFormatSupportedSOFT
4451 * Determines if the loopback device supports the given format for rendering.
4453 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4455 ALCboolean ret = ALC_FALSE;
4457 if(!VerifyDevice(&device) || device->Type != Loopback)
4458 alcSetError(device, ALC_INVALID_DEVICE);
4459 else if(freq <= 0)
4460 alcSetError(device, ALC_INVALID_VALUE);
4461 else
4463 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4464 ret = ALC_TRUE;
4466 if(device) ALCdevice_DecRef(device);
4468 return ret;
4471 /* alcRenderSamplesSOFT
4473 * Renders some samples into a buffer, using the format last set by the
4474 * attributes given to alcCreateContext.
4476 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4478 if(!VerifyDevice(&device) || device->Type != Loopback)
4479 alcSetError(device, ALC_INVALID_DEVICE);
4480 else if(samples < 0 || (samples > 0 && buffer == NULL))
4481 alcSetError(device, ALC_INVALID_VALUE);
4482 else
4484 V0(device->Backend,lock)();
4485 aluMixData(device, buffer, samples);
4486 V0(device->Backend,unlock)();
4488 if(device) ALCdevice_DecRef(device);
4492 /************************************************
4493 * ALC loopback2 functions
4494 ************************************************/
4496 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4498 ALCboolean ret = ALC_FALSE;
4500 if(!VerifyDevice(&device) || device->Type != Loopback)
4501 alcSetError(device, ALC_INVALID_DEVICE);
4502 else if(order <= 0)
4503 alcSetError(device, ALC_INVALID_VALUE);
4504 else
4506 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4507 ret = ALC_TRUE;
4509 if(device) ALCdevice_DecRef(device);
4511 return ret;
4514 /************************************************
4515 * ALC DSP pause/resume functions
4516 ************************************************/
4518 /* alcDevicePauseSOFT
4520 * Pause the DSP to stop audio processing.
4522 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4524 if(!VerifyDevice(&device) || device->Type != Playback)
4525 alcSetError(device, ALC_INVALID_DEVICE);
4526 else
4528 almtx_lock(&device->BackendLock);
4529 if((device->Flags&DEVICE_RUNNING))
4530 V0(device->Backend,stop)();
4531 device->Flags &= ~DEVICE_RUNNING;
4532 device->Flags |= DEVICE_PAUSED;
4533 almtx_unlock(&device->BackendLock);
4535 if(device) ALCdevice_DecRef(device);
4538 /* alcDeviceResumeSOFT
4540 * Resume the DSP to restart audio processing.
4542 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4544 if(!VerifyDevice(&device) || device->Type != Playback)
4545 alcSetError(device, ALC_INVALID_DEVICE);
4546 else
4548 almtx_lock(&device->BackendLock);
4549 if((device->Flags&DEVICE_PAUSED))
4551 device->Flags &= ~DEVICE_PAUSED;
4552 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4554 if(V0(device->Backend,start)() != ALC_FALSE)
4555 device->Flags |= DEVICE_RUNNING;
4556 else
4558 alcSetError(device, ALC_INVALID_DEVICE);
4559 V0(device->Backend,lock)();
4560 aluHandleDisconnect(device);
4561 V0(device->Backend,unlock)();
4565 almtx_unlock(&device->BackendLock);
4567 if(device) ALCdevice_DecRef(device);
4571 /************************************************
4572 * ALC HRTF functions
4573 ************************************************/
4575 /* alcGetStringiSOFT
4577 * Gets a string parameter at the given index.
4579 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4581 const ALCchar *str = NULL;
4583 if(!VerifyDevice(&device) || device->Type == Capture)
4584 alcSetError(device, ALC_INVALID_DEVICE);
4585 else switch(paramName)
4587 case ALC_HRTF_SPECIFIER_SOFT:
4588 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList))
4589 str = alstr_get_cstr(VECTOR_ELEM(device->HrtfList, index).name);
4590 else
4591 alcSetError(device, ALC_INVALID_VALUE);
4592 break;
4594 default:
4595 alcSetError(device, ALC_INVALID_ENUM);
4596 break;
4598 if(device) ALCdevice_DecRef(device);
4600 return str;
4603 /* alcResetDeviceSOFT
4605 * Resets the given device output, using the specified attribute list.
4607 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4609 ALCenum err;
4611 LockLists();
4612 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4614 UnlockLists();
4615 alcSetError(device, ALC_INVALID_DEVICE);
4616 if(device) ALCdevice_DecRef(device);
4617 return ALC_FALSE;
4619 almtx_lock(&device->BackendLock);
4620 UnlockLists();
4622 err = UpdateDeviceParams(device, attribs);
4623 almtx_unlock(&device->BackendLock);
4625 if(err != ALC_NO_ERROR)
4627 alcSetError(device, err);
4628 if(err == ALC_INVALID_DEVICE)
4630 V0(device->Backend,lock)();
4631 aluHandleDisconnect(device);
4632 V0(device->Backend,unlock)();
4634 ALCdevice_DecRef(device);
4635 return ALC_FALSE;
4637 ALCdevice_DecRef(device);
4639 return ALC_TRUE;