It's getFactory that may be NULL, not its return value...
[openal-soft.git] / Alc / ALc.c
blob4c6c90492afff7faf29d5640bee9b5904190edad
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(alcDevicePauseSOFT),
149 DECL(alcDeviceResumeSOFT),
151 DECL(alcGetStringiSOFT),
152 DECL(alcResetDeviceSOFT),
154 DECL(alcGetInteger64vSOFT),
156 DECL(alEnable),
157 DECL(alDisable),
158 DECL(alIsEnabled),
159 DECL(alGetString),
160 DECL(alGetBooleanv),
161 DECL(alGetIntegerv),
162 DECL(alGetFloatv),
163 DECL(alGetDoublev),
164 DECL(alGetBoolean),
165 DECL(alGetInteger),
166 DECL(alGetFloat),
167 DECL(alGetDouble),
168 DECL(alGetError),
169 DECL(alIsExtensionPresent),
170 DECL(alGetProcAddress),
171 DECL(alGetEnumValue),
172 DECL(alListenerf),
173 DECL(alListener3f),
174 DECL(alListenerfv),
175 DECL(alListeneri),
176 DECL(alListener3i),
177 DECL(alListeneriv),
178 DECL(alGetListenerf),
179 DECL(alGetListener3f),
180 DECL(alGetListenerfv),
181 DECL(alGetListeneri),
182 DECL(alGetListener3i),
183 DECL(alGetListeneriv),
184 DECL(alGenSources),
185 DECL(alDeleteSources),
186 DECL(alIsSource),
187 DECL(alSourcef),
188 DECL(alSource3f),
189 DECL(alSourcefv),
190 DECL(alSourcei),
191 DECL(alSource3i),
192 DECL(alSourceiv),
193 DECL(alGetSourcef),
194 DECL(alGetSource3f),
195 DECL(alGetSourcefv),
196 DECL(alGetSourcei),
197 DECL(alGetSource3i),
198 DECL(alGetSourceiv),
199 DECL(alSourcePlayv),
200 DECL(alSourceStopv),
201 DECL(alSourceRewindv),
202 DECL(alSourcePausev),
203 DECL(alSourcePlay),
204 DECL(alSourceStop),
205 DECL(alSourceRewind),
206 DECL(alSourcePause),
207 DECL(alSourceQueueBuffers),
208 DECL(alSourceUnqueueBuffers),
209 DECL(alGenBuffers),
210 DECL(alDeleteBuffers),
211 DECL(alIsBuffer),
212 DECL(alBufferData),
213 DECL(alBufferf),
214 DECL(alBuffer3f),
215 DECL(alBufferfv),
216 DECL(alBufferi),
217 DECL(alBuffer3i),
218 DECL(alBufferiv),
219 DECL(alGetBufferf),
220 DECL(alGetBuffer3f),
221 DECL(alGetBufferfv),
222 DECL(alGetBufferi),
223 DECL(alGetBuffer3i),
224 DECL(alGetBufferiv),
225 DECL(alDopplerFactor),
226 DECL(alDopplerVelocity),
227 DECL(alSpeedOfSound),
228 DECL(alDistanceModel),
230 DECL(alGenFilters),
231 DECL(alDeleteFilters),
232 DECL(alIsFilter),
233 DECL(alFilteri),
234 DECL(alFilteriv),
235 DECL(alFilterf),
236 DECL(alFilterfv),
237 DECL(alGetFilteri),
238 DECL(alGetFilteriv),
239 DECL(alGetFilterf),
240 DECL(alGetFilterfv),
241 DECL(alGenEffects),
242 DECL(alDeleteEffects),
243 DECL(alIsEffect),
244 DECL(alEffecti),
245 DECL(alEffectiv),
246 DECL(alEffectf),
247 DECL(alEffectfv),
248 DECL(alGetEffecti),
249 DECL(alGetEffectiv),
250 DECL(alGetEffectf),
251 DECL(alGetEffectfv),
252 DECL(alGenAuxiliaryEffectSlots),
253 DECL(alDeleteAuxiliaryEffectSlots),
254 DECL(alIsAuxiliaryEffectSlot),
255 DECL(alAuxiliaryEffectSloti),
256 DECL(alAuxiliaryEffectSlotiv),
257 DECL(alAuxiliaryEffectSlotf),
258 DECL(alAuxiliaryEffectSlotfv),
259 DECL(alGetAuxiliaryEffectSloti),
260 DECL(alGetAuxiliaryEffectSlotiv),
261 DECL(alGetAuxiliaryEffectSlotf),
262 DECL(alGetAuxiliaryEffectSlotfv),
264 DECL(alDeferUpdatesSOFT),
265 DECL(alProcessUpdatesSOFT),
267 DECL(alSourcedSOFT),
268 DECL(alSource3dSOFT),
269 DECL(alSourcedvSOFT),
270 DECL(alGetSourcedSOFT),
271 DECL(alGetSource3dSOFT),
272 DECL(alGetSourcedvSOFT),
273 DECL(alSourcei64SOFT),
274 DECL(alSource3i64SOFT),
275 DECL(alSourcei64vSOFT),
276 DECL(alGetSourcei64SOFT),
277 DECL(alGetSource3i64SOFT),
278 DECL(alGetSourcei64vSOFT),
280 DECL(alBufferSamplesSOFT),
281 DECL(alGetBufferSamplesSOFT),
282 DECL(alIsBufferFormatSupportedSOFT),
284 DECL(alGetStringiSOFT),
286 #undef DECL
288 #define DECL(x) { #x, (x) }
289 static const struct {
290 const ALCchar *enumName;
291 ALCenum value;
292 } alcEnumerations[] = {
293 DECL(ALC_INVALID),
294 DECL(ALC_FALSE),
295 DECL(ALC_TRUE),
297 DECL(ALC_MAJOR_VERSION),
298 DECL(ALC_MINOR_VERSION),
299 DECL(ALC_ATTRIBUTES_SIZE),
300 DECL(ALC_ALL_ATTRIBUTES),
301 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
302 DECL(ALC_DEVICE_SPECIFIER),
303 DECL(ALC_ALL_DEVICES_SPECIFIER),
304 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
305 DECL(ALC_EXTENSIONS),
306 DECL(ALC_FREQUENCY),
307 DECL(ALC_REFRESH),
308 DECL(ALC_SYNC),
309 DECL(ALC_MONO_SOURCES),
310 DECL(ALC_STEREO_SOURCES),
311 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
312 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
313 DECL(ALC_CAPTURE_SAMPLES),
314 DECL(ALC_CONNECTED),
316 DECL(ALC_EFX_MAJOR_VERSION),
317 DECL(ALC_EFX_MINOR_VERSION),
318 DECL(ALC_MAX_AUXILIARY_SENDS),
320 DECL(ALC_FORMAT_CHANNELS_SOFT),
321 DECL(ALC_FORMAT_TYPE_SOFT),
323 DECL(ALC_MONO_SOFT),
324 DECL(ALC_STEREO_SOFT),
325 DECL(ALC_QUAD_SOFT),
326 DECL(ALC_5POINT1_SOFT),
327 DECL(ALC_6POINT1_SOFT),
328 DECL(ALC_7POINT1_SOFT),
329 DECL(ALC_BFORMAT3D_SOFT),
331 DECL(ALC_BYTE_SOFT),
332 DECL(ALC_UNSIGNED_BYTE_SOFT),
333 DECL(ALC_SHORT_SOFT),
334 DECL(ALC_UNSIGNED_SHORT_SOFT),
335 DECL(ALC_INT_SOFT),
336 DECL(ALC_UNSIGNED_INT_SOFT),
337 DECL(ALC_FLOAT_SOFT),
339 DECL(ALC_HRTF_SOFT),
340 DECL(ALC_DONT_CARE_SOFT),
341 DECL(ALC_HRTF_STATUS_SOFT),
342 DECL(ALC_HRTF_DISABLED_SOFT),
343 DECL(ALC_HRTF_ENABLED_SOFT),
344 DECL(ALC_HRTF_DENIED_SOFT),
345 DECL(ALC_HRTF_REQUIRED_SOFT),
346 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
347 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
348 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
349 DECL(ALC_HRTF_SPECIFIER_SOFT),
350 DECL(ALC_HRTF_ID_SOFT),
352 DECL(ALC_AMBISONIC_LAYOUT_SOFT),
353 DECL(ALC_AMBISONIC_SCALING_SOFT),
354 DECL(ALC_AMBISONIC_ORDER_SOFT),
355 DECL(ALC_ACN_SOFT),
356 DECL(ALC_FUMA_SOFT),
357 DECL(ALC_N3D_SOFT),
358 DECL(ALC_SN3D_SOFT),
360 DECL(ALC_OUTPUT_LIMITER_SOFT),
362 DECL(ALC_NO_ERROR),
363 DECL(ALC_INVALID_DEVICE),
364 DECL(ALC_INVALID_CONTEXT),
365 DECL(ALC_INVALID_ENUM),
366 DECL(ALC_INVALID_VALUE),
367 DECL(ALC_OUT_OF_MEMORY),
370 DECL(AL_INVALID),
371 DECL(AL_NONE),
372 DECL(AL_FALSE),
373 DECL(AL_TRUE),
375 DECL(AL_SOURCE_RELATIVE),
376 DECL(AL_CONE_INNER_ANGLE),
377 DECL(AL_CONE_OUTER_ANGLE),
378 DECL(AL_PITCH),
379 DECL(AL_POSITION),
380 DECL(AL_DIRECTION),
381 DECL(AL_VELOCITY),
382 DECL(AL_LOOPING),
383 DECL(AL_BUFFER),
384 DECL(AL_GAIN),
385 DECL(AL_MIN_GAIN),
386 DECL(AL_MAX_GAIN),
387 DECL(AL_ORIENTATION),
388 DECL(AL_REFERENCE_DISTANCE),
389 DECL(AL_ROLLOFF_FACTOR),
390 DECL(AL_CONE_OUTER_GAIN),
391 DECL(AL_MAX_DISTANCE),
392 DECL(AL_SEC_OFFSET),
393 DECL(AL_SAMPLE_OFFSET),
394 DECL(AL_BYTE_OFFSET),
395 DECL(AL_SOURCE_TYPE),
396 DECL(AL_STATIC),
397 DECL(AL_STREAMING),
398 DECL(AL_UNDETERMINED),
399 DECL(AL_METERS_PER_UNIT),
400 DECL(AL_LOOP_POINTS_SOFT),
401 DECL(AL_DIRECT_CHANNELS_SOFT),
403 DECL(AL_DIRECT_FILTER),
404 DECL(AL_AUXILIARY_SEND_FILTER),
405 DECL(AL_AIR_ABSORPTION_FACTOR),
406 DECL(AL_ROOM_ROLLOFF_FACTOR),
407 DECL(AL_CONE_OUTER_GAINHF),
408 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
409 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
410 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
412 DECL(AL_SOURCE_STATE),
413 DECL(AL_INITIAL),
414 DECL(AL_PLAYING),
415 DECL(AL_PAUSED),
416 DECL(AL_STOPPED),
418 DECL(AL_BUFFERS_QUEUED),
419 DECL(AL_BUFFERS_PROCESSED),
421 DECL(AL_FORMAT_MONO8),
422 DECL(AL_FORMAT_MONO16),
423 DECL(AL_FORMAT_MONO_FLOAT32),
424 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
425 DECL(AL_FORMAT_STEREO8),
426 DECL(AL_FORMAT_STEREO16),
427 DECL(AL_FORMAT_STEREO_FLOAT32),
428 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
429 DECL(AL_FORMAT_MONO_IMA4),
430 DECL(AL_FORMAT_STEREO_IMA4),
431 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
432 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
433 DECL(AL_FORMAT_QUAD8_LOKI),
434 DECL(AL_FORMAT_QUAD16_LOKI),
435 DECL(AL_FORMAT_QUAD8),
436 DECL(AL_FORMAT_QUAD16),
437 DECL(AL_FORMAT_QUAD32),
438 DECL(AL_FORMAT_51CHN8),
439 DECL(AL_FORMAT_51CHN16),
440 DECL(AL_FORMAT_51CHN32),
441 DECL(AL_FORMAT_61CHN8),
442 DECL(AL_FORMAT_61CHN16),
443 DECL(AL_FORMAT_61CHN32),
444 DECL(AL_FORMAT_71CHN8),
445 DECL(AL_FORMAT_71CHN16),
446 DECL(AL_FORMAT_71CHN32),
447 DECL(AL_FORMAT_REAR8),
448 DECL(AL_FORMAT_REAR16),
449 DECL(AL_FORMAT_REAR32),
450 DECL(AL_FORMAT_MONO_MULAW),
451 DECL(AL_FORMAT_MONO_MULAW_EXT),
452 DECL(AL_FORMAT_STEREO_MULAW),
453 DECL(AL_FORMAT_STEREO_MULAW_EXT),
454 DECL(AL_FORMAT_QUAD_MULAW),
455 DECL(AL_FORMAT_51CHN_MULAW),
456 DECL(AL_FORMAT_61CHN_MULAW),
457 DECL(AL_FORMAT_71CHN_MULAW),
458 DECL(AL_FORMAT_REAR_MULAW),
459 DECL(AL_FORMAT_MONO_ALAW_EXT),
460 DECL(AL_FORMAT_STEREO_ALAW_EXT),
462 DECL(AL_FORMAT_BFORMAT2D_8),
463 DECL(AL_FORMAT_BFORMAT2D_16),
464 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
465 DECL(AL_FORMAT_BFORMAT2D_MULAW),
466 DECL(AL_FORMAT_BFORMAT3D_8),
467 DECL(AL_FORMAT_BFORMAT3D_16),
468 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
469 DECL(AL_FORMAT_BFORMAT3D_MULAW),
471 DECL(AL_MONO8_SOFT),
472 DECL(AL_MONO16_SOFT),
473 DECL(AL_MONO32F_SOFT),
474 DECL(AL_STEREO8_SOFT),
475 DECL(AL_STEREO16_SOFT),
476 DECL(AL_STEREO32F_SOFT),
477 DECL(AL_QUAD8_SOFT),
478 DECL(AL_QUAD16_SOFT),
479 DECL(AL_QUAD32F_SOFT),
480 DECL(AL_REAR8_SOFT),
481 DECL(AL_REAR16_SOFT),
482 DECL(AL_REAR32F_SOFT),
483 DECL(AL_5POINT1_8_SOFT),
484 DECL(AL_5POINT1_16_SOFT),
485 DECL(AL_5POINT1_32F_SOFT),
486 DECL(AL_6POINT1_8_SOFT),
487 DECL(AL_6POINT1_16_SOFT),
488 DECL(AL_6POINT1_32F_SOFT),
489 DECL(AL_7POINT1_8_SOFT),
490 DECL(AL_7POINT1_16_SOFT),
491 DECL(AL_7POINT1_32F_SOFT),
492 DECL(AL_BFORMAT2D_8_SOFT),
493 DECL(AL_BFORMAT2D_16_SOFT),
494 DECL(AL_BFORMAT2D_32F_SOFT),
495 DECL(AL_BFORMAT3D_8_SOFT),
496 DECL(AL_BFORMAT3D_16_SOFT),
497 DECL(AL_BFORMAT3D_32F_SOFT),
499 DECL(AL_MONO_SOFT),
500 DECL(AL_STEREO_SOFT),
501 DECL(AL_QUAD_SOFT),
502 DECL(AL_REAR_SOFT),
503 DECL(AL_5POINT1_SOFT),
504 DECL(AL_6POINT1_SOFT),
505 DECL(AL_7POINT1_SOFT),
506 DECL(AL_BFORMAT2D_SOFT),
507 DECL(AL_BFORMAT3D_SOFT),
509 DECL(AL_BYTE_SOFT),
510 DECL(AL_UNSIGNED_BYTE_SOFT),
511 DECL(AL_SHORT_SOFT),
512 DECL(AL_UNSIGNED_SHORT_SOFT),
513 DECL(AL_INT_SOFT),
514 DECL(AL_UNSIGNED_INT_SOFT),
515 DECL(AL_FLOAT_SOFT),
516 DECL(AL_DOUBLE_SOFT),
517 DECL(AL_BYTE3_SOFT),
518 DECL(AL_UNSIGNED_BYTE3_SOFT),
519 DECL(AL_MULAW_SOFT),
521 DECL(AL_FREQUENCY),
522 DECL(AL_BITS),
523 DECL(AL_CHANNELS),
524 DECL(AL_SIZE),
525 DECL(AL_INTERNAL_FORMAT_SOFT),
526 DECL(AL_BYTE_LENGTH_SOFT),
527 DECL(AL_SAMPLE_LENGTH_SOFT),
528 DECL(AL_SEC_LENGTH_SOFT),
529 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
530 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
532 DECL(AL_SOURCE_RADIUS),
534 DECL(AL_STEREO_ANGLES),
536 DECL(AL_UNUSED),
537 DECL(AL_PENDING),
538 DECL(AL_PROCESSED),
540 DECL(AL_NO_ERROR),
541 DECL(AL_INVALID_NAME),
542 DECL(AL_INVALID_ENUM),
543 DECL(AL_INVALID_VALUE),
544 DECL(AL_INVALID_OPERATION),
545 DECL(AL_OUT_OF_MEMORY),
547 DECL(AL_VENDOR),
548 DECL(AL_VERSION),
549 DECL(AL_RENDERER),
550 DECL(AL_EXTENSIONS),
552 DECL(AL_DOPPLER_FACTOR),
553 DECL(AL_DOPPLER_VELOCITY),
554 DECL(AL_DISTANCE_MODEL),
555 DECL(AL_SPEED_OF_SOUND),
556 DECL(AL_SOURCE_DISTANCE_MODEL),
557 DECL(AL_DEFERRED_UPDATES_SOFT),
558 DECL(AL_GAIN_LIMIT_SOFT),
560 DECL(AL_INVERSE_DISTANCE),
561 DECL(AL_INVERSE_DISTANCE_CLAMPED),
562 DECL(AL_LINEAR_DISTANCE),
563 DECL(AL_LINEAR_DISTANCE_CLAMPED),
564 DECL(AL_EXPONENT_DISTANCE),
565 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
567 DECL(AL_FILTER_TYPE),
568 DECL(AL_FILTER_NULL),
569 DECL(AL_FILTER_LOWPASS),
570 DECL(AL_FILTER_HIGHPASS),
571 DECL(AL_FILTER_BANDPASS),
573 DECL(AL_LOWPASS_GAIN),
574 DECL(AL_LOWPASS_GAINHF),
576 DECL(AL_HIGHPASS_GAIN),
577 DECL(AL_HIGHPASS_GAINLF),
579 DECL(AL_BANDPASS_GAIN),
580 DECL(AL_BANDPASS_GAINHF),
581 DECL(AL_BANDPASS_GAINLF),
583 DECL(AL_EFFECT_TYPE),
584 DECL(AL_EFFECT_NULL),
585 DECL(AL_EFFECT_REVERB),
586 DECL(AL_EFFECT_EAXREVERB),
587 DECL(AL_EFFECT_CHORUS),
588 DECL(AL_EFFECT_DISTORTION),
589 DECL(AL_EFFECT_ECHO),
590 DECL(AL_EFFECT_FLANGER),
591 #if 0
592 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
593 DECL(AL_EFFECT_VOCAL_MORPHER),
594 DECL(AL_EFFECT_PITCH_SHIFTER),
595 #endif
596 DECL(AL_EFFECT_RING_MODULATOR),
597 #if 0
598 DECL(AL_EFFECT_AUTOWAH),
599 #endif
600 DECL(AL_EFFECT_COMPRESSOR),
601 DECL(AL_EFFECT_EQUALIZER),
602 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
603 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
605 DECL(AL_EFFECTSLOT_EFFECT),
606 DECL(AL_EFFECTSLOT_GAIN),
607 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
608 DECL(AL_EFFECTSLOT_NULL),
610 DECL(AL_EAXREVERB_DENSITY),
611 DECL(AL_EAXREVERB_DIFFUSION),
612 DECL(AL_EAXREVERB_GAIN),
613 DECL(AL_EAXREVERB_GAINHF),
614 DECL(AL_EAXREVERB_GAINLF),
615 DECL(AL_EAXREVERB_DECAY_TIME),
616 DECL(AL_EAXREVERB_DECAY_HFRATIO),
617 DECL(AL_EAXREVERB_DECAY_LFRATIO),
618 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
619 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
620 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
621 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
622 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
623 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
624 DECL(AL_EAXREVERB_ECHO_TIME),
625 DECL(AL_EAXREVERB_ECHO_DEPTH),
626 DECL(AL_EAXREVERB_MODULATION_TIME),
627 DECL(AL_EAXREVERB_MODULATION_DEPTH),
628 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
629 DECL(AL_EAXREVERB_HFREFERENCE),
630 DECL(AL_EAXREVERB_LFREFERENCE),
631 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
632 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
634 DECL(AL_REVERB_DENSITY),
635 DECL(AL_REVERB_DIFFUSION),
636 DECL(AL_REVERB_GAIN),
637 DECL(AL_REVERB_GAINHF),
638 DECL(AL_REVERB_DECAY_TIME),
639 DECL(AL_REVERB_DECAY_HFRATIO),
640 DECL(AL_REVERB_REFLECTIONS_GAIN),
641 DECL(AL_REVERB_REFLECTIONS_DELAY),
642 DECL(AL_REVERB_LATE_REVERB_GAIN),
643 DECL(AL_REVERB_LATE_REVERB_DELAY),
644 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
645 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
646 DECL(AL_REVERB_DECAY_HFLIMIT),
648 DECL(AL_CHORUS_WAVEFORM),
649 DECL(AL_CHORUS_PHASE),
650 DECL(AL_CHORUS_RATE),
651 DECL(AL_CHORUS_DEPTH),
652 DECL(AL_CHORUS_FEEDBACK),
653 DECL(AL_CHORUS_DELAY),
655 DECL(AL_DISTORTION_EDGE),
656 DECL(AL_DISTORTION_GAIN),
657 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
658 DECL(AL_DISTORTION_EQCENTER),
659 DECL(AL_DISTORTION_EQBANDWIDTH),
661 DECL(AL_ECHO_DELAY),
662 DECL(AL_ECHO_LRDELAY),
663 DECL(AL_ECHO_DAMPING),
664 DECL(AL_ECHO_FEEDBACK),
665 DECL(AL_ECHO_SPREAD),
667 DECL(AL_FLANGER_WAVEFORM),
668 DECL(AL_FLANGER_PHASE),
669 DECL(AL_FLANGER_RATE),
670 DECL(AL_FLANGER_DEPTH),
671 DECL(AL_FLANGER_FEEDBACK),
672 DECL(AL_FLANGER_DELAY),
674 DECL(AL_RING_MODULATOR_FREQUENCY),
675 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
676 DECL(AL_RING_MODULATOR_WAVEFORM),
678 DECL(AL_COMPRESSOR_ONOFF),
680 DECL(AL_EQUALIZER_LOW_GAIN),
681 DECL(AL_EQUALIZER_LOW_CUTOFF),
682 DECL(AL_EQUALIZER_MID1_GAIN),
683 DECL(AL_EQUALIZER_MID1_CENTER),
684 DECL(AL_EQUALIZER_MID1_WIDTH),
685 DECL(AL_EQUALIZER_MID2_GAIN),
686 DECL(AL_EQUALIZER_MID2_CENTER),
687 DECL(AL_EQUALIZER_MID2_WIDTH),
688 DECL(AL_EQUALIZER_HIGH_GAIN),
689 DECL(AL_EQUALIZER_HIGH_CUTOFF),
691 DECL(AL_DEDICATED_GAIN),
693 DECL(AL_NUM_RESAMPLERS_SOFT),
694 DECL(AL_DEFAULT_RESAMPLER_SOFT),
695 DECL(AL_SOURCE_RESAMPLER_SOFT),
696 DECL(AL_RESAMPLER_NAME_SOFT),
698 DECL(AL_SOURCE_SPATIALIZE_SOFT),
699 DECL(AL_AUTO_SOFT),
701 #undef DECL
703 static const ALCchar alcNoError[] = "No Error";
704 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
705 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
706 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
707 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
708 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
711 /************************************************
712 * Global variables
713 ************************************************/
715 /* Enumerated device names */
716 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
718 static al_string alcAllDevicesList;
719 static al_string alcCaptureDeviceList;
721 /* Default is always the first in the list */
722 static ALCchar *alcDefaultAllDevicesSpecifier;
723 static ALCchar *alcCaptureDefaultDeviceSpecifier;
725 /* Default context extensions */
726 static const ALchar alExtList[] =
727 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
728 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
729 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
730 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
731 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
732 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
733 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length "
734 "AL_SOFT_source_resampler AL_SOFT_source_spatialize";
736 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
738 /* Thread-local current context */
739 static altss_t LocalContext;
740 /* Process-wide current context */
741 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
743 /* Mixing thread piority level */
744 ALint RTPrioLevel;
746 FILE *LogFile;
747 #ifdef _DEBUG
748 enum LogLevel LogLevel = LogWarning;
749 #else
750 enum LogLevel LogLevel = LogError;
751 #endif
753 /* Flag to trap ALC device errors */
754 static ALCboolean TrapALCError = ALC_FALSE;
756 /* One-time configuration init control */
757 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
759 /* Default effect that applies to sources that don't have an effect on send 0 */
760 static ALeffect DefaultEffect;
762 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
763 * updates.
765 static ALCboolean SuspendDefers = ALC_TRUE;
768 /************************************************
769 * ALC information
770 ************************************************/
771 static const ALCchar alcNoDeviceExtList[] =
772 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
773 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
774 static const ALCchar alcExtensionList[] =
775 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
776 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
777 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
778 "ALC_SOFT_loopback ALC_SOFT_output_limiter ALC_SOFT_pause_device";
779 static const ALCint alcMajorVersion = 1;
780 static const ALCint alcMinorVersion = 1;
782 static const ALCint alcEFXMajorVersion = 1;
783 static const ALCint alcEFXMinorVersion = 0;
786 /************************************************
787 * Device lists
788 ************************************************/
789 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
791 static almtx_t ListLock;
792 static inline void LockLists(void)
794 int ret = almtx_lock(&ListLock);
795 assert(ret == althrd_success);
797 static inline void UnlockLists(void)
799 int ret = almtx_unlock(&ListLock);
800 assert(ret == althrd_success);
803 /************************************************
804 * Library initialization
805 ************************************************/
806 #if defined(_WIN32)
807 static void alc_init(void);
808 static void alc_deinit(void);
809 static void alc_deinit_safe(void);
811 #ifndef AL_LIBTYPE_STATIC
812 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
814 switch(reason)
816 case DLL_PROCESS_ATTACH:
817 /* Pin the DLL so we won't get unloaded until the process terminates */
818 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
819 (WCHAR*)hModule, &hModule);
820 alc_init();
821 break;
823 case DLL_THREAD_DETACH:
824 break;
826 case DLL_PROCESS_DETACH:
827 if(!lpReserved)
828 alc_deinit();
829 else
830 alc_deinit_safe();
831 break;
833 return TRUE;
835 #elif defined(_MSC_VER)
836 #pragma section(".CRT$XCU",read)
837 static void alc_constructor(void);
838 static void alc_destructor(void);
839 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
841 static void alc_constructor(void)
843 atexit(alc_destructor);
844 alc_init();
847 static void alc_destructor(void)
849 alc_deinit();
851 #elif defined(HAVE_GCC_DESTRUCTOR)
852 static void alc_init(void) __attribute__((constructor));
853 static void alc_deinit(void) __attribute__((destructor));
854 #else
855 #error "No static initialization available on this platform!"
856 #endif
858 #elif defined(HAVE_GCC_DESTRUCTOR)
860 static void alc_init(void) __attribute__((constructor));
861 static void alc_deinit(void) __attribute__((destructor));
863 #else
864 #error "No global initialization available on this platform!"
865 #endif
867 static void ReleaseThreadCtx(void *ptr);
868 static void alc_init(void)
870 const char *str;
871 int ret;
873 LogFile = stderr;
875 AL_STRING_INIT(alcAllDevicesList);
876 AL_STRING_INIT(alcCaptureDeviceList);
878 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
879 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
880 ConeScale *= 0.5f;
882 str = getenv("__ALSOFT_REVERSE_Z");
883 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
884 ZScale *= -1.0f;
886 str = getenv("__ALSOFT_REVERB_IGNORES_SOUND_SPEED");
887 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
888 OverrideReverbSpeedOfSound = AL_TRUE;
890 ret = altss_create(&LocalContext, ReleaseThreadCtx);
891 assert(ret == althrd_success);
893 ret = almtx_init(&ListLock, almtx_recursive);
894 assert(ret == althrd_success);
896 ThunkInit();
899 static void alc_initconfig(void)
901 const char *devs, *str;
902 ALuint capfilter;
903 float valf;
904 int i, n;
906 str = getenv("ALSOFT_LOGLEVEL");
907 if(str)
909 long lvl = strtol(str, NULL, 0);
910 if(lvl >= NoLog && lvl <= LogRef)
911 LogLevel = lvl;
914 str = getenv("ALSOFT_LOGFILE");
915 if(str && str[0])
917 FILE *logfile = al_fopen(str, "wt");
918 if(logfile) LogFile = logfile;
919 else ERR("Failed to open log file '%s'\n", str);
922 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION,
923 ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
925 char buf[1024] = "";
926 int len = 0;
928 if(BackendListSize > 0)
929 len += snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
930 for(i = 1;i < BackendListSize;i++)
931 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
932 TRACE("Supported backends: %s\n", buf);
934 ReadALConfig();
936 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
937 if(str && *str)
939 if(strcasecmp(str, "ignore") == 0)
941 SuspendDefers = ALC_FALSE;
942 TRACE("Selected context suspend behavior, \"ignore\"\n");
944 else
945 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
948 capfilter = 0;
949 #if defined(HAVE_SSE4_1)
950 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
951 #elif defined(HAVE_SSE3)
952 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
953 #elif defined(HAVE_SSE2)
954 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
955 #elif defined(HAVE_SSE)
956 capfilter |= CPU_CAP_SSE;
957 #endif
958 #ifdef HAVE_NEON
959 capfilter |= CPU_CAP_NEON;
960 #endif
961 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
963 if(strcasecmp(str, "all") == 0)
964 capfilter = 0;
965 else
967 size_t len;
968 const char *next = str;
970 do {
971 str = next;
972 while(isspace(str[0]))
973 str++;
974 next = strchr(str, ',');
976 if(!str[0] || str[0] == ',')
977 continue;
979 len = (next ? ((size_t)(next-str)) : strlen(str));
980 while(len > 0 && isspace(str[len-1]))
981 len--;
982 if(len == 3 && strncasecmp(str, "sse", len) == 0)
983 capfilter &= ~CPU_CAP_SSE;
984 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
985 capfilter &= ~CPU_CAP_SSE2;
986 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
987 capfilter &= ~CPU_CAP_SSE3;
988 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
989 capfilter &= ~CPU_CAP_SSE4_1;
990 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
991 capfilter &= ~CPU_CAP_NEON;
992 else
993 WARN("Invalid CPU extension \"%s\"\n", str);
994 } while(next++);
997 FillCPUCaps(capfilter);
999 #ifdef _WIN32
1000 RTPrioLevel = 1;
1001 #else
1002 RTPrioLevel = 0;
1003 #endif
1004 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
1006 aluInit();
1007 aluInitMixer();
1009 str = getenv("ALSOFT_TRAP_ERROR");
1010 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1012 TrapALError = AL_TRUE;
1013 TrapALCError = AL_TRUE;
1015 else
1017 str = getenv("ALSOFT_TRAP_AL_ERROR");
1018 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1019 TrapALError = AL_TRUE;
1020 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1022 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1023 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1024 TrapALCError = ALC_TRUE;
1025 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1028 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1029 ReverbBoost *= powf(10.0f, valf / 20.0f);
1031 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1033 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1034 ConfigValueStr(NULL, NULL, "drivers", &devs))
1036 int n;
1037 size_t len;
1038 const char *next = devs;
1039 int endlist, delitem;
1041 i = 0;
1042 do {
1043 devs = next;
1044 while(isspace(devs[0]))
1045 devs++;
1046 next = strchr(devs, ',');
1048 delitem = (devs[0] == '-');
1049 if(devs[0] == '-') devs++;
1051 if(!devs[0] || devs[0] == ',')
1053 endlist = 0;
1054 continue;
1056 endlist = 1;
1058 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1059 while(len > 0 && isspace(devs[len-1]))
1060 len--;
1061 for(n = i;n < BackendListSize;n++)
1063 if(len == strlen(BackendList[n].name) &&
1064 strncmp(BackendList[n].name, devs, len) == 0)
1066 if(delitem)
1068 for(;n+1 < BackendListSize;n++)
1069 BackendList[n] = BackendList[n+1];
1070 BackendListSize--;
1072 else
1074 struct BackendInfo Bkp = BackendList[n];
1075 for(;n > i;n--)
1076 BackendList[n] = BackendList[n-1];
1077 BackendList[n] = Bkp;
1079 i++;
1081 break;
1084 } while(next++);
1086 if(endlist)
1087 BackendListSize = i;
1090 for(i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1092 ALCbackendFactory *factory = BackendList[i].getFactory();
1093 if(!V0(factory,init)())
1095 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1096 continue;
1099 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1100 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1102 PlaybackBackend = BackendList[i];
1103 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1105 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1107 CaptureBackend = BackendList[i];
1108 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1112 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1113 V0(factory,init)();
1116 if(!PlaybackBackend.name)
1117 WARN("No playback backend available!\n");
1118 if(!CaptureBackend.name)
1119 WARN("No capture backend available!\n");
1121 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1123 size_t len;
1124 const char *next = str;
1126 do {
1127 str = next;
1128 next = strchr(str, ',');
1130 if(!str[0] || next == str)
1131 continue;
1133 len = (next ? ((size_t)(next-str)) : strlen(str));
1134 for(n = 0;EffectList[n].name;n++)
1136 if(len == strlen(EffectList[n].name) &&
1137 strncmp(EffectList[n].name, str, len) == 0)
1138 DisabledEffects[EffectList[n].type] = AL_TRUE;
1140 } while(next++);
1143 InitEffectFactoryMap();
1145 InitEffect(&DefaultEffect);
1146 str = getenv("ALSOFT_DEFAULT_REVERB");
1147 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1148 LoadReverbPreset(str, &DefaultEffect);
1150 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1152 #ifdef __ANDROID__
1153 #include <jni.h>
1155 static JavaVM *gJavaVM;
1156 static pthread_key_t gJVMThreadKey;
1158 static void CleanupJNIEnv(void* UNUSED(ptr))
1160 JCALL0(gJavaVM,DetachCurrentThread)();
1163 void *Android_GetJNIEnv(void)
1165 if(!gJavaVM)
1167 WARN("gJavaVM is NULL!\n");
1168 return NULL;
1171 /* http://developer.android.com/guide/practices/jni.html
1173 * All threads are Linux threads, scheduled by the kernel. They're usually
1174 * started from managed code (using Thread.start), but they can also be
1175 * created elsewhere and then attached to the JavaVM. For example, a thread
1176 * started with pthread_create can be attached with the JNI
1177 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1178 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1179 * Attaching a natively-created thread causes a java.lang.Thread object to
1180 * be constructed and added to the "main" ThreadGroup, making it visible to
1181 * the debugger. Calling AttachCurrentThread on an already-attached thread
1182 * is a no-op.
1184 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1185 if(!env)
1187 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1188 if(status < 0)
1190 ERR("Failed to attach current thread\n");
1191 return NULL;
1193 pthread_setspecific(gJVMThreadKey, env);
1195 return env;
1198 /* Automatically called by JNI. */
1199 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1201 void *env;
1202 int err;
1204 gJavaVM = jvm;
1205 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1207 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1208 return JNI_ERR;
1211 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1212 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1214 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1215 ERR("pthread_key_create failed: %d\n", err);
1216 pthread_setspecific(gJVMThreadKey, env);
1217 return JNI_VERSION_1_4;
1219 #endif
1222 /************************************************
1223 * Library deinitialization
1224 ************************************************/
1225 static void alc_cleanup(void)
1227 ALCdevice *dev;
1229 AL_STRING_DEINIT(alcAllDevicesList);
1230 AL_STRING_DEINIT(alcCaptureDeviceList);
1232 free(alcDefaultAllDevicesSpecifier);
1233 alcDefaultAllDevicesSpecifier = NULL;
1234 free(alcCaptureDefaultDeviceSpecifier);
1235 alcCaptureDefaultDeviceSpecifier = NULL;
1237 if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL)
1239 ALCuint num = 0;
1240 do {
1241 num++;
1242 } while((dev=dev->next) != NULL);
1243 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1246 DeinitEffectFactoryMap();
1249 static void alc_deinit_safe(void)
1251 alc_cleanup();
1253 FreeHrtfs();
1254 FreeALConfig();
1256 ThunkExit();
1257 almtx_destroy(&ListLock);
1258 altss_delete(LocalContext);
1260 if(LogFile != stderr)
1261 fclose(LogFile);
1262 LogFile = NULL;
1265 static void alc_deinit(void)
1267 int i;
1269 alc_cleanup();
1271 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1272 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1274 for(i = 0;i < BackendListSize;i++)
1276 ALCbackendFactory *factory = BackendList[i].getFactory();
1277 V0(factory,deinit)();
1280 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1281 V0(factory,deinit)();
1284 alc_deinit_safe();
1288 /************************************************
1289 * Device enumeration
1290 ************************************************/
1291 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1293 DO_INITCONFIG();
1295 LockLists();
1296 alstr_clear(list);
1298 if(backendinfo->getFactory)
1300 ALCbackendFactory *factory = backendinfo->getFactory();
1301 V(factory,probe)(type);
1304 UnlockLists();
1306 static void ProbeAllDevicesList(void)
1307 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1308 static void ProbeCaptureDeviceList(void)
1309 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1311 static void AppendDevice(const ALCchar *name, al_string *devnames)
1313 size_t len = strlen(name);
1314 if(len > 0)
1315 alstr_append_range(devnames, name, name+len+1);
1317 void AppendAllDevicesList(const ALCchar *name)
1318 { AppendDevice(name, &alcAllDevicesList); }
1319 void AppendCaptureDeviceList(const ALCchar *name)
1320 { AppendDevice(name, &alcCaptureDeviceList); }
1323 /************************************************
1324 * Device format information
1325 ************************************************/
1326 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1328 switch(type)
1330 case DevFmtByte: return "Signed Byte";
1331 case DevFmtUByte: return "Unsigned Byte";
1332 case DevFmtShort: return "Signed Short";
1333 case DevFmtUShort: return "Unsigned Short";
1334 case DevFmtInt: return "Signed Int";
1335 case DevFmtUInt: return "Unsigned Int";
1336 case DevFmtFloat: return "Float";
1338 return "(unknown type)";
1340 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1342 switch(chans)
1344 case DevFmtMono: return "Mono";
1345 case DevFmtStereo: return "Stereo";
1346 case DevFmtQuad: return "Quadraphonic";
1347 case DevFmtX51: return "5.1 Surround";
1348 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1349 case DevFmtX61: return "6.1 Surround";
1350 case DevFmtX71: return "7.1 Surround";
1351 case DevFmtAmbi3D: return "Ambisonic 3D";
1353 return "(unknown channels)";
1356 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder);
1357 ALsizei BytesFromDevFmt(enum DevFmtType type)
1359 switch(type)
1361 case DevFmtByte: return sizeof(ALbyte);
1362 case DevFmtUByte: return sizeof(ALubyte);
1363 case DevFmtShort: return sizeof(ALshort);
1364 case DevFmtUShort: return sizeof(ALushort);
1365 case DevFmtInt: return sizeof(ALint);
1366 case DevFmtUInt: return sizeof(ALuint);
1367 case DevFmtFloat: return sizeof(ALfloat);
1369 return 0;
1371 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder)
1373 switch(chans)
1375 case DevFmtMono: return 1;
1376 case DevFmtStereo: return 2;
1377 case DevFmtQuad: return 4;
1378 case DevFmtX51: return 6;
1379 case DevFmtX51Rear: return 6;
1380 case DevFmtX61: return 7;
1381 case DevFmtX71: return 8;
1382 case DevFmtAmbi3D: return (ambiorder >= 3) ? 16 :
1383 (ambiorder == 2) ? 9 :
1384 (ambiorder == 1) ? 4 : 1;
1386 return 0;
1389 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1390 enum DevFmtType *type)
1392 static const struct {
1393 ALenum format;
1394 enum DevFmtChannels channels;
1395 enum DevFmtType type;
1396 } list[] = {
1397 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1398 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1399 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1401 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1402 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1403 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1405 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1406 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1407 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1409 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1410 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1411 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1413 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1414 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1415 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1417 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1418 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1419 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1421 ALuint i;
1423 for(i = 0;i < COUNTOF(list);i++)
1425 if(list[i].format == format)
1427 *chans = list[i].channels;
1428 *type = list[i].type;
1429 return AL_TRUE;
1433 return AL_FALSE;
1436 static ALCboolean IsValidALCType(ALCenum type)
1438 switch(type)
1440 case ALC_BYTE_SOFT:
1441 case ALC_UNSIGNED_BYTE_SOFT:
1442 case ALC_SHORT_SOFT:
1443 case ALC_UNSIGNED_SHORT_SOFT:
1444 case ALC_INT_SOFT:
1445 case ALC_UNSIGNED_INT_SOFT:
1446 case ALC_FLOAT_SOFT:
1447 return ALC_TRUE;
1449 return ALC_FALSE;
1452 static ALCboolean IsValidALCChannels(ALCenum channels)
1454 switch(channels)
1456 case ALC_MONO_SOFT:
1457 case ALC_STEREO_SOFT:
1458 case ALC_QUAD_SOFT:
1459 case ALC_5POINT1_SOFT:
1460 case ALC_6POINT1_SOFT:
1461 case ALC_7POINT1_SOFT:
1462 case ALC_BFORMAT3D_SOFT:
1463 return ALC_TRUE;
1465 return ALC_FALSE;
1468 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1470 switch(layout)
1472 case ALC_ACN_SOFT:
1473 case ALC_FUMA_SOFT:
1474 return ALC_TRUE;
1476 return ALC_FALSE;
1479 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1481 switch(scaling)
1483 case ALC_N3D_SOFT:
1484 case ALC_SN3D_SOFT:
1485 case ALC_FUMA_SOFT:
1486 return ALC_TRUE;
1488 return ALC_FALSE;
1491 /************************************************
1492 * Miscellaneous ALC helpers
1493 ************************************************/
1495 void ALCdevice_Lock(ALCdevice *device)
1497 V0(device->Backend,lock)();
1500 void ALCdevice_Unlock(ALCdevice *device)
1502 V0(device->Backend,unlock)();
1506 /* SetDefaultWFXChannelOrder
1508 * Sets the default channel order used by WaveFormatEx.
1510 void SetDefaultWFXChannelOrder(ALCdevice *device)
1512 ALsizei i;
1514 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1515 device->RealOut.ChannelName[i] = InvalidChannel;
1517 switch(device->FmtChans)
1519 case DevFmtMono:
1520 device->RealOut.ChannelName[0] = FrontCenter;
1521 break;
1522 case DevFmtStereo:
1523 device->RealOut.ChannelName[0] = FrontLeft;
1524 device->RealOut.ChannelName[1] = FrontRight;
1525 break;
1526 case DevFmtQuad:
1527 device->RealOut.ChannelName[0] = FrontLeft;
1528 device->RealOut.ChannelName[1] = FrontRight;
1529 device->RealOut.ChannelName[2] = BackLeft;
1530 device->RealOut.ChannelName[3] = BackRight;
1531 break;
1532 case DevFmtX51:
1533 device->RealOut.ChannelName[0] = FrontLeft;
1534 device->RealOut.ChannelName[1] = FrontRight;
1535 device->RealOut.ChannelName[2] = FrontCenter;
1536 device->RealOut.ChannelName[3] = LFE;
1537 device->RealOut.ChannelName[4] = SideLeft;
1538 device->RealOut.ChannelName[5] = SideRight;
1539 break;
1540 case DevFmtX51Rear:
1541 device->RealOut.ChannelName[0] = FrontLeft;
1542 device->RealOut.ChannelName[1] = FrontRight;
1543 device->RealOut.ChannelName[2] = FrontCenter;
1544 device->RealOut.ChannelName[3] = LFE;
1545 device->RealOut.ChannelName[4] = BackLeft;
1546 device->RealOut.ChannelName[5] = BackRight;
1547 break;
1548 case DevFmtX61:
1549 device->RealOut.ChannelName[0] = FrontLeft;
1550 device->RealOut.ChannelName[1] = FrontRight;
1551 device->RealOut.ChannelName[2] = FrontCenter;
1552 device->RealOut.ChannelName[3] = LFE;
1553 device->RealOut.ChannelName[4] = BackCenter;
1554 device->RealOut.ChannelName[5] = SideLeft;
1555 device->RealOut.ChannelName[6] = SideRight;
1556 break;
1557 case DevFmtX71:
1558 device->RealOut.ChannelName[0] = FrontLeft;
1559 device->RealOut.ChannelName[1] = FrontRight;
1560 device->RealOut.ChannelName[2] = FrontCenter;
1561 device->RealOut.ChannelName[3] = LFE;
1562 device->RealOut.ChannelName[4] = BackLeft;
1563 device->RealOut.ChannelName[5] = BackRight;
1564 device->RealOut.ChannelName[6] = SideLeft;
1565 device->RealOut.ChannelName[7] = SideRight;
1566 break;
1567 case DevFmtAmbi3D:
1568 device->RealOut.ChannelName[0] = Aux0;
1569 if(device->AmbiOrder > 0)
1571 device->RealOut.ChannelName[1] = Aux1;
1572 device->RealOut.ChannelName[2] = Aux2;
1573 device->RealOut.ChannelName[3] = Aux3;
1575 if(device->AmbiOrder > 1)
1577 device->RealOut.ChannelName[4] = Aux4;
1578 device->RealOut.ChannelName[5] = Aux5;
1579 device->RealOut.ChannelName[6] = Aux6;
1580 device->RealOut.ChannelName[7] = Aux7;
1581 device->RealOut.ChannelName[8] = Aux8;
1583 if(device->AmbiOrder > 2)
1585 device->RealOut.ChannelName[9] = Aux9;
1586 device->RealOut.ChannelName[10] = Aux10;
1587 device->RealOut.ChannelName[11] = Aux11;
1588 device->RealOut.ChannelName[12] = Aux12;
1589 device->RealOut.ChannelName[13] = Aux13;
1590 device->RealOut.ChannelName[14] = Aux14;
1591 device->RealOut.ChannelName[15] = Aux15;
1593 break;
1597 /* SetDefaultChannelOrder
1599 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1601 void SetDefaultChannelOrder(ALCdevice *device)
1603 ALsizei i;
1605 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1606 device->RealOut.ChannelName[i] = InvalidChannel;
1608 switch(device->FmtChans)
1610 case DevFmtX51Rear:
1611 device->RealOut.ChannelName[0] = FrontLeft;
1612 device->RealOut.ChannelName[1] = FrontRight;
1613 device->RealOut.ChannelName[2] = BackLeft;
1614 device->RealOut.ChannelName[3] = BackRight;
1615 device->RealOut.ChannelName[4] = FrontCenter;
1616 device->RealOut.ChannelName[5] = LFE;
1617 return;
1618 case DevFmtX71:
1619 device->RealOut.ChannelName[0] = FrontLeft;
1620 device->RealOut.ChannelName[1] = FrontRight;
1621 device->RealOut.ChannelName[2] = BackLeft;
1622 device->RealOut.ChannelName[3] = BackRight;
1623 device->RealOut.ChannelName[4] = FrontCenter;
1624 device->RealOut.ChannelName[5] = LFE;
1625 device->RealOut.ChannelName[6] = SideLeft;
1626 device->RealOut.ChannelName[7] = SideRight;
1627 return;
1629 /* Same as WFX order */
1630 case DevFmtMono:
1631 case DevFmtStereo:
1632 case DevFmtQuad:
1633 case DevFmtX51:
1634 case DevFmtX61:
1635 case DevFmtAmbi3D:
1636 SetDefaultWFXChannelOrder(device);
1637 break;
1641 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1644 /* ALCcontext_DeferUpdates
1646 * Defers/suspends updates for the given context's listener and sources. This
1647 * does *NOT* stop mixing, but rather prevents certain property changes from
1648 * taking effect.
1650 void ALCcontext_DeferUpdates(ALCcontext *context)
1652 ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE);
1655 /* ALCcontext_ProcessUpdates
1657 * Resumes update processing after being deferred.
1659 void ALCcontext_ProcessUpdates(ALCcontext *context)
1661 ReadLock(&context->PropLock);
1662 if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
1664 /* Tell the mixer to stop applying updates, then wait for any active
1665 * updating to finish, before providing updates.
1667 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1668 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1669 althrd_yield();
1671 if(!ATOMIC_FLAG_TEST_AND_SET(&context->PropsClean, almemory_order_acq_rel))
1672 UpdateContextProps(context);
1673 if(!ATOMIC_FLAG_TEST_AND_SET(&context->Listener->PropsClean, almemory_order_acq_rel))
1674 UpdateListenerProps(context);
1675 UpdateAllEffectSlotProps(context);
1676 UpdateAllSourceProps(context);
1678 /* Now with all updates declared, let the mixer continue applying them
1679 * so they all happen at once.
1681 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1683 ReadUnlock(&context->PropLock);
1687 /* alcSetError
1689 * Stores the latest ALC device error
1691 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1693 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1694 if(TrapALCError)
1696 #ifdef _WIN32
1697 /* DebugBreak() will cause an exception if there is no debugger */
1698 if(IsDebuggerPresent())
1699 DebugBreak();
1700 #elif defined(SIGTRAP)
1701 raise(SIGTRAP);
1702 #endif
1705 if(device)
1706 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1707 else
1708 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1712 struct Compressor *CreateDeviceLimiter(const ALCdevice *device)
1714 return CompressorInit(0.0f, 0.0f, AL_FALSE, AL_TRUE, 0.0f, 0.0f, 0.5f, 2.0f,
1715 0.0f, -3.0f, 3.0f, device->Frequency);
1718 /* UpdateClockBase
1720 * Updates the device's base clock time with however many samples have been
1721 * done. This is used so frequency changes on the device don't cause the time
1722 * to jump forward or back. Must not be called while the device is running/
1723 * mixing.
1725 static inline void UpdateClockBase(ALCdevice *device)
1727 IncrementRef(&device->MixCount);
1728 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1729 device->SamplesDone = 0;
1730 IncrementRef(&device->MixCount);
1733 /* UpdateDeviceParams
1735 * Updates device parameters according to the attribute list (caller is
1736 * responsible for holding the list lock).
1738 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1740 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1741 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1742 ALCenum gainLimiter = device->Limiter ? ALC_TRUE : ALC_FALSE;
1743 const ALsizei old_sends = device->NumAuxSends;
1744 ALsizei new_sends = device->NumAuxSends;
1745 enum DevFmtChannels oldChans;
1746 enum DevFmtType oldType;
1747 ALboolean update_failed;
1748 ALCsizei hrtf_id = -1;
1749 ALCcontext *context;
1750 ALCuint oldFreq;
1751 size_t size;
1752 ALCsizei i;
1753 int val;
1755 // Check for attributes
1756 if(device->Type == Loopback)
1758 ALCsizei numMono, numStereo, numSends;
1759 ALCenum alayout = AL_NONE;
1760 ALCenum ascale = AL_NONE;
1761 ALCenum schans = AL_NONE;
1762 ALCenum stype = AL_NONE;
1763 ALCsizei attrIdx = 0;
1764 ALCsizei aorder = 0;
1765 ALCuint freq = 0;
1767 if(!attrList)
1769 WARN("Missing attributes for loopback device\n");
1770 return ALC_INVALID_VALUE;
1773 numMono = device->NumMonoSources;
1774 numStereo = device->NumStereoSources;
1775 numSends = old_sends;
1777 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1778 while(attrList[attrIdx])
1780 switch(attrList[attrIdx])
1782 case ALC_FORMAT_CHANNELS_SOFT:
1783 schans = attrList[attrIdx + 1];
1784 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1785 if(!IsValidALCChannels(schans))
1786 return ALC_INVALID_VALUE;
1787 break;
1789 case ALC_FORMAT_TYPE_SOFT:
1790 stype = attrList[attrIdx + 1];
1791 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1792 if(!IsValidALCType(stype))
1793 return ALC_INVALID_VALUE;
1794 break;
1796 case ALC_FREQUENCY:
1797 freq = attrList[attrIdx + 1];
1798 TRACE_ATTR(ALC_FREQUENCY, freq);
1799 if(freq < MIN_OUTPUT_RATE)
1800 return ALC_INVALID_VALUE;
1801 break;
1803 case ALC_AMBISONIC_LAYOUT_SOFT:
1804 alayout = attrList[attrIdx + 1];
1805 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1806 if(!IsValidAmbiLayout(alayout))
1807 return ALC_INVALID_VALUE;
1808 break;
1810 case ALC_AMBISONIC_SCALING_SOFT:
1811 ascale = attrList[attrIdx + 1];
1812 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1813 if(!IsValidAmbiScaling(ascale))
1814 return ALC_INVALID_VALUE;
1815 break;
1817 case ALC_AMBISONIC_ORDER_SOFT:
1818 aorder = attrList[attrIdx + 1];
1819 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1820 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1821 return ALC_INVALID_VALUE;
1822 break;
1824 case ALC_MONO_SOURCES:
1825 numMono = attrList[attrIdx + 1];
1826 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1827 numMono = maxi(numMono, 0);
1828 break;
1830 case ALC_STEREO_SOURCES:
1831 numStereo = attrList[attrIdx + 1];
1832 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1833 numStereo = maxi(numStereo, 0);
1834 break;
1836 case ALC_MAX_AUXILIARY_SENDS:
1837 numSends = attrList[attrIdx + 1];
1838 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1839 numSends = clampi(numSends, 0, MAX_SENDS);
1840 break;
1842 case ALC_HRTF_SOFT:
1843 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1844 if(attrList[attrIdx + 1] == ALC_FALSE)
1845 hrtf_appreq = Hrtf_Disable;
1846 else if(attrList[attrIdx + 1] == ALC_TRUE)
1847 hrtf_appreq = Hrtf_Enable;
1848 else
1849 hrtf_appreq = Hrtf_Default;
1850 break;
1852 case ALC_HRTF_ID_SOFT:
1853 hrtf_id = attrList[attrIdx + 1];
1854 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1855 break;
1857 case ALC_OUTPUT_LIMITER_SOFT:
1858 gainLimiter = attrList[attrIdx + 1];
1859 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1860 break;
1862 default:
1863 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList[attrIdx],
1864 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1865 break;
1868 attrIdx += 2;
1870 #undef TRACE_ATTR
1872 if(!schans || !stype || !freq)
1874 WARN("Missing format for loopback device\n");
1875 return ALC_INVALID_VALUE;
1877 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1879 WARN("Missing ambisonic info for loopback device\n");
1880 return ALC_INVALID_VALUE;
1883 if((device->Flags&DEVICE_RUNNING))
1884 V0(device->Backend,stop)();
1885 device->Flags &= ~DEVICE_RUNNING;
1887 UpdateClockBase(device);
1889 device->Frequency = freq;
1890 device->FmtChans = schans;
1891 device->FmtType = stype;
1892 if(schans == ALC_BFORMAT3D_SOFT)
1894 device->AmbiOrder = aorder;
1895 device->AmbiLayout = alayout;
1896 device->AmbiScale = ascale;
1899 if(numMono > INT_MAX-numStereo)
1900 numMono = INT_MAX-numStereo;
1901 numMono += numStereo;
1902 if(ConfigValueInt(NULL, NULL, "sources", &numMono))
1904 if(numMono <= 0)
1905 numMono = 256;
1907 else
1908 numMono = maxi(numMono, 256);
1909 numStereo = mini(numStereo, numMono);
1910 numMono -= numStereo;
1911 device->SourcesMax = numMono + numStereo;
1913 device->NumMonoSources = numMono;
1914 device->NumStereoSources = numStereo;
1916 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1917 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1918 else
1919 new_sends = numSends;
1921 else if(attrList && attrList[0])
1923 ALCsizei numMono, numStereo, numSends;
1924 ALCsizei attrIdx = 0;
1925 ALCuint freq;
1927 /* If a context is already running on the device, stop playback so the
1928 * device attributes can be updated. */
1929 if((device->Flags&DEVICE_RUNNING))
1930 V0(device->Backend,stop)();
1931 device->Flags &= ~DEVICE_RUNNING;
1933 UpdateClockBase(device);
1935 freq = device->Frequency;
1936 numMono = device->NumMonoSources;
1937 numStereo = device->NumStereoSources;
1938 numSends = old_sends;
1940 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1941 while(attrList[attrIdx])
1943 switch(attrList[attrIdx])
1945 case ALC_FREQUENCY:
1946 freq = attrList[attrIdx + 1];
1947 TRACE_ATTR(ALC_FREQUENCY, freq);
1948 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1949 break;
1951 case ALC_MONO_SOURCES:
1952 numMono = attrList[attrIdx + 1];
1953 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1954 numMono = maxi(numMono, 0);
1955 break;
1957 case ALC_STEREO_SOURCES:
1958 numStereo = attrList[attrIdx + 1];
1959 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1960 numStereo = maxi(numStereo, 0);
1961 break;
1963 case ALC_MAX_AUXILIARY_SENDS:
1964 numSends = attrList[attrIdx + 1];
1965 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1966 numSends = clampi(numSends, 0, MAX_SENDS);
1967 break;
1969 case ALC_HRTF_SOFT:
1970 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1971 if(attrList[attrIdx + 1] == ALC_FALSE)
1972 hrtf_appreq = Hrtf_Disable;
1973 else if(attrList[attrIdx + 1] == ALC_TRUE)
1974 hrtf_appreq = Hrtf_Enable;
1975 else
1976 hrtf_appreq = Hrtf_Default;
1977 break;
1979 case ALC_HRTF_ID_SOFT:
1980 hrtf_id = attrList[attrIdx + 1];
1981 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1982 break;
1984 case ALC_OUTPUT_LIMITER_SOFT:
1985 gainLimiter = attrList[attrIdx + 1];
1986 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1987 break;
1989 default:
1990 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
1991 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1992 break;
1995 attrIdx += 2;
1997 #undef TRACE_ATTR
1999 ConfigValueUInt(alstr_get_cstr(device->DeviceName), NULL, "frequency", &freq);
2000 freq = maxu(freq, MIN_OUTPUT_RATE);
2002 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
2003 device->Frequency;
2004 /* SSE and Neon do best with the update size being a multiple of 4 */
2005 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2006 device->UpdateSize = (device->UpdateSize+3)&~3;
2008 device->Frequency = freq;
2010 if(numMono > INT_MAX-numStereo)
2011 numMono = INT_MAX-numStereo;
2012 numMono += numStereo;
2013 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono))
2015 if(numMono <= 0)
2016 numMono = 256;
2018 else
2019 numMono = maxi(numMono, 256);
2020 numStereo = mini(numStereo, numMono);
2021 numMono -= numStereo;
2022 device->SourcesMax = numMono + numStereo;
2024 device->NumMonoSources = numMono;
2025 device->NumStereoSources = numStereo;
2027 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2028 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2029 else
2030 new_sends = numSends;
2033 if((device->Flags&DEVICE_RUNNING))
2034 return ALC_NO_ERROR;
2036 al_free(device->Uhj_Encoder);
2037 device->Uhj_Encoder = NULL;
2039 al_free(device->Bs2b);
2040 device->Bs2b = NULL;
2042 al_free(device->ChannelDelay[0].Buffer);
2043 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2045 device->ChannelDelay[i].Length = 0;
2046 device->ChannelDelay[i].Buffer = NULL;
2049 al_free(device->Dry.Buffer);
2050 device->Dry.Buffer = NULL;
2051 device->Dry.NumChannels = 0;
2052 device->FOAOut.Buffer = NULL;
2053 device->FOAOut.NumChannels = 0;
2054 device->RealOut.Buffer = NULL;
2055 device->RealOut.NumChannels = 0;
2057 UpdateClockBase(device);
2059 device->DitherSeed = DITHER_RNG_SEED;
2061 /*************************************************************************
2062 * Update device format request if HRTF is requested
2064 device->HrtfStatus = ALC_HRTF_DISABLED_SOFT;
2065 if(device->Type != Loopback)
2067 const char *hrtf;
2068 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2070 if(strcasecmp(hrtf, "true") == 0)
2071 hrtf_userreq = Hrtf_Enable;
2072 else if(strcasecmp(hrtf, "false") == 0)
2073 hrtf_userreq = Hrtf_Disable;
2074 else if(strcasecmp(hrtf, "auto") != 0)
2075 ERR("Unexpected hrtf value: %s\n", hrtf);
2078 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2080 struct Hrtf *hrtf = NULL;
2081 if(VECTOR_SIZE(device->HrtfList) == 0)
2083 VECTOR_DEINIT(device->HrtfList);
2084 device->HrtfList = EnumerateHrtf(device->DeviceName);
2086 if(VECTOR_SIZE(device->HrtfList) > 0)
2088 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
2089 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
2090 else
2091 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
2094 if(hrtf)
2096 device->FmtChans = DevFmtStereo;
2097 device->Frequency = hrtf->sampleRate;
2098 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2099 if(device->HrtfHandle)
2100 Hrtf_DecRef(device->HrtfHandle);
2101 device->HrtfHandle = hrtf;
2103 else
2105 hrtf_userreq = Hrtf_Default;
2106 hrtf_appreq = Hrtf_Disable;
2107 device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2112 oldFreq = device->Frequency;
2113 oldChans = device->FmtChans;
2114 oldType = device->FmtType;
2116 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2117 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2118 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2119 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2120 device->UpdateSize, device->NumUpdates
2123 if(V0(device->Backend,reset)() == ALC_FALSE)
2124 return ALC_INVALID_DEVICE;
2126 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2128 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2129 DevFmtChannelsString(device->FmtChans));
2130 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2132 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2134 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2135 DevFmtTypeString(device->FmtType));
2136 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2138 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2140 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2141 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2144 if((device->UpdateSize&3) != 0)
2146 if((CPUCapFlags&CPU_CAP_SSE))
2147 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2148 if((CPUCapFlags&CPU_CAP_NEON))
2149 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2152 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2153 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2154 device->Frequency, device->UpdateSize, device->NumUpdates
2157 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2158 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2159 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2161 /* Allocate extra channels for any post-filter output. */
2162 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2163 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2165 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2166 device->Dry.Buffer = al_calloc(16, size);
2167 if(!device->Dry.Buffer)
2169 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2170 return ALC_INVALID_DEVICE;
2173 if(device->RealOut.NumChannels != 0)
2174 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2175 device->FOAOut.NumChannels;
2176 else
2178 device->RealOut.Buffer = device->Dry.Buffer;
2179 device->RealOut.NumChannels = device->Dry.NumChannels;
2182 if(device->FOAOut.NumChannels != 0)
2183 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2184 else
2186 device->FOAOut.Buffer = device->Dry.Buffer;
2187 device->FOAOut.NumChannels = device->Dry.NumChannels;
2190 device->NumAuxSends = new_sends;
2191 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2192 device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2193 device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2195 device->DitherDepth = 0.0f;
2196 if(GetConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "dither", 1))
2198 ALint depth = 0;
2199 ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "dither-depth", &depth);
2200 if(depth <= 0)
2202 switch(device->FmtType)
2204 case DevFmtByte:
2205 case DevFmtUByte:
2206 depth = 8;
2207 break;
2208 case DevFmtShort:
2209 case DevFmtUShort:
2210 depth = 16;
2211 break;
2212 case DevFmtInt:
2213 case DevFmtUInt:
2214 case DevFmtFloat:
2215 break;
2218 else if(depth > 24)
2219 depth = 24;
2220 device->DitherDepth = (depth > 0) ? powf(2.0f, (ALfloat)(depth-1)) : 0.0f;
2222 if(!(device->DitherDepth > 0.0f))
2223 TRACE("Dithering disabled\n");
2224 else
2225 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device->DitherDepth)+1.0f,
2226 device->DitherDepth);
2228 if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
2229 gainLimiter = val ? ALC_TRUE : ALC_FALSE;
2230 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2231 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2232 * ALC_TRUE.
2234 if(gainLimiter != ALC_FALSE)
2236 if(!device->Limiter || device->Frequency != GetCompressorSampleRate(device->Limiter))
2238 al_free(device->Limiter);
2239 device->Limiter = CreateDeviceLimiter(device);
2242 else
2244 al_free(device->Limiter);
2245 device->Limiter = NULL;
2247 TRACE("Output limiter %s\n", device->Limiter ? "enabled" : "disabled");
2249 /* Need to delay returning failure until replacement Send arrays have been
2250 * allocated with the appropriate size.
2252 update_failed = AL_FALSE;
2253 START_MIXER_MODE();
2254 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2255 while(context)
2257 struct ALvoiceProps *vprops;
2258 ALsizei pos;
2260 if(context->DefaultSlot)
2262 ALeffectslot *slot = context->DefaultSlot;
2263 ALeffectState *state = slot->Effect.State;
2265 state->OutBuffer = device->Dry.Buffer;
2266 state->OutChannels = device->Dry.NumChannels;
2267 if(V(state,deviceUpdate)(device) == AL_FALSE)
2268 update_failed = AL_TRUE;
2269 else
2270 UpdateEffectSlotProps(slot, context);
2273 WriteLock(&context->PropLock);
2274 LockUIntMapRead(&context->EffectSlotMap);
2275 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2277 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2278 ALeffectState *state = slot->Effect.State;
2280 state->OutBuffer = device->Dry.Buffer;
2281 state->OutChannels = device->Dry.NumChannels;
2282 if(V(state,deviceUpdate)(device) == AL_FALSE)
2283 update_failed = AL_TRUE;
2284 else
2285 UpdateEffectSlotProps(slot, context);
2287 UnlockUIntMapRead(&context->EffectSlotMap);
2289 LockUIntMapRead(&context->SourceMap);
2290 RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax);
2291 for(pos = 0;pos < context->SourceMap.size;pos++)
2293 ALsource *source = context->SourceMap.values[pos];
2295 if(old_sends != device->NumAuxSends)
2297 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2298 ALsizei s;
2300 memcpy(sends, source->Send,
2301 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2303 for(s = device->NumAuxSends;s < old_sends;s++)
2305 if(source->Send[s].Slot)
2306 DecrementRef(&source->Send[s].Slot->ref);
2307 source->Send[s].Slot = NULL;
2309 al_free(source->Send);
2310 source->Send = sends;
2311 for(s = old_sends;s < device->NumAuxSends;s++)
2313 source->Send[s].Slot = NULL;
2314 source->Send[s].Gain = 1.0f;
2315 source->Send[s].GainHF = 1.0f;
2316 source->Send[s].HFReference = LOWPASSFREQREF;
2317 source->Send[s].GainLF = 1.0f;
2318 source->Send[s].LFReference = HIGHPASSFREQREF;
2322 ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
2325 /* Clear any pre-existing voice property structs, in case the number of
2326 * auxiliary sends is changing. Active sources will have updates
2327 * respecified in UpdateAllSourceProps.
2329 vprops = ATOMIC_EXCHANGE_PTR(&context->FreeVoiceProps, NULL, almemory_order_acq_rel);
2330 while(vprops)
2332 struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed);
2333 al_free(vprops);
2334 vprops = next;
2337 AllocateVoices(context, context->MaxVoices, old_sends);
2338 for(pos = 0;pos < context->VoiceCount;pos++)
2340 ALvoice *voice = context->Voices[pos];
2342 al_free(ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_acq_rel));
2344 if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
2345 continue;
2347 if(device->AvgSpeakerDist > 0.0f)
2349 /* Reinitialize the NFC filters for new parameters. */
2350 ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
2351 (device->AvgSpeakerDist * device->Frequency);
2352 for(i = 0;i < voice->NumChannels;i++)
2354 NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1);
2355 NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1);
2356 NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1);
2360 UnlockUIntMapRead(&context->SourceMap);
2362 ATOMIC_FLAG_TEST_AND_SET(&context->PropsClean, almemory_order_release);
2363 UpdateContextProps(context);
2364 ATOMIC_FLAG_TEST_AND_SET(&context->Listener->PropsClean, almemory_order_release);
2365 UpdateListenerProps(context);
2366 UpdateAllSourceProps(context);
2367 WriteUnlock(&context->PropLock);
2369 context = context->next;
2371 END_MIXER_MODE();
2372 if(update_failed)
2373 return ALC_INVALID_DEVICE;
2375 if(!(device->Flags&DEVICE_PAUSED))
2377 if(V0(device->Backend,start)() == ALC_FALSE)
2378 return ALC_INVALID_DEVICE;
2379 device->Flags |= DEVICE_RUNNING;
2382 return ALC_NO_ERROR;
2385 /* FreeDevice
2387 * Frees the device structure, and destroys any objects the app failed to
2388 * delete. Called once there's no more references on the device.
2390 static ALCvoid FreeDevice(ALCdevice *device)
2392 ALsizei i;
2394 TRACE("%p\n", device);
2396 V0(device->Backend,close)();
2397 DELETE_OBJ(device->Backend);
2398 device->Backend = NULL;
2400 almtx_destroy(&device->BackendLock);
2402 if(device->BufferMap.size > 0)
2404 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2405 (device->BufferMap.size==1)?"":"s");
2406 ReleaseALBuffers(device);
2408 ResetUIntMap(&device->BufferMap);
2410 if(device->EffectMap.size > 0)
2412 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2413 (device->EffectMap.size==1)?"":"s");
2414 ReleaseALEffects(device);
2416 ResetUIntMap(&device->EffectMap);
2418 if(device->FilterMap.size > 0)
2420 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2421 (device->FilterMap.size==1)?"":"s");
2422 ReleaseALFilters(device);
2424 ResetUIntMap(&device->FilterMap);
2426 AL_STRING_DEINIT(device->HrtfName);
2427 FreeHrtfList(&device->HrtfList);
2428 if(device->HrtfHandle)
2429 Hrtf_DecRef(device->HrtfHandle);
2430 device->HrtfHandle = NULL;
2431 al_free(device->Hrtf);
2432 device->Hrtf = NULL;
2434 al_free(device->Bs2b);
2435 device->Bs2b = NULL;
2437 al_free(device->Uhj_Encoder);
2438 device->Uhj_Encoder = NULL;
2440 bformatdec_free(device->AmbiDecoder);
2441 device->AmbiDecoder = NULL;
2443 ambiup_free(device->AmbiUp);
2444 device->AmbiUp = NULL;
2446 al_free(device->Stablizer);
2447 device->Stablizer = NULL;
2449 al_free(device->Limiter);
2450 device->Limiter = NULL;
2452 al_free(device->ChannelDelay[0].Buffer);
2453 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2455 device->ChannelDelay[i].Gain = 1.0f;
2456 device->ChannelDelay[i].Length = 0;
2457 device->ChannelDelay[i].Buffer = NULL;
2460 AL_STRING_DEINIT(device->DeviceName);
2462 al_free(device->Dry.Buffer);
2463 device->Dry.Buffer = NULL;
2464 device->Dry.NumChannels = 0;
2465 device->FOAOut.Buffer = NULL;
2466 device->FOAOut.NumChannels = 0;
2467 device->RealOut.Buffer = NULL;
2468 device->RealOut.NumChannels = 0;
2470 al_free(device);
2474 void ALCdevice_IncRef(ALCdevice *device)
2476 uint ref;
2477 ref = IncrementRef(&device->ref);
2478 TRACEREF("%p increasing refcount to %u\n", device, ref);
2481 void ALCdevice_DecRef(ALCdevice *device)
2483 uint ref;
2484 ref = DecrementRef(&device->ref);
2485 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2486 if(ref == 0) FreeDevice(device);
2489 /* VerifyDevice
2491 * Checks if the device handle is valid, and increments its ref count if so.
2493 static ALCboolean VerifyDevice(ALCdevice **device)
2495 ALCdevice *tmpDevice;
2497 LockLists();
2498 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2499 while(tmpDevice)
2501 if(tmpDevice == *device)
2503 ALCdevice_IncRef(tmpDevice);
2504 UnlockLists();
2505 return ALC_TRUE;
2507 tmpDevice = tmpDevice->next;
2509 UnlockLists();
2511 *device = NULL;
2512 return ALC_FALSE;
2516 /* InitContext
2518 * Initializes context fields
2520 static ALvoid InitContext(ALCcontext *Context)
2522 ALlistener *listener = Context->Listener;
2523 struct ALeffectslotArray *auxslots;
2525 //Initialise listener
2526 listener->Gain = 1.0f;
2527 listener->Position[0] = 0.0f;
2528 listener->Position[1] = 0.0f;
2529 listener->Position[2] = 0.0f;
2530 listener->Velocity[0] = 0.0f;
2531 listener->Velocity[1] = 0.0f;
2532 listener->Velocity[2] = 0.0f;
2533 listener->Forward[0] = 0.0f;
2534 listener->Forward[1] = 0.0f;
2535 listener->Forward[2] = -1.0f;
2536 listener->Up[0] = 0.0f;
2537 listener->Up[1] = 1.0f;
2538 listener->Up[2] = 0.0f;
2539 ATOMIC_FLAG_TEST_AND_SET(&listener->PropsClean, almemory_order_relaxed);
2541 ATOMIC_INIT(&listener->Update, NULL);
2543 //Validate Context
2544 InitRef(&Context->UpdateCount, 0);
2545 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2546 Context->GainBoost = 1.0f;
2547 RWLockInit(&Context->PropLock);
2548 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2549 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2550 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2552 if(Context->DefaultSlot)
2554 auxslots = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, 1));
2555 auxslots->count = 1;
2556 auxslots->slot[0] = Context->DefaultSlot;
2558 else
2560 auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray));
2561 auxslots->count = 0;
2563 ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots);
2565 //Set globals
2566 Context->DistanceModel = DefaultDistanceModel;
2567 Context->SourceDistanceModel = AL_FALSE;
2568 Context->DopplerFactor = 1.0f;
2569 Context->DopplerVelocity = 1.0f;
2570 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2571 Context->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT;
2572 ATOMIC_FLAG_TEST_AND_SET(&Context->PropsClean, almemory_order_relaxed);
2573 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2575 ATOMIC_INIT(&Context->Update, NULL);
2576 ATOMIC_INIT(&Context->FreeContextProps, NULL);
2577 ATOMIC_INIT(&Context->FreeListenerProps, NULL);
2578 ATOMIC_INIT(&Context->FreeVoiceProps, NULL);
2579 ATOMIC_INIT(&Context->FreeEffectslotProps, NULL);
2581 Context->ExtensionList = alExtList;
2584 listener->Params.Matrix = IdentityMatrixf;
2585 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2586 listener->Params.Gain = listener->Gain;
2587 listener->Params.MetersPerUnit = Context->MetersPerUnit;
2588 listener->Params.DopplerFactor = Context->DopplerFactor;
2589 listener->Params.SpeedOfSound = Context->SpeedOfSound * Context->DopplerVelocity;
2590 listener->Params.ReverbSpeedOfSound = listener->Params.SpeedOfSound *
2591 listener->Params.MetersPerUnit;
2592 listener->Params.SourceDistanceModel = Context->SourceDistanceModel;
2593 listener->Params.DistanceModel = Context->DistanceModel;
2597 /* FreeContext
2599 * Cleans up the context, and destroys any remaining objects the app failed to
2600 * delete. Called once there's no more references on the context.
2602 static void FreeContext(ALCcontext *context)
2604 ALlistener *listener = context->Listener;
2605 struct ALeffectslotArray *auxslots;
2606 struct ALeffectslotProps *eprops;
2607 struct ALlistenerProps *lprops;
2608 struct ALcontextProps *cprops;
2609 struct ALvoiceProps *vprops;
2610 size_t count;
2611 ALsizei i;
2613 TRACE("%p\n", context);
2615 if((cprops=ATOMIC_LOAD(&context->Update, almemory_order_acquire)) != NULL)
2617 TRACE("Freed unapplied context update %p\n", cprops);
2618 al_free(cprops);
2621 count = 0;
2622 cprops = ATOMIC_LOAD(&context->FreeContextProps, almemory_order_acquire);
2623 while(cprops)
2625 struct ALcontextProps *next = ATOMIC_LOAD(&cprops->next, almemory_order_acquire);
2626 al_free(cprops);
2627 cprops = next;
2628 ++count;
2630 TRACE("Freed "SZFMT" context property object%s\n", count, (count==1)?"":"s");
2632 if(context->DefaultSlot)
2634 DeinitEffectSlot(context->DefaultSlot);
2635 context->DefaultSlot = NULL;
2638 auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
2639 al_free(auxslots);
2641 if(context->SourceMap.size > 0)
2643 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2644 (context->SourceMap.size==1)?"":"s");
2645 ReleaseALSources(context);
2647 ResetUIntMap(&context->SourceMap);
2649 count = 0;
2650 eprops = ATOMIC_LOAD(&context->FreeEffectslotProps, almemory_order_relaxed);
2651 while(eprops)
2653 struct ALeffectslotProps *next = ATOMIC_LOAD(&eprops->next, almemory_order_relaxed);
2654 if(eprops->State) ALeffectState_DecRef(eprops->State);
2655 al_free(eprops);
2656 eprops = next;
2657 ++count;
2659 TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s");
2660 if(context->EffectSlotMap.size > 0)
2662 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2663 (context->EffectSlotMap.size==1)?"":"s");
2664 ReleaseALAuxiliaryEffectSlots(context);
2666 ResetUIntMap(&context->EffectSlotMap);
2668 count = 0;
2669 vprops = ATOMIC_LOAD(&context->FreeVoiceProps, almemory_order_relaxed);
2670 while(vprops)
2672 struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed);
2673 al_free(vprops);
2674 vprops = next;
2675 ++count;
2677 TRACE("Freed "SZFMT" voice property object%s\n", count, (count==1)?"":"s");
2679 for(i = 0;i < context->VoiceCount;i++)
2680 DeinitVoice(context->Voices[i]);
2681 al_free(context->Voices);
2682 context->Voices = NULL;
2683 context->VoiceCount = 0;
2684 context->MaxVoices = 0;
2686 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2688 TRACE("Freed unapplied listener update %p\n", lprops);
2689 al_free(lprops);
2691 count = 0;
2692 lprops = ATOMIC_LOAD(&context->FreeListenerProps, almemory_order_acquire);
2693 while(lprops)
2695 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2696 al_free(lprops);
2697 lprops = next;
2698 ++count;
2700 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2702 ALCdevice_DecRef(context->Device);
2703 context->Device = NULL;
2705 //Invalidate context
2706 memset(context, 0, sizeof(ALCcontext));
2707 al_free(context);
2710 /* ReleaseContext
2712 * Removes the context reference from the given device and removes it from
2713 * being current on the running thread or globally. Returns true if other
2714 * contexts still exist on the device.
2716 static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
2718 ALCcontext *origctx, *newhead;
2719 bool ret = true;
2721 if(altss_get(LocalContext) == context)
2723 WARN("%p released while current on thread\n", context);
2724 altss_set(LocalContext, NULL);
2725 ALCcontext_DecRef(context);
2728 origctx = context;
2729 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
2730 ALCcontext_DecRef(context);
2732 ALCdevice_Lock(device);
2733 origctx = context;
2734 newhead = context->next;
2735 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
2737 ALCcontext *volatile*list = &origctx->next;
2738 while(*list)
2740 if(*list == context)
2742 *list = (*list)->next;
2743 break;
2745 list = &(*list)->next;
2748 else
2749 ret = !!newhead;
2750 ALCdevice_Unlock(device);
2752 ALCcontext_DecRef(context);
2753 return ret;
2756 void ALCcontext_IncRef(ALCcontext *context)
2758 uint ref = IncrementRef(&context->ref);
2759 TRACEREF("%p increasing refcount to %u\n", context, ref);
2762 void ALCcontext_DecRef(ALCcontext *context)
2764 uint ref = DecrementRef(&context->ref);
2765 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2766 if(ref == 0) FreeContext(context);
2769 static void ReleaseThreadCtx(void *ptr)
2771 ALCcontext *context = ptr;
2772 uint ref = DecrementRef(&context->ref);
2773 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2774 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2777 /* VerifyContext
2779 * Checks that the given context is valid, and increments its reference count.
2781 static ALCboolean VerifyContext(ALCcontext **context)
2783 ALCdevice *dev;
2785 LockLists();
2786 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2787 while(dev)
2789 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2790 while(ctx)
2792 if(ctx == *context)
2794 ALCcontext_IncRef(ctx);
2795 UnlockLists();
2796 return ALC_TRUE;
2798 ctx = ctx->next;
2800 dev = dev->next;
2802 UnlockLists();
2804 *context = NULL;
2805 return ALC_FALSE;
2809 /* GetContextRef
2811 * Returns the currently active context for this thread, and adds a reference
2812 * without locking it.
2814 ALCcontext *GetContextRef(void)
2816 ALCcontext *context;
2818 context = altss_get(LocalContext);
2819 if(context)
2820 ALCcontext_IncRef(context);
2821 else
2823 LockLists();
2824 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2825 if(context)
2826 ALCcontext_IncRef(context);
2827 UnlockLists();
2830 return context;
2834 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2836 ALCdevice *device = context->Device;
2837 ALsizei num_sends = device->NumAuxSends;
2838 struct ALvoiceProps *props;
2839 size_t sizeof_props;
2840 size_t sizeof_voice;
2841 ALvoice **voices;
2842 ALvoice *voice;
2843 ALsizei v = 0;
2844 size_t size;
2846 if(num_voices == context->MaxVoices && num_sends == old_sends)
2847 return;
2849 /* Allocate the voice pointers, voices, and the voices' stored source
2850 * property set (including the dynamically-sized Send[] array) in one
2851 * chunk.
2853 sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
2854 sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
2855 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2857 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2858 /* The voice and property objects are stored interleaved since they're
2859 * paired together.
2861 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2862 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2864 if(context->Voices)
2866 const ALsizei v_count = mini(context->VoiceCount, num_voices);
2867 const ALsizei s_count = mini(old_sends, num_sends);
2869 for(;v < v_count;v++)
2871 ALvoice *old_voice = context->Voices[v];
2872 ALsizei i;
2874 /* Copy the old voice data and source property set to the new
2875 * storage.
2877 *voice = *old_voice;
2878 for(i = 0;i < s_count;i++)
2879 voice->Send[i] = old_voice->Send[i];
2880 *props = *(old_voice->Props);
2881 for(i = 0;i < s_count;i++)
2882 props->Send[i] = old_voice->Props->Send[i];
2884 /* Set this voice's property set pointer and voice reference. */
2885 voice->Props = props;
2886 voices[v] = voice;
2888 /* Increment pointers to the next storage space. */
2889 voice = (ALvoice*)((char*)props + sizeof_props);
2890 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2892 /* Deinit any left over voices that weren't copied over to the new
2893 * array. NOTE: If this does anything, v equals num_voices and
2894 * num_voices is less than VoiceCount, so the following loop won't do
2895 * anything.
2897 for(;v < context->VoiceCount;v++)
2898 DeinitVoice(context->Voices[v]);
2900 /* Finish setting the voices' property set pointers and references. */
2901 for(;v < num_voices;v++)
2903 ATOMIC_INIT(&voice->Update, NULL);
2905 voice->Props = props;
2906 voices[v] = voice;
2908 voice = (ALvoice*)((char*)props + sizeof_props);
2909 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2912 al_free(context->Voices);
2913 context->Voices = voices;
2914 context->MaxVoices = num_voices;
2915 context->VoiceCount = mini(context->VoiceCount, num_voices);
2919 /************************************************
2920 * Standard ALC functions
2921 ************************************************/
2923 /* alcGetError
2925 * Return last ALC generated error code for the given device
2927 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2929 ALCenum errorCode;
2931 if(VerifyDevice(&device))
2933 errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
2934 ALCdevice_DecRef(device);
2936 else
2937 errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
2939 return errorCode;
2943 /* alcSuspendContext
2945 * Suspends updates for the given context
2947 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2949 if(!SuspendDefers)
2950 return;
2952 if(!VerifyContext(&context))
2953 alcSetError(NULL, ALC_INVALID_CONTEXT);
2954 else
2956 ALCcontext_DeferUpdates(context);
2957 ALCcontext_DecRef(context);
2961 /* alcProcessContext
2963 * Resumes processing updates for the given context
2965 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2967 if(!SuspendDefers)
2968 return;
2970 if(!VerifyContext(&context))
2971 alcSetError(NULL, ALC_INVALID_CONTEXT);
2972 else
2974 ALCcontext_ProcessUpdates(context);
2975 ALCcontext_DecRef(context);
2980 /* alcGetString
2982 * Returns information about the device, and error strings
2984 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2986 const ALCchar *value = NULL;
2988 switch(param)
2990 case ALC_NO_ERROR:
2991 value = alcNoError;
2992 break;
2994 case ALC_INVALID_ENUM:
2995 value = alcErrInvalidEnum;
2996 break;
2998 case ALC_INVALID_VALUE:
2999 value = alcErrInvalidValue;
3000 break;
3002 case ALC_INVALID_DEVICE:
3003 value = alcErrInvalidDevice;
3004 break;
3006 case ALC_INVALID_CONTEXT:
3007 value = alcErrInvalidContext;
3008 break;
3010 case ALC_OUT_OF_MEMORY:
3011 value = alcErrOutOfMemory;
3012 break;
3014 case ALC_DEVICE_SPECIFIER:
3015 value = alcDefaultName;
3016 break;
3018 case ALC_ALL_DEVICES_SPECIFIER:
3019 if(VerifyDevice(&Device))
3021 value = alstr_get_cstr(Device->DeviceName);
3022 ALCdevice_DecRef(Device);
3024 else
3026 ProbeAllDevicesList();
3027 value = alstr_get_cstr(alcAllDevicesList);
3029 break;
3031 case ALC_CAPTURE_DEVICE_SPECIFIER:
3032 if(VerifyDevice(&Device))
3034 value = alstr_get_cstr(Device->DeviceName);
3035 ALCdevice_DecRef(Device);
3037 else
3039 ProbeCaptureDeviceList();
3040 value = alstr_get_cstr(alcCaptureDeviceList);
3042 break;
3044 /* Default devices are always first in the list */
3045 case ALC_DEFAULT_DEVICE_SPECIFIER:
3046 value = alcDefaultName;
3047 break;
3049 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
3050 if(alstr_empty(alcAllDevicesList))
3051 ProbeAllDevicesList();
3053 VerifyDevice(&Device);
3055 free(alcDefaultAllDevicesSpecifier);
3056 alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
3057 if(!alcDefaultAllDevicesSpecifier)
3058 alcSetError(Device, ALC_OUT_OF_MEMORY);
3060 value = alcDefaultAllDevicesSpecifier;
3061 if(Device) ALCdevice_DecRef(Device);
3062 break;
3064 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
3065 if(alstr_empty(alcCaptureDeviceList))
3066 ProbeCaptureDeviceList();
3068 VerifyDevice(&Device);
3070 free(alcCaptureDefaultDeviceSpecifier);
3071 alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
3072 if(!alcCaptureDefaultDeviceSpecifier)
3073 alcSetError(Device, ALC_OUT_OF_MEMORY);
3075 value = alcCaptureDefaultDeviceSpecifier;
3076 if(Device) ALCdevice_DecRef(Device);
3077 break;
3079 case ALC_EXTENSIONS:
3080 if(!VerifyDevice(&Device))
3081 value = alcNoDeviceExtList;
3082 else
3084 value = alcExtensionList;
3085 ALCdevice_DecRef(Device);
3087 break;
3089 case ALC_HRTF_SPECIFIER_SOFT:
3090 if(!VerifyDevice(&Device))
3091 alcSetError(NULL, ALC_INVALID_DEVICE);
3092 else
3094 almtx_lock(&Device->BackendLock);
3095 value = (Device->HrtfHandle ? alstr_get_cstr(Device->HrtfName) : "");
3096 almtx_unlock(&Device->BackendLock);
3097 ALCdevice_DecRef(Device);
3099 break;
3101 default:
3102 VerifyDevice(&Device);
3103 alcSetError(Device, ALC_INVALID_ENUM);
3104 if(Device) ALCdevice_DecRef(Device);
3105 break;
3108 return value;
3112 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
3114 if(device->Type == Loopback && device->FmtChans == DevFmtAmbi3D)
3115 return 27;
3116 return 21;
3119 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3121 ALCsizei i;
3123 if(size <= 0 || values == NULL)
3125 alcSetError(device, ALC_INVALID_VALUE);
3126 return 0;
3129 if(!device)
3131 switch(param)
3133 case ALC_MAJOR_VERSION:
3134 values[0] = alcMajorVersion;
3135 return 1;
3136 case ALC_MINOR_VERSION:
3137 values[0] = alcMinorVersion;
3138 return 1;
3140 case ALC_ATTRIBUTES_SIZE:
3141 case ALC_ALL_ATTRIBUTES:
3142 case ALC_FREQUENCY:
3143 case ALC_REFRESH:
3144 case ALC_SYNC:
3145 case ALC_MONO_SOURCES:
3146 case ALC_STEREO_SOURCES:
3147 case ALC_CAPTURE_SAMPLES:
3148 case ALC_FORMAT_CHANNELS_SOFT:
3149 case ALC_FORMAT_TYPE_SOFT:
3150 case ALC_AMBISONIC_LAYOUT_SOFT:
3151 case ALC_AMBISONIC_SCALING_SOFT:
3152 case ALC_AMBISONIC_ORDER_SOFT:
3153 case ALC_MAX_AMBISONIC_ORDER_SOFT:
3154 alcSetError(NULL, ALC_INVALID_DEVICE);
3155 return 0;
3157 default:
3158 alcSetError(NULL, ALC_INVALID_ENUM);
3159 return 0;
3161 return 0;
3164 if(device->Type == Capture)
3166 switch(param)
3168 case ALC_CAPTURE_SAMPLES:
3169 almtx_lock(&device->BackendLock);
3170 values[0] = V0(device->Backend,availableSamples)();
3171 almtx_unlock(&device->BackendLock);
3172 return 1;
3174 case ALC_CONNECTED:
3175 values[0] = device->Connected;
3176 return 1;
3178 default:
3179 alcSetError(device, ALC_INVALID_ENUM);
3180 return 0;
3182 return 0;
3185 /* render device */
3186 switch(param)
3188 case ALC_MAJOR_VERSION:
3189 values[0] = alcMajorVersion;
3190 return 1;
3192 case ALC_MINOR_VERSION:
3193 values[0] = alcMinorVersion;
3194 return 1;
3196 case ALC_EFX_MAJOR_VERSION:
3197 values[0] = alcEFXMajorVersion;
3198 return 1;
3200 case ALC_EFX_MINOR_VERSION:
3201 values[0] = alcEFXMinorVersion;
3202 return 1;
3204 case ALC_MAX_AMBISONIC_ORDER_SOFT:
3205 values[0] = MAX_AMBI_ORDER;
3206 return 1;
3208 case ALC_ATTRIBUTES_SIZE:
3209 values[0] = NumAttrsForDevice(device);
3210 return 1;
3212 case ALC_ALL_ATTRIBUTES:
3213 if(size < NumAttrsForDevice(device))
3215 alcSetError(device, ALC_INVALID_VALUE);
3216 return 0;
3219 i = 0;
3220 almtx_lock(&device->BackendLock);
3221 values[i++] = ALC_FREQUENCY;
3222 values[i++] = device->Frequency;
3224 if(device->Type != Loopback)
3226 values[i++] = ALC_REFRESH;
3227 values[i++] = device->Frequency / device->UpdateSize;
3229 values[i++] = ALC_SYNC;
3230 values[i++] = ALC_FALSE;
3232 else
3234 if(device->FmtChans == DevFmtAmbi3D)
3236 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3237 values[i++] = device->AmbiLayout;
3239 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3240 values[i++] = device->AmbiScale;
3242 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3243 values[i++] = device->AmbiOrder;
3246 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3247 values[i++] = device->FmtChans;
3249 values[i++] = ALC_FORMAT_TYPE_SOFT;
3250 values[i++] = device->FmtType;
3253 values[i++] = ALC_MONO_SOURCES;
3254 values[i++] = device->NumMonoSources;
3256 values[i++] = ALC_STEREO_SOURCES;
3257 values[i++] = device->NumStereoSources;
3259 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3260 values[i++] = device->NumAuxSends;
3262 values[i++] = ALC_HRTF_SOFT;
3263 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3265 values[i++] = ALC_HRTF_STATUS_SOFT;
3266 values[i++] = device->HrtfStatus;
3268 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3269 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3271 values[i++] = ALC_MAX_AMBISONIC_ORDER_SOFT;
3272 values[i++] = MAX_AMBI_ORDER;
3273 almtx_unlock(&device->BackendLock);
3275 values[i++] = 0;
3276 return i;
3278 case ALC_FREQUENCY:
3279 values[0] = device->Frequency;
3280 return 1;
3282 case ALC_REFRESH:
3283 if(device->Type == Loopback)
3285 alcSetError(device, ALC_INVALID_DEVICE);
3286 return 0;
3288 almtx_lock(&device->BackendLock);
3289 values[0] = device->Frequency / device->UpdateSize;
3290 almtx_unlock(&device->BackendLock);
3291 return 1;
3293 case ALC_SYNC:
3294 if(device->Type == Loopback)
3296 alcSetError(device, ALC_INVALID_DEVICE);
3297 return 0;
3299 values[0] = ALC_FALSE;
3300 return 1;
3302 case ALC_FORMAT_CHANNELS_SOFT:
3303 if(device->Type != Loopback)
3305 alcSetError(device, ALC_INVALID_DEVICE);
3306 return 0;
3308 values[0] = device->FmtChans;
3309 return 1;
3311 case ALC_FORMAT_TYPE_SOFT:
3312 if(device->Type != Loopback)
3314 alcSetError(device, ALC_INVALID_DEVICE);
3315 return 0;
3317 values[0] = device->FmtType;
3318 return 1;
3320 case ALC_AMBISONIC_LAYOUT_SOFT:
3321 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3323 alcSetError(device, ALC_INVALID_DEVICE);
3324 return 0;
3326 values[0] = device->AmbiLayout;
3327 return 1;
3329 case ALC_AMBISONIC_SCALING_SOFT:
3330 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3332 alcSetError(device, ALC_INVALID_DEVICE);
3333 return 0;
3335 values[0] = device->AmbiScale;
3336 return 1;
3338 case ALC_AMBISONIC_ORDER_SOFT:
3339 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3341 alcSetError(device, ALC_INVALID_DEVICE);
3342 return 0;
3344 values[0] = device->AmbiOrder;
3345 return 1;
3347 case ALC_MONO_SOURCES:
3348 values[0] = device->NumMonoSources;
3349 return 1;
3351 case ALC_STEREO_SOURCES:
3352 values[0] = device->NumStereoSources;
3353 return 1;
3355 case ALC_MAX_AUXILIARY_SENDS:
3356 values[0] = device->NumAuxSends;
3357 return 1;
3359 case ALC_CONNECTED:
3360 values[0] = device->Connected;
3361 return 1;
3363 case ALC_HRTF_SOFT:
3364 values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3365 return 1;
3367 case ALC_HRTF_STATUS_SOFT:
3368 values[0] = device->HrtfStatus;
3369 return 1;
3371 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3372 almtx_lock(&device->BackendLock);
3373 FreeHrtfList(&device->HrtfList);
3374 device->HrtfList = EnumerateHrtf(device->DeviceName);
3375 values[0] = (ALCint)VECTOR_SIZE(device->HrtfList);
3376 almtx_unlock(&device->BackendLock);
3377 return 1;
3379 case ALC_OUTPUT_LIMITER_SOFT:
3380 values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3381 return 1;
3383 default:
3384 alcSetError(device, ALC_INVALID_ENUM);
3385 return 0;
3387 return 0;
3390 /* alcGetIntegerv
3392 * Returns information about the device and the version of OpenAL
3394 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3396 VerifyDevice(&device);
3397 if(size <= 0 || values == NULL)
3398 alcSetError(device, ALC_INVALID_VALUE);
3399 else
3400 GetIntegerv(device, param, size, values);
3401 if(device) ALCdevice_DecRef(device);
3404 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3406 ALCint *ivals;
3407 ALsizei i;
3409 VerifyDevice(&device);
3410 if(size <= 0 || values == NULL)
3411 alcSetError(device, ALC_INVALID_VALUE);
3412 else if(!device || device->Type == Capture)
3414 ivals = malloc(size * sizeof(ALCint));
3415 size = GetIntegerv(device, pname, size, ivals);
3416 for(i = 0;i < size;i++)
3417 values[i] = ivals[i];
3418 free(ivals);
3420 else /* render device */
3422 ClockLatency clock;
3423 ALuint64 basecount;
3424 ALuint samplecount;
3425 ALuint refcount;
3427 switch(pname)
3429 case ALC_ATTRIBUTES_SIZE:
3430 *values = NumAttrsForDevice(device)+4;
3431 break;
3433 case ALC_ALL_ATTRIBUTES:
3434 if(size < NumAttrsForDevice(device)+4)
3435 alcSetError(device, ALC_INVALID_VALUE);
3436 else
3438 i = 0;
3439 almtx_lock(&device->BackendLock);
3440 values[i++] = ALC_FREQUENCY;
3441 values[i++] = device->Frequency;
3443 if(device->Type != Loopback)
3445 values[i++] = ALC_REFRESH;
3446 values[i++] = device->Frequency / device->UpdateSize;
3448 values[i++] = ALC_SYNC;
3449 values[i++] = ALC_FALSE;
3451 else
3453 if(device->FmtChans == DevFmtAmbi3D)
3455 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3456 values[i++] = device->AmbiLayout;
3458 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3459 values[i++] = device->AmbiScale;
3461 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3462 values[i++] = device->AmbiOrder;
3465 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3466 values[i++] = device->FmtChans;
3468 values[i++] = ALC_FORMAT_TYPE_SOFT;
3469 values[i++] = device->FmtType;
3472 values[i++] = ALC_MONO_SOURCES;
3473 values[i++] = device->NumMonoSources;
3475 values[i++] = ALC_STEREO_SOURCES;
3476 values[i++] = device->NumStereoSources;
3478 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3479 values[i++] = device->NumAuxSends;
3481 values[i++] = ALC_HRTF_SOFT;
3482 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3484 values[i++] = ALC_HRTF_STATUS_SOFT;
3485 values[i++] = device->HrtfStatus;
3487 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3488 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3490 clock = V0(device->Backend,getClockLatency)();
3491 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3492 values[i++] = clock.ClockTime;
3494 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3495 values[i++] = clock.Latency;
3496 almtx_unlock(&device->BackendLock);
3498 values[i++] = 0;
3500 break;
3502 case ALC_DEVICE_CLOCK_SOFT:
3503 almtx_lock(&device->BackendLock);
3504 do {
3505 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3506 althrd_yield();
3507 basecount = device->ClockBase;
3508 samplecount = device->SamplesDone;
3509 } while(refcount != ReadRef(&device->MixCount));
3510 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3511 almtx_unlock(&device->BackendLock);
3512 break;
3514 case ALC_DEVICE_LATENCY_SOFT:
3515 almtx_lock(&device->BackendLock);
3516 clock = V0(device->Backend,getClockLatency)();
3517 almtx_unlock(&device->BackendLock);
3518 *values = clock.Latency;
3519 break;
3521 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3522 if(size < 2)
3523 alcSetError(device, ALC_INVALID_VALUE);
3524 else
3526 almtx_lock(&device->BackendLock);
3527 clock = V0(device->Backend,getClockLatency)();
3528 almtx_unlock(&device->BackendLock);
3529 values[0] = clock.ClockTime;
3530 values[1] = clock.Latency;
3532 break;
3534 default:
3535 ivals = malloc(size * sizeof(ALCint));
3536 size = GetIntegerv(device, pname, size, ivals);
3537 for(i = 0;i < size;i++)
3538 values[i] = ivals[i];
3539 free(ivals);
3540 break;
3543 if(device)
3544 ALCdevice_DecRef(device);
3548 /* alcIsExtensionPresent
3550 * Determines if there is support for a particular extension
3552 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3554 ALCboolean bResult = ALC_FALSE;
3556 VerifyDevice(&device);
3558 if(!extName)
3559 alcSetError(device, ALC_INVALID_VALUE);
3560 else
3562 size_t len = strlen(extName);
3563 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3564 while(ptr && *ptr)
3566 if(strncasecmp(ptr, extName, len) == 0 &&
3567 (ptr[len] == '\0' || isspace(ptr[len])))
3569 bResult = ALC_TRUE;
3570 break;
3572 if((ptr=strchr(ptr, ' ')) != NULL)
3574 do {
3575 ++ptr;
3576 } while(isspace(*ptr));
3580 if(device)
3581 ALCdevice_DecRef(device);
3582 return bResult;
3586 /* alcGetProcAddress
3588 * Retrieves the function address for a particular extension function
3590 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3592 ALCvoid *ptr = NULL;
3594 if(!funcName)
3596 VerifyDevice(&device);
3597 alcSetError(device, ALC_INVALID_VALUE);
3598 if(device) ALCdevice_DecRef(device);
3600 else
3602 size_t i = 0;
3603 for(i = 0;i < COUNTOF(alcFunctions);i++)
3605 if(strcmp(alcFunctions[i].funcName, funcName) == 0)
3607 ptr = alcFunctions[i].address;
3608 break;
3613 return ptr;
3617 /* alcGetEnumValue
3619 * Get the value for a particular ALC enumeration name
3621 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3623 ALCenum val = 0;
3625 if(!enumName)
3627 VerifyDevice(&device);
3628 alcSetError(device, ALC_INVALID_VALUE);
3629 if(device) ALCdevice_DecRef(device);
3631 else
3633 size_t i = 0;
3634 for(i = 0;i < COUNTOF(alcEnumerations);i++)
3636 if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
3638 val = alcEnumerations[i].value;
3639 break;
3644 return val;
3648 /* alcCreateContext
3650 * Create and attach a context to the given device.
3652 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3654 ALCcontext *ALContext;
3655 ALfloat valf;
3656 ALCenum err;
3658 /* Explicitly hold the list lock while taking the BackendLock in case the
3659 * device is asynchronously destropyed, to ensure this new context is
3660 * properly cleaned up after being made.
3662 LockLists();
3663 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3665 UnlockLists();
3666 alcSetError(device, ALC_INVALID_DEVICE);
3667 if(device) ALCdevice_DecRef(device);
3668 return NULL;
3670 almtx_lock(&device->BackendLock);
3671 UnlockLists();
3673 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3675 if(device->Type == Playback && DefaultEffect.type != AL_EFFECT_NULL)
3676 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener)+sizeof(ALeffectslot));
3677 else
3678 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3679 if(!ALContext)
3681 almtx_unlock(&device->BackendLock);
3683 alcSetError(device, ALC_OUT_OF_MEMORY);
3684 ALCdevice_DecRef(device);
3685 return NULL;
3688 InitRef(&ALContext->ref, 1);
3689 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3690 ALContext->DefaultSlot = NULL;
3692 ALContext->Voices = NULL;
3693 ALContext->VoiceCount = 0;
3694 ALContext->MaxVoices = 0;
3695 ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL);
3696 ALContext->Device = device;
3698 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3700 almtx_unlock(&device->BackendLock);
3702 al_free(ALContext);
3703 ALContext = NULL;
3705 alcSetError(device, err);
3706 if(err == ALC_INVALID_DEVICE)
3708 V0(device->Backend,lock)();
3709 aluHandleDisconnect(device);
3710 V0(device->Backend,unlock)();
3712 ALCdevice_DecRef(device);
3713 return NULL;
3715 AllocateVoices(ALContext, 256, device->NumAuxSends);
3717 if(DefaultEffect.type != AL_EFFECT_NULL && device->Type == Playback)
3719 ALContext->DefaultSlot = (ALeffectslot*)(ALContext->_listener_mem + sizeof(ALlistener));
3720 if(InitEffectSlot(ALContext->DefaultSlot) == AL_NO_ERROR)
3721 aluInitEffectPanning(ALContext->DefaultSlot);
3722 else
3724 ALContext->DefaultSlot = NULL;
3725 ERR("Failed to initialize the default effect slot\n");
3729 ALCdevice_IncRef(ALContext->Device);
3730 InitContext(ALContext);
3732 if(ConfigValueFloat(alstr_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3734 if(!isfinite(valf))
3735 ERR("volume-adjust must be finite: %f\n", valf);
3736 else
3738 ALfloat db = clampf(valf, -24.0f, 24.0f);
3739 if(db != valf)
3740 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3741 ALContext->GainBoost = powf(10.0f, db/20.0f);
3742 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3745 UpdateListenerProps(ALContext);
3748 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3749 do {
3750 ALContext->next = head;
3751 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
3752 ALContext) == 0);
3754 almtx_unlock(&device->BackendLock);
3756 if(ALContext->DefaultSlot)
3758 if(InitializeEffect(ALContext, ALContext->DefaultSlot, &DefaultEffect) == AL_NO_ERROR)
3759 UpdateEffectSlotProps(ALContext->DefaultSlot, ALContext);
3760 else
3761 ERR("Failed to initialize the default effect\n");
3764 ALCdevice_DecRef(device);
3766 TRACE("Created context %p\n", ALContext);
3767 return ALContext;
3770 /* alcDestroyContext
3772 * Remove a context from its device
3774 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3776 ALCdevice *Device;
3778 LockLists();
3779 if(!VerifyContext(&context))
3781 UnlockLists();
3782 alcSetError(NULL, ALC_INVALID_CONTEXT);
3783 return;
3786 Device = context->Device;
3787 if(Device)
3789 almtx_lock(&Device->BackendLock);
3790 if(!ReleaseContext(context, Device))
3792 V0(Device->Backend,stop)();
3793 Device->Flags &= ~DEVICE_RUNNING;
3795 almtx_unlock(&Device->BackendLock);
3797 UnlockLists();
3799 ALCcontext_DecRef(context);
3803 /* alcGetCurrentContext
3805 * Returns the currently active context on the calling thread
3807 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3809 ALCcontext *Context = altss_get(LocalContext);
3810 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3811 return Context;
3814 /* alcGetThreadContext
3816 * Returns the currently active thread-local context
3818 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3820 return altss_get(LocalContext);
3824 /* alcMakeContextCurrent
3826 * Makes the given context the active process-wide context, and removes the
3827 * thread-local context for the calling thread.
3829 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3831 /* context must be valid or NULL */
3832 if(context && !VerifyContext(&context))
3834 alcSetError(NULL, ALC_INVALID_CONTEXT);
3835 return ALC_FALSE;
3837 /* context's reference count is already incremented */
3838 context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
3839 if(context) ALCcontext_DecRef(context);
3841 if((context=altss_get(LocalContext)) != NULL)
3843 altss_set(LocalContext, NULL);
3844 ALCcontext_DecRef(context);
3847 return ALC_TRUE;
3850 /* alcSetThreadContext
3852 * Makes the given context the active context for the current thread
3854 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3856 ALCcontext *old;
3858 /* context must be valid or NULL */
3859 if(context && !VerifyContext(&context))
3861 alcSetError(NULL, ALC_INVALID_CONTEXT);
3862 return ALC_FALSE;
3864 /* context's reference count is already incremented */
3865 old = altss_get(LocalContext);
3866 altss_set(LocalContext, context);
3867 if(old) ALCcontext_DecRef(old);
3869 return ALC_TRUE;
3873 /* alcGetContextsDevice
3875 * Returns the device that a particular context is attached to
3877 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3879 ALCdevice *Device;
3881 if(!VerifyContext(&Context))
3883 alcSetError(NULL, ALC_INVALID_CONTEXT);
3884 return NULL;
3886 Device = Context->Device;
3887 ALCcontext_DecRef(Context);
3889 return Device;
3893 /* alcOpenDevice
3895 * Opens the named device.
3897 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3899 ALCbackendFactory *factory;
3900 const ALCchar *fmt;
3901 ALCdevice *device;
3902 ALCenum err;
3903 ALCsizei i;
3905 DO_INITCONFIG();
3907 if(!PlaybackBackend.name)
3909 alcSetError(NULL, ALC_INVALID_VALUE);
3910 return NULL;
3913 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3914 #ifdef _WIN32
3915 /* Some old Windows apps hardcode these expecting OpenAL to use a
3916 * specific audio API, even when they're not enumerated. Creative's
3917 * router effectively ignores them too.
3919 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3920 || strcasecmp(deviceName, "MMSYSTEM") == 0
3921 #endif
3923 deviceName = NULL;
3925 device = al_calloc(16, sizeof(ALCdevice));
3926 if(!device)
3928 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3929 return NULL;
3932 //Validate device
3933 InitRef(&device->ref, 1);
3934 device->Connected = ALC_TRUE;
3935 device->Type = Playback;
3936 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3938 device->Flags = 0;
3939 device->Bs2b = NULL;
3940 device->Uhj_Encoder = NULL;
3941 device->Hrtf = NULL;
3942 device->HrtfHandle = NULL;
3943 VECTOR_INIT(device->HrtfList);
3944 AL_STRING_INIT(device->HrtfName);
3945 device->Render_Mode = NormalRender;
3946 AL_STRING_INIT(device->DeviceName);
3947 device->Dry.Buffer = NULL;
3948 device->Dry.NumChannels = 0;
3949 device->FOAOut.Buffer = NULL;
3950 device->FOAOut.NumChannels = 0;
3951 device->RealOut.Buffer = NULL;
3952 device->RealOut.NumChannels = 0;
3953 device->Limiter = NULL;
3954 device->AvgSpeakerDist = 0.0f;
3956 ATOMIC_INIT(&device->ContextList, NULL);
3958 device->ClockBase = 0;
3959 device->SamplesDone = 0;
3961 device->SourcesMax = 256;
3962 device->AuxiliaryEffectSlotMax = 64;
3963 device->NumAuxSends = DEFAULT_SENDS;
3965 InitUIntMap(&device->BufferMap, INT_MAX);
3966 InitUIntMap(&device->EffectMap, INT_MAX);
3967 InitUIntMap(&device->FilterMap, INT_MAX);
3969 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3971 device->ChannelDelay[i].Gain = 1.0f;
3972 device->ChannelDelay[i].Length = 0;
3973 device->ChannelDelay[i].Buffer = NULL;
3976 //Set output format
3977 device->FmtChans = DevFmtChannelsDefault;
3978 device->FmtType = DevFmtTypeDefault;
3979 device->Frequency = DEFAULT_OUTPUT_RATE;
3980 device->IsHeadphones = AL_FALSE;
3981 device->AmbiLayout = AmbiLayout_Default;
3982 device->AmbiScale = AmbiNorm_Default;
3983 device->NumUpdates = 3;
3984 device->UpdateSize = 1024;
3986 factory = PlaybackBackend.getFactory();
3987 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3988 if(!device->Backend)
3990 al_free(device);
3991 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3992 return NULL;
3996 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3998 static const struct {
3999 const char name[16];
4000 enum DevFmtChannels chans;
4001 ALsizei order;
4002 } chanlist[] = {
4003 { "mono", DevFmtMono, 0 },
4004 { "stereo", DevFmtStereo, 0 },
4005 { "quad", DevFmtQuad, 0 },
4006 { "surround51", DevFmtX51, 0 },
4007 { "surround61", DevFmtX61, 0 },
4008 { "surround71", DevFmtX71, 0 },
4009 { "surround51rear", DevFmtX51Rear, 0 },
4010 { "ambi1", DevFmtAmbi3D, 1 },
4011 { "ambi2", DevFmtAmbi3D, 2 },
4012 { "ambi3", DevFmtAmbi3D, 3 },
4014 size_t i;
4016 for(i = 0;i < COUNTOF(chanlist);i++)
4018 if(strcasecmp(chanlist[i].name, fmt) == 0)
4020 device->FmtChans = chanlist[i].chans;
4021 device->AmbiOrder = chanlist[i].order;
4022 device->Flags |= DEVICE_CHANNELS_REQUEST;
4023 break;
4026 if(i == COUNTOF(chanlist))
4027 ERR("Unsupported channels: %s\n", fmt);
4029 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
4031 static const struct {
4032 const char name[16];
4033 enum DevFmtType type;
4034 } typelist[] = {
4035 { "int8", DevFmtByte },
4036 { "uint8", DevFmtUByte },
4037 { "int16", DevFmtShort },
4038 { "uint16", DevFmtUShort },
4039 { "int32", DevFmtInt },
4040 { "uint32", DevFmtUInt },
4041 { "float32", DevFmtFloat },
4043 size_t i;
4045 for(i = 0;i < COUNTOF(typelist);i++)
4047 if(strcasecmp(typelist[i].name, fmt) == 0)
4049 device->FmtType = typelist[i].type;
4050 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
4051 break;
4054 if(i == COUNTOF(typelist))
4055 ERR("Unsupported sample-type: %s\n", fmt);
4058 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
4060 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4061 if(device->Frequency < MIN_OUTPUT_RATE)
4062 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
4063 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
4066 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
4067 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
4069 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
4070 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
4071 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
4072 device->UpdateSize = (device->UpdateSize+3)&~3;
4074 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
4075 if(device->SourcesMax == 0) device->SourcesMax = 256;
4077 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4078 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4080 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
4081 device->NumAuxSends = clampi(
4082 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4085 device->NumStereoSources = 1;
4086 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4088 // Find a playback device to open
4089 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4091 DELETE_OBJ(device->Backend);
4092 al_free(device);
4093 alcSetError(NULL, err);
4094 return NULL;
4096 almtx_init(&device->BackendLock, almtx_plain);
4098 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
4100 if(strcasecmp(fmt, "fuma") == 0)
4102 device->AmbiLayout = AmbiLayout_FuMa;
4103 device->AmbiScale = AmbiNorm_FuMa;
4105 else if(strcasecmp(fmt, "acn+sn3d") == 0)
4107 device->AmbiLayout = AmbiLayout_ACN;
4108 device->AmbiScale = AmbiNorm_SN3D;
4110 else if(strcasecmp(fmt, "acn+n3d") == 0)
4112 device->AmbiLayout = AmbiLayout_ACN;
4113 device->AmbiScale = AmbiNorm_N3D;
4115 else
4116 ERR("Unsupported ambi-format: %s\n", fmt);
4119 device->Limiter = CreateDeviceLimiter(device);
4122 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4123 do {
4124 device->next = head;
4125 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4128 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4129 return device;
4132 /* alcCloseDevice
4134 * Closes the given device.
4136 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
4138 ALCdevice *iter, *origdev;
4139 ALCcontext *ctx;
4141 LockLists();
4142 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4143 do {
4144 if(iter == device)
4145 break;
4146 } while((iter=iter->next) != NULL);
4147 if(!iter || iter->Type == Capture)
4149 alcSetError(iter, ALC_INVALID_DEVICE);
4150 UnlockLists();
4151 return ALC_FALSE;
4153 almtx_lock(&device->BackendLock);
4155 origdev = device;
4156 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4158 ALCdevice *volatile*list = &origdev->next;
4159 while(*list)
4161 if(*list == device)
4163 *list = (*list)->next;
4164 break;
4166 list = &(*list)->next;
4169 UnlockLists();
4171 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
4172 while(ctx != NULL)
4174 ALCcontext *next = ctx->next;
4175 WARN("Releasing context %p\n", ctx);
4176 ReleaseContext(ctx, device);
4177 ctx = next;
4179 if((device->Flags&DEVICE_RUNNING))
4180 V0(device->Backend,stop)();
4181 device->Flags &= ~DEVICE_RUNNING;
4182 almtx_unlock(&device->BackendLock);
4184 ALCdevice_DecRef(device);
4186 return ALC_TRUE;
4190 /************************************************
4191 * ALC capture functions
4192 ************************************************/
4193 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4195 ALCbackendFactory *factory;
4196 ALCdevice *device = NULL;
4197 ALCenum err;
4198 ALCsizei i;
4200 DO_INITCONFIG();
4202 if(!CaptureBackend.name)
4204 alcSetError(NULL, ALC_INVALID_VALUE);
4205 return NULL;
4208 if(samples <= 0)
4210 alcSetError(NULL, ALC_INVALID_VALUE);
4211 return NULL;
4214 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4215 deviceName = NULL;
4217 device = al_calloc(16, sizeof(ALCdevice));
4218 if(!device)
4220 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4221 return NULL;
4224 //Validate device
4225 InitRef(&device->ref, 1);
4226 device->Connected = ALC_TRUE;
4227 device->Type = Capture;
4229 device->Hrtf = NULL;
4230 device->HrtfHandle = NULL;
4231 VECTOR_INIT(device->HrtfList);
4232 AL_STRING_INIT(device->HrtfName);
4234 AL_STRING_INIT(device->DeviceName);
4235 device->Dry.Buffer = NULL;
4236 device->Dry.NumChannels = 0;
4237 device->FOAOut.Buffer = NULL;
4238 device->FOAOut.NumChannels = 0;
4239 device->RealOut.Buffer = NULL;
4240 device->RealOut.NumChannels = 0;
4242 InitUIntMap(&device->BufferMap, INT_MAX);
4243 InitUIntMap(&device->EffectMap, INT_MAX);
4244 InitUIntMap(&device->FilterMap, INT_MAX);
4246 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4248 device->ChannelDelay[i].Gain = 1.0f;
4249 device->ChannelDelay[i].Length = 0;
4250 device->ChannelDelay[i].Buffer = NULL;
4253 factory = CaptureBackend.getFactory();
4254 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4255 if(!device->Backend)
4257 al_free(device);
4258 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4259 return NULL;
4262 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4263 device->Frequency = frequency;
4265 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4266 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4268 al_free(device);
4269 alcSetError(NULL, ALC_INVALID_ENUM);
4270 return NULL;
4272 device->IsHeadphones = AL_FALSE;
4273 device->AmbiOrder = 0;
4274 device->AmbiLayout = AmbiLayout_Default;
4275 device->AmbiScale = AmbiNorm_Default;
4277 device->UpdateSize = samples;
4278 device->NumUpdates = 1;
4280 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4281 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
4282 device->Frequency, device->UpdateSize, device->NumUpdates
4284 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4286 al_free(device);
4287 alcSetError(NULL, err);
4288 return NULL;
4290 almtx_init(&device->BackendLock, almtx_plain);
4293 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4294 do {
4295 device->next = head;
4296 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4299 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4300 return device;
4303 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4305 ALCdevice *iter, *origdev;
4307 LockLists();
4308 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4309 do {
4310 if(iter == device)
4311 break;
4312 } while((iter=iter->next) != NULL);
4313 if(!iter || iter->Type != Capture)
4315 alcSetError(iter, ALC_INVALID_DEVICE);
4316 UnlockLists();
4317 return ALC_FALSE;
4320 origdev = device;
4321 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4323 ALCdevice *volatile*list = &origdev->next;
4324 while(*list)
4326 if(*list == device)
4328 *list = (*list)->next;
4329 break;
4331 list = &(*list)->next;
4334 UnlockLists();
4336 ALCdevice_DecRef(device);
4338 return ALC_TRUE;
4341 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4343 if(!VerifyDevice(&device) || device->Type != Capture)
4344 alcSetError(device, ALC_INVALID_DEVICE);
4345 else
4347 almtx_lock(&device->BackendLock);
4348 if(!device->Connected)
4349 alcSetError(device, ALC_INVALID_DEVICE);
4350 else if(!(device->Flags&DEVICE_RUNNING))
4352 if(V0(device->Backend,start)())
4353 device->Flags |= DEVICE_RUNNING;
4354 else
4356 aluHandleDisconnect(device);
4357 alcSetError(device, ALC_INVALID_DEVICE);
4360 almtx_unlock(&device->BackendLock);
4363 if(device) ALCdevice_DecRef(device);
4366 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4368 if(!VerifyDevice(&device) || device->Type != Capture)
4369 alcSetError(device, ALC_INVALID_DEVICE);
4370 else
4372 almtx_lock(&device->BackendLock);
4373 if((device->Flags&DEVICE_RUNNING))
4374 V0(device->Backend,stop)();
4375 device->Flags &= ~DEVICE_RUNNING;
4376 almtx_unlock(&device->BackendLock);
4379 if(device) ALCdevice_DecRef(device);
4382 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4384 if(!VerifyDevice(&device) || device->Type != Capture)
4385 alcSetError(device, ALC_INVALID_DEVICE);
4386 else
4388 ALCenum err = ALC_INVALID_VALUE;
4390 almtx_lock(&device->BackendLock);
4391 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4392 err = V(device->Backend,captureSamples)(buffer, samples);
4393 almtx_unlock(&device->BackendLock);
4395 if(err != ALC_NO_ERROR)
4396 alcSetError(device, err);
4398 if(device) ALCdevice_DecRef(device);
4402 /************************************************
4403 * ALC loopback functions
4404 ************************************************/
4406 /* alcLoopbackOpenDeviceSOFT
4408 * Open a loopback device, for manual rendering.
4410 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4412 ALCbackendFactory *factory;
4413 ALCdevice *device;
4414 ALCsizei i;
4416 DO_INITCONFIG();
4418 /* Make sure the device name, if specified, is us. */
4419 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4421 alcSetError(NULL, ALC_INVALID_VALUE);
4422 return NULL;
4425 device = al_calloc(16, sizeof(ALCdevice));
4426 if(!device)
4428 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4429 return NULL;
4432 //Validate device
4433 InitRef(&device->ref, 1);
4434 device->Connected = ALC_TRUE;
4435 device->Type = Loopback;
4436 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4438 device->Flags = 0;
4439 device->Hrtf = NULL;
4440 device->HrtfHandle = NULL;
4441 VECTOR_INIT(device->HrtfList);
4442 AL_STRING_INIT(device->HrtfName);
4443 device->Bs2b = NULL;
4444 device->Uhj_Encoder = NULL;
4445 device->Render_Mode = NormalRender;
4446 AL_STRING_INIT(device->DeviceName);
4447 device->Dry.Buffer = NULL;
4448 device->Dry.NumChannels = 0;
4449 device->FOAOut.Buffer = NULL;
4450 device->FOAOut.NumChannels = 0;
4451 device->RealOut.Buffer = NULL;
4452 device->RealOut.NumChannels = 0;
4453 device->Limiter = NULL;
4454 device->AvgSpeakerDist = 0.0f;
4456 ATOMIC_INIT(&device->ContextList, NULL);
4458 device->ClockBase = 0;
4459 device->SamplesDone = 0;
4461 device->SourcesMax = 256;
4462 device->AuxiliaryEffectSlotMax = 64;
4463 device->NumAuxSends = DEFAULT_SENDS;
4465 InitUIntMap(&device->BufferMap, INT_MAX);
4466 InitUIntMap(&device->EffectMap, INT_MAX);
4467 InitUIntMap(&device->FilterMap, INT_MAX);
4469 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4471 device->ChannelDelay[i].Gain = 1.0f;
4472 device->ChannelDelay[i].Length = 0;
4473 device->ChannelDelay[i].Buffer = NULL;
4476 factory = ALCloopbackFactory_getFactory();
4477 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4478 if(!device->Backend)
4480 al_free(device);
4481 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4482 return NULL;
4484 almtx_init(&device->BackendLock, almtx_plain);
4486 //Set output format
4487 device->NumUpdates = 0;
4488 device->UpdateSize = 0;
4490 device->Frequency = DEFAULT_OUTPUT_RATE;
4491 device->FmtChans = DevFmtChannelsDefault;
4492 device->FmtType = DevFmtTypeDefault;
4493 device->IsHeadphones = AL_FALSE;
4494 device->AmbiLayout = AmbiLayout_Default;
4495 device->AmbiScale = AmbiNorm_Default;
4497 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4498 if(device->SourcesMax == 0) device->SourcesMax = 256;
4500 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4501 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4503 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4504 device->NumAuxSends = clampi(
4505 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4508 device->NumStereoSources = 1;
4509 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4511 // Open the "backend"
4512 V(device->Backend,open)("Loopback");
4514 device->Limiter = CreateDeviceLimiter(device);
4517 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4518 do {
4519 device->next = head;
4520 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4523 TRACE("Created device %p\n", device);
4524 return device;
4527 /* alcIsRenderFormatSupportedSOFT
4529 * Determines if the loopback device supports the given format for rendering.
4531 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4533 ALCboolean ret = ALC_FALSE;
4535 if(!VerifyDevice(&device) || device->Type != Loopback)
4536 alcSetError(device, ALC_INVALID_DEVICE);
4537 else if(freq <= 0)
4538 alcSetError(device, ALC_INVALID_VALUE);
4539 else
4541 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4542 ret = ALC_TRUE;
4544 if(device) ALCdevice_DecRef(device);
4546 return ret;
4549 /* alcRenderSamplesSOFT
4551 * Renders some samples into a buffer, using the format last set by the
4552 * attributes given to alcCreateContext.
4554 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4556 if(!VerifyDevice(&device) || device->Type != Loopback)
4557 alcSetError(device, ALC_INVALID_DEVICE);
4558 else if(samples < 0 || (samples > 0 && buffer == NULL))
4559 alcSetError(device, ALC_INVALID_VALUE);
4560 else
4562 V0(device->Backend,lock)();
4563 aluMixData(device, buffer, samples);
4564 V0(device->Backend,unlock)();
4566 if(device) ALCdevice_DecRef(device);
4570 /************************************************
4571 * ALC DSP pause/resume functions
4572 ************************************************/
4574 /* alcDevicePauseSOFT
4576 * Pause the DSP to stop audio processing.
4578 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4580 if(!VerifyDevice(&device) || device->Type != Playback)
4581 alcSetError(device, ALC_INVALID_DEVICE);
4582 else
4584 almtx_lock(&device->BackendLock);
4585 if((device->Flags&DEVICE_RUNNING))
4586 V0(device->Backend,stop)();
4587 device->Flags &= ~DEVICE_RUNNING;
4588 device->Flags |= DEVICE_PAUSED;
4589 almtx_unlock(&device->BackendLock);
4591 if(device) ALCdevice_DecRef(device);
4594 /* alcDeviceResumeSOFT
4596 * Resume the DSP to restart audio processing.
4598 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4600 if(!VerifyDevice(&device) || device->Type != Playback)
4601 alcSetError(device, ALC_INVALID_DEVICE);
4602 else
4604 almtx_lock(&device->BackendLock);
4605 if((device->Flags&DEVICE_PAUSED))
4607 device->Flags &= ~DEVICE_PAUSED;
4608 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4610 if(V0(device->Backend,start)() != ALC_FALSE)
4611 device->Flags |= DEVICE_RUNNING;
4612 else
4614 alcSetError(device, ALC_INVALID_DEVICE);
4615 V0(device->Backend,lock)();
4616 aluHandleDisconnect(device);
4617 V0(device->Backend,unlock)();
4621 almtx_unlock(&device->BackendLock);
4623 if(device) ALCdevice_DecRef(device);
4627 /************************************************
4628 * ALC HRTF functions
4629 ************************************************/
4631 /* alcGetStringiSOFT
4633 * Gets a string parameter at the given index.
4635 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4637 const ALCchar *str = NULL;
4639 if(!VerifyDevice(&device) || device->Type == Capture)
4640 alcSetError(device, ALC_INVALID_DEVICE);
4641 else switch(paramName)
4643 case ALC_HRTF_SPECIFIER_SOFT:
4644 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList))
4645 str = alstr_get_cstr(VECTOR_ELEM(device->HrtfList, index).name);
4646 else
4647 alcSetError(device, ALC_INVALID_VALUE);
4648 break;
4650 default:
4651 alcSetError(device, ALC_INVALID_ENUM);
4652 break;
4654 if(device) ALCdevice_DecRef(device);
4656 return str;
4659 /* alcResetDeviceSOFT
4661 * Resets the given device output, using the specified attribute list.
4663 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4665 ALCenum err;
4667 LockLists();
4668 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4670 UnlockLists();
4671 alcSetError(device, ALC_INVALID_DEVICE);
4672 if(device) ALCdevice_DecRef(device);
4673 return ALC_FALSE;
4675 almtx_lock(&device->BackendLock);
4676 UnlockLists();
4678 err = UpdateDeviceParams(device, attribs);
4679 almtx_unlock(&device->BackendLock);
4681 if(err != ALC_NO_ERROR)
4683 alcSetError(device, err);
4684 if(err == ALC_INVALID_DEVICE)
4686 V0(device->Backend,lock)();
4687 aluHandleDisconnect(device);
4688 V0(device->Backend,unlock)();
4690 ALCdevice_DecRef(device);
4691 return ALC_FALSE;
4693 ALCdevice_DecRef(device);
4695 return ALC_TRUE;