Implement opening and closing devices in the router
[openal-soft.git] / Alc / ALc.c
blob6d5454f5252b42e60e994d2a8891ce275423dd43
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include "version.h"
25 #include <math.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <memory.h>
29 #include <ctype.h>
30 #include <signal.h>
32 #include "alMain.h"
33 #include "alSource.h"
34 #include "alListener.h"
35 #include "alThunk.h"
36 #include "alSource.h"
37 #include "alBuffer.h"
38 #include "alAuxEffectSlot.h"
39 #include "alError.h"
40 #include "bformatdec.h"
41 #include "alu.h"
43 #include "compat.h"
44 #include "threads.h"
45 #include "alstring.h"
46 #include "almalloc.h"
48 #include "backends/base.h"
51 /************************************************
52 * Backends
53 ************************************************/
54 struct BackendInfo {
55 const char *name;
56 ALCbackendFactory* (*getFactory)(void);
59 static struct BackendInfo BackendList[] = {
60 #ifdef HAVE_JACK
61 { "jack", ALCjackBackendFactory_getFactory },
62 #endif
63 #ifdef HAVE_PULSEAUDIO
64 { "pulse", ALCpulseBackendFactory_getFactory },
65 #endif
66 #ifdef HAVE_ALSA
67 { "alsa", ALCalsaBackendFactory_getFactory },
68 #endif
69 #ifdef HAVE_COREAUDIO
70 { "core", ALCcoreAudioBackendFactory_getFactory },
71 #endif
72 #ifdef HAVE_OSS
73 { "oss", ALCossBackendFactory_getFactory },
74 #endif
75 #ifdef HAVE_SOLARIS
76 { "solaris", ALCsolarisBackendFactory_getFactory },
77 #endif
78 #ifdef HAVE_SNDIO
79 { "sndio", ALCsndioBackendFactory_getFactory },
80 #endif
81 #ifdef HAVE_QSA
82 { "qsa", ALCqsaBackendFactory_getFactory },
83 #endif
84 #ifdef HAVE_MMDEVAPI
85 { "mmdevapi", ALCmmdevBackendFactory_getFactory },
86 #endif
87 #ifdef HAVE_DSOUND
88 { "dsound", ALCdsoundBackendFactory_getFactory },
89 #endif
90 #ifdef HAVE_WINMM
91 { "winmm", ALCwinmmBackendFactory_getFactory },
92 #endif
93 #ifdef HAVE_PORTAUDIO
94 { "port", ALCportBackendFactory_getFactory },
95 #endif
96 #ifdef HAVE_OPENSL
97 { "opensl", ALCopenslBackendFactory_getFactory },
98 #endif
100 { "null", ALCnullBackendFactory_getFactory },
101 #ifdef HAVE_WAVE
102 { "wave", ALCwaveBackendFactory_getFactory },
103 #endif
105 static ALsizei BackendListSize = COUNTOF(BackendList);
106 #undef EmptyFuncs
108 static struct BackendInfo PlaybackBackend;
109 static struct BackendInfo CaptureBackend;
112 /************************************************
113 * Functions, enums, and errors
114 ************************************************/
115 #define DECL(x) { #x, (ALCvoid*)(x) }
116 static const struct {
117 const ALCchar *funcName;
118 ALCvoid *address;
119 } alcFunctions[] = {
120 DECL(alcCreateContext),
121 DECL(alcMakeContextCurrent),
122 DECL(alcProcessContext),
123 DECL(alcSuspendContext),
124 DECL(alcDestroyContext),
125 DECL(alcGetCurrentContext),
126 DECL(alcGetContextsDevice),
127 DECL(alcOpenDevice),
128 DECL(alcCloseDevice),
129 DECL(alcGetError),
130 DECL(alcIsExtensionPresent),
131 DECL(alcGetProcAddress),
132 DECL(alcGetEnumValue),
133 DECL(alcGetString),
134 DECL(alcGetIntegerv),
135 DECL(alcCaptureOpenDevice),
136 DECL(alcCaptureCloseDevice),
137 DECL(alcCaptureStart),
138 DECL(alcCaptureStop),
139 DECL(alcCaptureSamples),
141 DECL(alcSetThreadContext),
142 DECL(alcGetThreadContext),
144 DECL(alcLoopbackOpenDeviceSOFT),
145 DECL(alcIsRenderFormatSupportedSOFT),
146 DECL(alcRenderSamplesSOFT),
148 DECL(alcIsAmbisonicFormatSupportedSOFT),
150 DECL(alcDevicePauseSOFT),
151 DECL(alcDeviceResumeSOFT),
153 DECL(alcGetStringiSOFT),
154 DECL(alcResetDeviceSOFT),
156 DECL(alcGetInteger64vSOFT),
158 DECL(alEnable),
159 DECL(alDisable),
160 DECL(alIsEnabled),
161 DECL(alGetString),
162 DECL(alGetBooleanv),
163 DECL(alGetIntegerv),
164 DECL(alGetFloatv),
165 DECL(alGetDoublev),
166 DECL(alGetBoolean),
167 DECL(alGetInteger),
168 DECL(alGetFloat),
169 DECL(alGetDouble),
170 DECL(alGetError),
171 DECL(alIsExtensionPresent),
172 DECL(alGetProcAddress),
173 DECL(alGetEnumValue),
174 DECL(alListenerf),
175 DECL(alListener3f),
176 DECL(alListenerfv),
177 DECL(alListeneri),
178 DECL(alListener3i),
179 DECL(alListeneriv),
180 DECL(alGetListenerf),
181 DECL(alGetListener3f),
182 DECL(alGetListenerfv),
183 DECL(alGetListeneri),
184 DECL(alGetListener3i),
185 DECL(alGetListeneriv),
186 DECL(alGenSources),
187 DECL(alDeleteSources),
188 DECL(alIsSource),
189 DECL(alSourcef),
190 DECL(alSource3f),
191 DECL(alSourcefv),
192 DECL(alSourcei),
193 DECL(alSource3i),
194 DECL(alSourceiv),
195 DECL(alGetSourcef),
196 DECL(alGetSource3f),
197 DECL(alGetSourcefv),
198 DECL(alGetSourcei),
199 DECL(alGetSource3i),
200 DECL(alGetSourceiv),
201 DECL(alSourcePlayv),
202 DECL(alSourceStopv),
203 DECL(alSourceRewindv),
204 DECL(alSourcePausev),
205 DECL(alSourcePlay),
206 DECL(alSourceStop),
207 DECL(alSourceRewind),
208 DECL(alSourcePause),
209 DECL(alSourceQueueBuffers),
210 DECL(alSourceUnqueueBuffers),
211 DECL(alGenBuffers),
212 DECL(alDeleteBuffers),
213 DECL(alIsBuffer),
214 DECL(alBufferData),
215 DECL(alBufferf),
216 DECL(alBuffer3f),
217 DECL(alBufferfv),
218 DECL(alBufferi),
219 DECL(alBuffer3i),
220 DECL(alBufferiv),
221 DECL(alGetBufferf),
222 DECL(alGetBuffer3f),
223 DECL(alGetBufferfv),
224 DECL(alGetBufferi),
225 DECL(alGetBuffer3i),
226 DECL(alGetBufferiv),
227 DECL(alDopplerFactor),
228 DECL(alDopplerVelocity),
229 DECL(alSpeedOfSound),
230 DECL(alDistanceModel),
232 DECL(alGenFilters),
233 DECL(alDeleteFilters),
234 DECL(alIsFilter),
235 DECL(alFilteri),
236 DECL(alFilteriv),
237 DECL(alFilterf),
238 DECL(alFilterfv),
239 DECL(alGetFilteri),
240 DECL(alGetFilteriv),
241 DECL(alGetFilterf),
242 DECL(alGetFilterfv),
243 DECL(alGenEffects),
244 DECL(alDeleteEffects),
245 DECL(alIsEffect),
246 DECL(alEffecti),
247 DECL(alEffectiv),
248 DECL(alEffectf),
249 DECL(alEffectfv),
250 DECL(alGetEffecti),
251 DECL(alGetEffectiv),
252 DECL(alGetEffectf),
253 DECL(alGetEffectfv),
254 DECL(alGenAuxiliaryEffectSlots),
255 DECL(alDeleteAuxiliaryEffectSlots),
256 DECL(alIsAuxiliaryEffectSlot),
257 DECL(alAuxiliaryEffectSloti),
258 DECL(alAuxiliaryEffectSlotiv),
259 DECL(alAuxiliaryEffectSlotf),
260 DECL(alAuxiliaryEffectSlotfv),
261 DECL(alGetAuxiliaryEffectSloti),
262 DECL(alGetAuxiliaryEffectSlotiv),
263 DECL(alGetAuxiliaryEffectSlotf),
264 DECL(alGetAuxiliaryEffectSlotfv),
266 DECL(alDeferUpdatesSOFT),
267 DECL(alProcessUpdatesSOFT),
269 DECL(alSourcedSOFT),
270 DECL(alSource3dSOFT),
271 DECL(alSourcedvSOFT),
272 DECL(alGetSourcedSOFT),
273 DECL(alGetSource3dSOFT),
274 DECL(alGetSourcedvSOFT),
275 DECL(alSourcei64SOFT),
276 DECL(alSource3i64SOFT),
277 DECL(alSourcei64vSOFT),
278 DECL(alGetSourcei64SOFT),
279 DECL(alGetSource3i64SOFT),
280 DECL(alGetSourcei64vSOFT),
282 DECL(alBufferSamplesSOFT),
283 DECL(alGetBufferSamplesSOFT),
284 DECL(alIsBufferFormatSupportedSOFT),
286 DECL(alGetStringiSOFT),
288 #undef DECL
290 #define DECL(x) { #x, (x) }
291 static const struct {
292 const ALCchar *enumName;
293 ALCenum value;
294 } alcEnumerations[] = {
295 DECL(ALC_INVALID),
296 DECL(ALC_FALSE),
297 DECL(ALC_TRUE),
299 DECL(ALC_MAJOR_VERSION),
300 DECL(ALC_MINOR_VERSION),
301 DECL(ALC_ATTRIBUTES_SIZE),
302 DECL(ALC_ALL_ATTRIBUTES),
303 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
304 DECL(ALC_DEVICE_SPECIFIER),
305 DECL(ALC_ALL_DEVICES_SPECIFIER),
306 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
307 DECL(ALC_EXTENSIONS),
308 DECL(ALC_FREQUENCY),
309 DECL(ALC_REFRESH),
310 DECL(ALC_SYNC),
311 DECL(ALC_MONO_SOURCES),
312 DECL(ALC_STEREO_SOURCES),
313 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
314 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
315 DECL(ALC_CAPTURE_SAMPLES),
316 DECL(ALC_CONNECTED),
318 DECL(ALC_EFX_MAJOR_VERSION),
319 DECL(ALC_EFX_MINOR_VERSION),
320 DECL(ALC_MAX_AUXILIARY_SENDS),
322 DECL(ALC_FORMAT_CHANNELS_SOFT),
323 DECL(ALC_FORMAT_TYPE_SOFT),
325 DECL(ALC_MONO_SOFT),
326 DECL(ALC_STEREO_SOFT),
327 DECL(ALC_QUAD_SOFT),
328 DECL(ALC_5POINT1_SOFT),
329 DECL(ALC_6POINT1_SOFT),
330 DECL(ALC_7POINT1_SOFT),
331 DECL(ALC_BFORMAT3D_SOFT),
333 DECL(ALC_BYTE_SOFT),
334 DECL(ALC_UNSIGNED_BYTE_SOFT),
335 DECL(ALC_SHORT_SOFT),
336 DECL(ALC_UNSIGNED_SHORT_SOFT),
337 DECL(ALC_INT_SOFT),
338 DECL(ALC_UNSIGNED_INT_SOFT),
339 DECL(ALC_FLOAT_SOFT),
341 DECL(ALC_HRTF_SOFT),
342 DECL(ALC_DONT_CARE_SOFT),
343 DECL(ALC_HRTF_STATUS_SOFT),
344 DECL(ALC_HRTF_DISABLED_SOFT),
345 DECL(ALC_HRTF_ENABLED_SOFT),
346 DECL(ALC_HRTF_DENIED_SOFT),
347 DECL(ALC_HRTF_REQUIRED_SOFT),
348 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
349 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
350 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
351 DECL(ALC_HRTF_SPECIFIER_SOFT),
352 DECL(ALC_HRTF_ID_SOFT),
354 DECL(ALC_AMBISONIC_LAYOUT_SOFT),
355 DECL(ALC_AMBISONIC_SCALING_SOFT),
356 DECL(ALC_AMBISONIC_ORDER_SOFT),
357 DECL(ALC_ACN_SOFT),
358 DECL(ALC_FUMA_SOFT),
359 DECL(ALC_N3D_SOFT),
360 DECL(ALC_SN3D_SOFT),
362 DECL(ALC_OUTPUT_LIMITER_SOFT),
364 DECL(ALC_NO_ERROR),
365 DECL(ALC_INVALID_DEVICE),
366 DECL(ALC_INVALID_CONTEXT),
367 DECL(ALC_INVALID_ENUM),
368 DECL(ALC_INVALID_VALUE),
369 DECL(ALC_OUT_OF_MEMORY),
372 DECL(AL_INVALID),
373 DECL(AL_NONE),
374 DECL(AL_FALSE),
375 DECL(AL_TRUE),
377 DECL(AL_SOURCE_RELATIVE),
378 DECL(AL_CONE_INNER_ANGLE),
379 DECL(AL_CONE_OUTER_ANGLE),
380 DECL(AL_PITCH),
381 DECL(AL_POSITION),
382 DECL(AL_DIRECTION),
383 DECL(AL_VELOCITY),
384 DECL(AL_LOOPING),
385 DECL(AL_BUFFER),
386 DECL(AL_GAIN),
387 DECL(AL_MIN_GAIN),
388 DECL(AL_MAX_GAIN),
389 DECL(AL_ORIENTATION),
390 DECL(AL_REFERENCE_DISTANCE),
391 DECL(AL_ROLLOFF_FACTOR),
392 DECL(AL_CONE_OUTER_GAIN),
393 DECL(AL_MAX_DISTANCE),
394 DECL(AL_SEC_OFFSET),
395 DECL(AL_SAMPLE_OFFSET),
396 DECL(AL_BYTE_OFFSET),
397 DECL(AL_SOURCE_TYPE),
398 DECL(AL_STATIC),
399 DECL(AL_STREAMING),
400 DECL(AL_UNDETERMINED),
401 DECL(AL_METERS_PER_UNIT),
402 DECL(AL_LOOP_POINTS_SOFT),
403 DECL(AL_DIRECT_CHANNELS_SOFT),
405 DECL(AL_DIRECT_FILTER),
406 DECL(AL_AUXILIARY_SEND_FILTER),
407 DECL(AL_AIR_ABSORPTION_FACTOR),
408 DECL(AL_ROOM_ROLLOFF_FACTOR),
409 DECL(AL_CONE_OUTER_GAINHF),
410 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
412 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
414 DECL(AL_SOURCE_STATE),
415 DECL(AL_INITIAL),
416 DECL(AL_PLAYING),
417 DECL(AL_PAUSED),
418 DECL(AL_STOPPED),
420 DECL(AL_BUFFERS_QUEUED),
421 DECL(AL_BUFFERS_PROCESSED),
423 DECL(AL_FORMAT_MONO8),
424 DECL(AL_FORMAT_MONO16),
425 DECL(AL_FORMAT_MONO_FLOAT32),
426 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
427 DECL(AL_FORMAT_STEREO8),
428 DECL(AL_FORMAT_STEREO16),
429 DECL(AL_FORMAT_STEREO_FLOAT32),
430 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
431 DECL(AL_FORMAT_MONO_IMA4),
432 DECL(AL_FORMAT_STEREO_IMA4),
433 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
434 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
435 DECL(AL_FORMAT_QUAD8_LOKI),
436 DECL(AL_FORMAT_QUAD16_LOKI),
437 DECL(AL_FORMAT_QUAD8),
438 DECL(AL_FORMAT_QUAD16),
439 DECL(AL_FORMAT_QUAD32),
440 DECL(AL_FORMAT_51CHN8),
441 DECL(AL_FORMAT_51CHN16),
442 DECL(AL_FORMAT_51CHN32),
443 DECL(AL_FORMAT_61CHN8),
444 DECL(AL_FORMAT_61CHN16),
445 DECL(AL_FORMAT_61CHN32),
446 DECL(AL_FORMAT_71CHN8),
447 DECL(AL_FORMAT_71CHN16),
448 DECL(AL_FORMAT_71CHN32),
449 DECL(AL_FORMAT_REAR8),
450 DECL(AL_FORMAT_REAR16),
451 DECL(AL_FORMAT_REAR32),
452 DECL(AL_FORMAT_MONO_MULAW),
453 DECL(AL_FORMAT_MONO_MULAW_EXT),
454 DECL(AL_FORMAT_STEREO_MULAW),
455 DECL(AL_FORMAT_STEREO_MULAW_EXT),
456 DECL(AL_FORMAT_QUAD_MULAW),
457 DECL(AL_FORMAT_51CHN_MULAW),
458 DECL(AL_FORMAT_61CHN_MULAW),
459 DECL(AL_FORMAT_71CHN_MULAW),
460 DECL(AL_FORMAT_REAR_MULAW),
461 DECL(AL_FORMAT_MONO_ALAW_EXT),
462 DECL(AL_FORMAT_STEREO_ALAW_EXT),
464 DECL(AL_FORMAT_BFORMAT2D_8),
465 DECL(AL_FORMAT_BFORMAT2D_16),
466 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
467 DECL(AL_FORMAT_BFORMAT2D_MULAW),
468 DECL(AL_FORMAT_BFORMAT3D_8),
469 DECL(AL_FORMAT_BFORMAT3D_16),
470 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
471 DECL(AL_FORMAT_BFORMAT3D_MULAW),
473 DECL(AL_MONO8_SOFT),
474 DECL(AL_MONO16_SOFT),
475 DECL(AL_MONO32F_SOFT),
476 DECL(AL_STEREO8_SOFT),
477 DECL(AL_STEREO16_SOFT),
478 DECL(AL_STEREO32F_SOFT),
479 DECL(AL_QUAD8_SOFT),
480 DECL(AL_QUAD16_SOFT),
481 DECL(AL_QUAD32F_SOFT),
482 DECL(AL_REAR8_SOFT),
483 DECL(AL_REAR16_SOFT),
484 DECL(AL_REAR32F_SOFT),
485 DECL(AL_5POINT1_8_SOFT),
486 DECL(AL_5POINT1_16_SOFT),
487 DECL(AL_5POINT1_32F_SOFT),
488 DECL(AL_6POINT1_8_SOFT),
489 DECL(AL_6POINT1_16_SOFT),
490 DECL(AL_6POINT1_32F_SOFT),
491 DECL(AL_7POINT1_8_SOFT),
492 DECL(AL_7POINT1_16_SOFT),
493 DECL(AL_7POINT1_32F_SOFT),
494 DECL(AL_BFORMAT2D_8_SOFT),
495 DECL(AL_BFORMAT2D_16_SOFT),
496 DECL(AL_BFORMAT2D_32F_SOFT),
497 DECL(AL_BFORMAT3D_8_SOFT),
498 DECL(AL_BFORMAT3D_16_SOFT),
499 DECL(AL_BFORMAT3D_32F_SOFT),
501 DECL(AL_MONO_SOFT),
502 DECL(AL_STEREO_SOFT),
503 DECL(AL_QUAD_SOFT),
504 DECL(AL_REAR_SOFT),
505 DECL(AL_5POINT1_SOFT),
506 DECL(AL_6POINT1_SOFT),
507 DECL(AL_7POINT1_SOFT),
508 DECL(AL_BFORMAT2D_SOFT),
509 DECL(AL_BFORMAT3D_SOFT),
511 DECL(AL_BYTE_SOFT),
512 DECL(AL_UNSIGNED_BYTE_SOFT),
513 DECL(AL_SHORT_SOFT),
514 DECL(AL_UNSIGNED_SHORT_SOFT),
515 DECL(AL_INT_SOFT),
516 DECL(AL_UNSIGNED_INT_SOFT),
517 DECL(AL_FLOAT_SOFT),
518 DECL(AL_DOUBLE_SOFT),
519 DECL(AL_BYTE3_SOFT),
520 DECL(AL_UNSIGNED_BYTE3_SOFT),
521 DECL(AL_MULAW_SOFT),
523 DECL(AL_FREQUENCY),
524 DECL(AL_BITS),
525 DECL(AL_CHANNELS),
526 DECL(AL_SIZE),
527 DECL(AL_INTERNAL_FORMAT_SOFT),
528 DECL(AL_BYTE_LENGTH_SOFT),
529 DECL(AL_SAMPLE_LENGTH_SOFT),
530 DECL(AL_SEC_LENGTH_SOFT),
531 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
532 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
534 DECL(AL_SOURCE_RADIUS),
536 DECL(AL_STEREO_ANGLES),
538 DECL(AL_UNUSED),
539 DECL(AL_PENDING),
540 DECL(AL_PROCESSED),
542 DECL(AL_NO_ERROR),
543 DECL(AL_INVALID_NAME),
544 DECL(AL_INVALID_ENUM),
545 DECL(AL_INVALID_VALUE),
546 DECL(AL_INVALID_OPERATION),
547 DECL(AL_OUT_OF_MEMORY),
549 DECL(AL_VENDOR),
550 DECL(AL_VERSION),
551 DECL(AL_RENDERER),
552 DECL(AL_EXTENSIONS),
554 DECL(AL_DOPPLER_FACTOR),
555 DECL(AL_DOPPLER_VELOCITY),
556 DECL(AL_DISTANCE_MODEL),
557 DECL(AL_SPEED_OF_SOUND),
558 DECL(AL_SOURCE_DISTANCE_MODEL),
559 DECL(AL_DEFERRED_UPDATES_SOFT),
560 DECL(AL_GAIN_LIMIT_SOFT),
562 DECL(AL_INVERSE_DISTANCE),
563 DECL(AL_INVERSE_DISTANCE_CLAMPED),
564 DECL(AL_LINEAR_DISTANCE),
565 DECL(AL_LINEAR_DISTANCE_CLAMPED),
566 DECL(AL_EXPONENT_DISTANCE),
567 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
569 DECL(AL_FILTER_TYPE),
570 DECL(AL_FILTER_NULL),
571 DECL(AL_FILTER_LOWPASS),
572 DECL(AL_FILTER_HIGHPASS),
573 DECL(AL_FILTER_BANDPASS),
575 DECL(AL_LOWPASS_GAIN),
576 DECL(AL_LOWPASS_GAINHF),
578 DECL(AL_HIGHPASS_GAIN),
579 DECL(AL_HIGHPASS_GAINLF),
581 DECL(AL_BANDPASS_GAIN),
582 DECL(AL_BANDPASS_GAINHF),
583 DECL(AL_BANDPASS_GAINLF),
585 DECL(AL_EFFECT_TYPE),
586 DECL(AL_EFFECT_NULL),
587 DECL(AL_EFFECT_REVERB),
588 DECL(AL_EFFECT_EAXREVERB),
589 DECL(AL_EFFECT_CHORUS),
590 DECL(AL_EFFECT_DISTORTION),
591 DECL(AL_EFFECT_ECHO),
592 DECL(AL_EFFECT_FLANGER),
593 #if 0
594 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
595 DECL(AL_EFFECT_VOCAL_MORPHER),
596 DECL(AL_EFFECT_PITCH_SHIFTER),
597 #endif
598 DECL(AL_EFFECT_RING_MODULATOR),
599 #if 0
600 DECL(AL_EFFECT_AUTOWAH),
601 #endif
602 DECL(AL_EFFECT_COMPRESSOR),
603 DECL(AL_EFFECT_EQUALIZER),
604 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
605 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
607 DECL(AL_EFFECTSLOT_EFFECT),
608 DECL(AL_EFFECTSLOT_GAIN),
609 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
610 DECL(AL_EFFECTSLOT_NULL),
612 DECL(AL_EAXREVERB_DENSITY),
613 DECL(AL_EAXREVERB_DIFFUSION),
614 DECL(AL_EAXREVERB_GAIN),
615 DECL(AL_EAXREVERB_GAINHF),
616 DECL(AL_EAXREVERB_GAINLF),
617 DECL(AL_EAXREVERB_DECAY_TIME),
618 DECL(AL_EAXREVERB_DECAY_HFRATIO),
619 DECL(AL_EAXREVERB_DECAY_LFRATIO),
620 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
621 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
622 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
623 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
624 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
625 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
626 DECL(AL_EAXREVERB_ECHO_TIME),
627 DECL(AL_EAXREVERB_ECHO_DEPTH),
628 DECL(AL_EAXREVERB_MODULATION_TIME),
629 DECL(AL_EAXREVERB_MODULATION_DEPTH),
630 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
631 DECL(AL_EAXREVERB_HFREFERENCE),
632 DECL(AL_EAXREVERB_LFREFERENCE),
633 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
634 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
636 DECL(AL_REVERB_DENSITY),
637 DECL(AL_REVERB_DIFFUSION),
638 DECL(AL_REVERB_GAIN),
639 DECL(AL_REVERB_GAINHF),
640 DECL(AL_REVERB_DECAY_TIME),
641 DECL(AL_REVERB_DECAY_HFRATIO),
642 DECL(AL_REVERB_REFLECTIONS_GAIN),
643 DECL(AL_REVERB_REFLECTIONS_DELAY),
644 DECL(AL_REVERB_LATE_REVERB_GAIN),
645 DECL(AL_REVERB_LATE_REVERB_DELAY),
646 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
647 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
648 DECL(AL_REVERB_DECAY_HFLIMIT),
650 DECL(AL_CHORUS_WAVEFORM),
651 DECL(AL_CHORUS_PHASE),
652 DECL(AL_CHORUS_RATE),
653 DECL(AL_CHORUS_DEPTH),
654 DECL(AL_CHORUS_FEEDBACK),
655 DECL(AL_CHORUS_DELAY),
657 DECL(AL_DISTORTION_EDGE),
658 DECL(AL_DISTORTION_GAIN),
659 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
660 DECL(AL_DISTORTION_EQCENTER),
661 DECL(AL_DISTORTION_EQBANDWIDTH),
663 DECL(AL_ECHO_DELAY),
664 DECL(AL_ECHO_LRDELAY),
665 DECL(AL_ECHO_DAMPING),
666 DECL(AL_ECHO_FEEDBACK),
667 DECL(AL_ECHO_SPREAD),
669 DECL(AL_FLANGER_WAVEFORM),
670 DECL(AL_FLANGER_PHASE),
671 DECL(AL_FLANGER_RATE),
672 DECL(AL_FLANGER_DEPTH),
673 DECL(AL_FLANGER_FEEDBACK),
674 DECL(AL_FLANGER_DELAY),
676 DECL(AL_RING_MODULATOR_FREQUENCY),
677 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
678 DECL(AL_RING_MODULATOR_WAVEFORM),
680 DECL(AL_COMPRESSOR_ONOFF),
682 DECL(AL_EQUALIZER_LOW_GAIN),
683 DECL(AL_EQUALIZER_LOW_CUTOFF),
684 DECL(AL_EQUALIZER_MID1_GAIN),
685 DECL(AL_EQUALIZER_MID1_CENTER),
686 DECL(AL_EQUALIZER_MID1_WIDTH),
687 DECL(AL_EQUALIZER_MID2_GAIN),
688 DECL(AL_EQUALIZER_MID2_CENTER),
689 DECL(AL_EQUALIZER_MID2_WIDTH),
690 DECL(AL_EQUALIZER_HIGH_GAIN),
691 DECL(AL_EQUALIZER_HIGH_CUTOFF),
693 DECL(AL_DEDICATED_GAIN),
695 DECL(AL_NUM_RESAMPLERS_SOFT),
696 DECL(AL_DEFAULT_RESAMPLER_SOFT),
697 DECL(AL_SOURCE_RESAMPLER_SOFT),
698 DECL(AL_RESAMPLER_NAME_SOFT),
700 DECL(AL_SOURCE_SPATIALIZE_SOFT),
701 DECL(AL_AUTO_SOFT),
703 #undef DECL
705 static const ALCchar alcNoError[] = "No Error";
706 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
707 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
708 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
709 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
710 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
713 /************************************************
714 * Global variables
715 ************************************************/
717 /* Enumerated device names */
718 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
720 static al_string alcAllDevicesList;
721 static al_string alcCaptureDeviceList;
723 /* Default is always the first in the list */
724 static ALCchar *alcDefaultAllDevicesSpecifier;
725 static ALCchar *alcCaptureDefaultDeviceSpecifier;
727 /* Default context extensions */
728 static const ALchar alExtList[] =
729 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
730 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
731 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
732 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
733 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
734 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
735 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length "
736 "AL_SOFT_source_resampler AL_SOFT_source_spatialize";
738 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
740 /* Thread-local current context */
741 static altss_t LocalContext;
742 /* Process-wide current context */
743 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
745 /* Mixing thread piority level */
746 ALint RTPrioLevel;
748 FILE *LogFile;
749 #ifdef _DEBUG
750 enum LogLevel LogLevel = LogWarning;
751 #else
752 enum LogLevel LogLevel = LogError;
753 #endif
755 /* Flag to trap ALC device errors */
756 static ALCboolean TrapALCError = ALC_FALSE;
758 /* One-time configuration init control */
759 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
761 /* Default effect that applies to sources that don't have an effect on send 0 */
762 static ALeffect DefaultEffect;
764 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
765 * updates.
767 static ALCboolean SuspendDefers = ALC_TRUE;
770 /************************************************
771 * ALC information
772 ************************************************/
773 static const ALCchar alcNoDeviceExtList[] =
774 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
775 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
776 static const ALCchar alcExtensionList[] =
777 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
778 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
779 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
780 "ALC_SOFT_loopback ALC_SOFT_output_limiter ALC_SOFT_pause_device";
781 static const ALCint alcMajorVersion = 1;
782 static const ALCint alcMinorVersion = 1;
784 static const ALCint alcEFXMajorVersion = 1;
785 static const ALCint alcEFXMinorVersion = 0;
788 /************************************************
789 * Device lists
790 ************************************************/
791 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
793 static almtx_t ListLock;
794 static inline void LockLists(void)
796 int ret = almtx_lock(&ListLock);
797 assert(ret == althrd_success);
799 static inline void UnlockLists(void)
801 int ret = almtx_unlock(&ListLock);
802 assert(ret == althrd_success);
805 /************************************************
806 * Library initialization
807 ************************************************/
808 #if defined(_WIN32)
809 static void alc_init(void);
810 static void alc_deinit(void);
811 static void alc_deinit_safe(void);
813 #ifndef AL_LIBTYPE_STATIC
814 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
816 switch(reason)
818 case DLL_PROCESS_ATTACH:
819 /* Pin the DLL so we won't get unloaded until the process terminates */
820 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
821 (WCHAR*)hModule, &hModule);
822 alc_init();
823 break;
825 case DLL_THREAD_DETACH:
826 break;
828 case DLL_PROCESS_DETACH:
829 if(!lpReserved)
830 alc_deinit();
831 else
832 alc_deinit_safe();
833 break;
835 return TRUE;
837 #elif defined(_MSC_VER)
838 #pragma section(".CRT$XCU",read)
839 static void alc_constructor(void);
840 static void alc_destructor(void);
841 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
843 static void alc_constructor(void)
845 atexit(alc_destructor);
846 alc_init();
849 static void alc_destructor(void)
851 alc_deinit();
853 #elif defined(HAVE_GCC_DESTRUCTOR)
854 static void alc_init(void) __attribute__((constructor));
855 static void alc_deinit(void) __attribute__((destructor));
856 #else
857 #error "No static initialization available on this platform!"
858 #endif
860 #elif defined(HAVE_GCC_DESTRUCTOR)
862 static void alc_init(void) __attribute__((constructor));
863 static void alc_deinit(void) __attribute__((destructor));
865 #else
866 #error "No global initialization available on this platform!"
867 #endif
869 static void ReleaseThreadCtx(void *ptr);
870 static void alc_init(void)
872 const char *str;
873 int ret;
875 LogFile = stderr;
877 AL_STRING_INIT(alcAllDevicesList);
878 AL_STRING_INIT(alcCaptureDeviceList);
880 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
881 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
882 ConeScale *= 0.5f;
884 str = getenv("__ALSOFT_REVERSE_Z");
885 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
886 ZScale *= -1.0f;
888 ret = altss_create(&LocalContext, ReleaseThreadCtx);
889 assert(ret == althrd_success);
891 ret = almtx_init(&ListLock, almtx_recursive);
892 assert(ret == althrd_success);
894 ThunkInit();
897 static void alc_initconfig(void)
899 const char *devs, *str;
900 ALuint capfilter;
901 float valf;
902 int i, n;
904 str = getenv("ALSOFT_LOGLEVEL");
905 if(str)
907 long lvl = strtol(str, NULL, 0);
908 if(lvl >= NoLog && lvl <= LogRef)
909 LogLevel = lvl;
912 str = getenv("ALSOFT_LOGFILE");
913 if(str && str[0])
915 FILE *logfile = al_fopen(str, "wt");
916 if(logfile) LogFile = logfile;
917 else ERR("Failed to open log file '%s'\n", str);
920 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION,
921 ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
923 char buf[1024] = "";
924 int len = 0;
926 if(BackendListSize > 0)
927 len += snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
928 for(i = 1;i < BackendListSize;i++)
929 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
930 TRACE("Supported backends: %s\n", buf);
932 ReadALConfig();
934 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
935 if(str && *str)
937 if(strcasecmp(str, "ignore") == 0)
939 SuspendDefers = ALC_FALSE;
940 TRACE("Selected context suspend behavior, \"ignore\"\n");
942 else
943 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
946 capfilter = 0;
947 #if defined(HAVE_SSE4_1)
948 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
949 #elif defined(HAVE_SSE3)
950 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
951 #elif defined(HAVE_SSE2)
952 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
953 #elif defined(HAVE_SSE)
954 capfilter |= CPU_CAP_SSE;
955 #endif
956 #ifdef HAVE_NEON
957 capfilter |= CPU_CAP_NEON;
958 #endif
959 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
961 if(strcasecmp(str, "all") == 0)
962 capfilter = 0;
963 else
965 size_t len;
966 const char *next = str;
968 do {
969 str = next;
970 while(isspace(str[0]))
971 str++;
972 next = strchr(str, ',');
974 if(!str[0] || str[0] == ',')
975 continue;
977 len = (next ? ((size_t)(next-str)) : strlen(str));
978 while(len > 0 && isspace(str[len-1]))
979 len--;
980 if(len == 3 && strncasecmp(str, "sse", len) == 0)
981 capfilter &= ~CPU_CAP_SSE;
982 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
983 capfilter &= ~CPU_CAP_SSE2;
984 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
985 capfilter &= ~CPU_CAP_SSE3;
986 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
987 capfilter &= ~CPU_CAP_SSE4_1;
988 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
989 capfilter &= ~CPU_CAP_NEON;
990 else
991 WARN("Invalid CPU extension \"%s\"\n", str);
992 } while(next++);
995 FillCPUCaps(capfilter);
997 #ifdef _WIN32
998 RTPrioLevel = 1;
999 #else
1000 RTPrioLevel = 0;
1001 #endif
1002 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
1004 aluInitMixer();
1006 str = getenv("ALSOFT_TRAP_ERROR");
1007 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1009 TrapALError = AL_TRUE;
1010 TrapALCError = AL_TRUE;
1012 else
1014 str = getenv("ALSOFT_TRAP_AL_ERROR");
1015 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1016 TrapALError = AL_TRUE;
1017 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1019 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1020 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1021 TrapALCError = ALC_TRUE;
1022 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1025 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1026 ReverbBoost *= powf(10.0f, valf / 20.0f);
1028 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1030 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1031 ConfigValueStr(NULL, NULL, "drivers", &devs))
1033 int n;
1034 size_t len;
1035 const char *next = devs;
1036 int endlist, delitem;
1038 i = 0;
1039 do {
1040 devs = next;
1041 while(isspace(devs[0]))
1042 devs++;
1043 next = strchr(devs, ',');
1045 delitem = (devs[0] == '-');
1046 if(devs[0] == '-') devs++;
1048 if(!devs[0] || devs[0] == ',')
1050 endlist = 0;
1051 continue;
1053 endlist = 1;
1055 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1056 while(len > 0 && isspace(devs[len-1]))
1057 len--;
1058 for(n = i;n < BackendListSize;n++)
1060 if(len == strlen(BackendList[n].name) &&
1061 strncmp(BackendList[n].name, devs, len) == 0)
1063 if(delitem)
1065 for(;n+1 < BackendListSize;n++)
1066 BackendList[n] = BackendList[n+1];
1067 BackendListSize--;
1069 else
1071 struct BackendInfo Bkp = BackendList[n];
1072 for(;n > i;n--)
1073 BackendList[n] = BackendList[n-1];
1074 BackendList[n] = Bkp;
1076 i++;
1078 break;
1081 } while(next++);
1083 if(endlist)
1084 BackendListSize = i;
1087 for(i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1089 ALCbackendFactory *factory = BackendList[i].getFactory();
1090 if(!V0(factory,init)())
1092 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1093 continue;
1096 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1097 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1099 PlaybackBackend = BackendList[i];
1100 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1102 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1104 CaptureBackend = BackendList[i];
1105 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1109 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1110 V0(factory,init)();
1113 if(!PlaybackBackend.name)
1114 WARN("No playback backend available!\n");
1115 if(!CaptureBackend.name)
1116 WARN("No capture backend available!\n");
1118 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1120 size_t len;
1121 const char *next = str;
1123 do {
1124 str = next;
1125 next = strchr(str, ',');
1127 if(!str[0] || next == str)
1128 continue;
1130 len = (next ? ((size_t)(next-str)) : strlen(str));
1131 for(n = 0;EffectList[n].name;n++)
1133 if(len == strlen(EffectList[n].name) &&
1134 strncmp(EffectList[n].name, str, len) == 0)
1135 DisabledEffects[EffectList[n].type] = AL_TRUE;
1137 } while(next++);
1140 InitEffectFactoryMap();
1142 InitEffect(&DefaultEffect);
1143 str = getenv("ALSOFT_DEFAULT_REVERB");
1144 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1145 LoadReverbPreset(str, &DefaultEffect);
1147 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1149 #ifdef __ANDROID__
1150 #include <jni.h>
1152 static JavaVM *gJavaVM;
1153 static pthread_key_t gJVMThreadKey;
1155 static void CleanupJNIEnv(void* UNUSED(ptr))
1157 JCALL0(gJavaVM,DetachCurrentThread)();
1160 void *Android_GetJNIEnv(void)
1162 if(!gJavaVM)
1164 WARN("gJavaVM is NULL!\n");
1165 return NULL;
1168 /* http://developer.android.com/guide/practices/jni.html
1170 * All threads are Linux threads, scheduled by the kernel. They're usually
1171 * started from managed code (using Thread.start), but they can also be
1172 * created elsewhere and then attached to the JavaVM. For example, a thread
1173 * started with pthread_create can be attached with the JNI
1174 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1175 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1176 * Attaching a natively-created thread causes a java.lang.Thread object to
1177 * be constructed and added to the "main" ThreadGroup, making it visible to
1178 * the debugger. Calling AttachCurrentThread on an already-attached thread
1179 * is a no-op.
1181 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1182 if(!env)
1184 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1185 if(status < 0)
1187 ERR("Failed to attach current thread\n");
1188 return NULL;
1190 pthread_setspecific(gJVMThreadKey, env);
1192 return env;
1195 /* Automatically called by JNI. */
1196 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1198 void *env;
1199 int err;
1201 gJavaVM = jvm;
1202 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1204 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1205 return JNI_ERR;
1208 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1209 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1211 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1212 ERR("pthread_key_create failed: %d\n", err);
1213 pthread_setspecific(gJVMThreadKey, env);
1214 return JNI_VERSION_1_4;
1217 /* Android doesn't have log2f, really? */
1218 #define log2f(x) (logf(x) / logf(2.0f))
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 ALCbackendFactory *factory;
1295 DO_INITCONFIG();
1297 LockLists();
1298 alstr_clear(list);
1300 factory = backendinfo->getFactory();
1301 V(factory,probe)(type);
1303 UnlockLists();
1305 static void ProbeAllDevicesList(void)
1306 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1307 static void ProbeCaptureDeviceList(void)
1308 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1310 static void AppendDevice(const ALCchar *name, al_string *devnames)
1312 size_t len = strlen(name);
1313 if(len > 0)
1314 alstr_append_range(devnames, name, name+len+1);
1316 void AppendAllDevicesList(const ALCchar *name)
1317 { AppendDevice(name, &alcAllDevicesList); }
1318 void AppendCaptureDeviceList(const ALCchar *name)
1319 { AppendDevice(name, &alcCaptureDeviceList); }
1322 /************************************************
1323 * Device format information
1324 ************************************************/
1325 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1327 switch(type)
1329 case DevFmtByte: return "Signed Byte";
1330 case DevFmtUByte: return "Unsigned Byte";
1331 case DevFmtShort: return "Signed Short";
1332 case DevFmtUShort: return "Unsigned Short";
1333 case DevFmtInt: return "Signed Int";
1334 case DevFmtUInt: return "Unsigned Int";
1335 case DevFmtFloat: return "Float";
1337 return "(unknown type)";
1339 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1341 switch(chans)
1343 case DevFmtMono: return "Mono";
1344 case DevFmtStereo: return "Stereo";
1345 case DevFmtQuad: return "Quadraphonic";
1346 case DevFmtX51: return "5.1 Surround";
1347 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1348 case DevFmtX61: return "6.1 Surround";
1349 case DevFmtX71: return "7.1 Surround";
1350 case DevFmtAmbi3D: return "Ambisonic 3D";
1352 return "(unknown channels)";
1355 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder);
1356 ALsizei BytesFromDevFmt(enum DevFmtType type)
1358 switch(type)
1360 case DevFmtByte: return sizeof(ALbyte);
1361 case DevFmtUByte: return sizeof(ALubyte);
1362 case DevFmtShort: return sizeof(ALshort);
1363 case DevFmtUShort: return sizeof(ALushort);
1364 case DevFmtInt: return sizeof(ALint);
1365 case DevFmtUInt: return sizeof(ALuint);
1366 case DevFmtFloat: return sizeof(ALfloat);
1368 return 0;
1370 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder)
1372 switch(chans)
1374 case DevFmtMono: return 1;
1375 case DevFmtStereo: return 2;
1376 case DevFmtQuad: return 4;
1377 case DevFmtX51: return 6;
1378 case DevFmtX51Rear: return 6;
1379 case DevFmtX61: return 7;
1380 case DevFmtX71: return 8;
1381 case DevFmtAmbi3D: return (ambiorder >= 3) ? 16 :
1382 (ambiorder == 2) ? 9 :
1383 (ambiorder == 1) ? 4 : 1;
1385 return 0;
1388 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1389 enum DevFmtType *type)
1391 static const struct {
1392 ALenum format;
1393 enum DevFmtChannels channels;
1394 enum DevFmtType type;
1395 } list[] = {
1396 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1397 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1398 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1400 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1401 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1402 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1404 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1405 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1406 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1408 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1409 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1410 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1412 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1413 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1414 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1416 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1417 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1418 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1420 ALuint i;
1422 for(i = 0;i < COUNTOF(list);i++)
1424 if(list[i].format == format)
1426 *chans = list[i].channels;
1427 *type = list[i].type;
1428 return AL_TRUE;
1432 return AL_FALSE;
1435 static ALCboolean IsValidALCType(ALCenum type)
1437 switch(type)
1439 case ALC_BYTE_SOFT:
1440 case ALC_UNSIGNED_BYTE_SOFT:
1441 case ALC_SHORT_SOFT:
1442 case ALC_UNSIGNED_SHORT_SOFT:
1443 case ALC_INT_SOFT:
1444 case ALC_UNSIGNED_INT_SOFT:
1445 case ALC_FLOAT_SOFT:
1446 return ALC_TRUE;
1448 return ALC_FALSE;
1451 static ALCboolean IsValidALCChannels(ALCenum channels)
1453 switch(channels)
1455 case ALC_MONO_SOFT:
1456 case ALC_STEREO_SOFT:
1457 case ALC_QUAD_SOFT:
1458 case ALC_5POINT1_SOFT:
1459 case ALC_6POINT1_SOFT:
1460 case ALC_7POINT1_SOFT:
1461 case ALC_BFORMAT3D_SOFT:
1462 return ALC_TRUE;
1464 return ALC_FALSE;
1467 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1469 switch(layout)
1471 case ALC_ACN_SOFT:
1472 case ALC_FUMA_SOFT:
1473 return ALC_TRUE;
1475 return ALC_FALSE;
1478 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1480 switch(scaling)
1482 case ALC_N3D_SOFT:
1483 case ALC_SN3D_SOFT:
1484 case ALC_FUMA_SOFT:
1485 return ALC_TRUE;
1487 return ALC_FALSE;
1490 /************************************************
1491 * Miscellaneous ALC helpers
1492 ************************************************/
1494 void ALCdevice_Lock(ALCdevice *device)
1496 V0(device->Backend,lock)();
1499 void ALCdevice_Unlock(ALCdevice *device)
1501 V0(device->Backend,unlock)();
1505 /* SetDefaultWFXChannelOrder
1507 * Sets the default channel order used by WaveFormatEx.
1509 void SetDefaultWFXChannelOrder(ALCdevice *device)
1511 ALsizei i;
1513 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1514 device->RealOut.ChannelName[i] = InvalidChannel;
1516 switch(device->FmtChans)
1518 case DevFmtMono:
1519 device->RealOut.ChannelName[0] = FrontCenter;
1520 break;
1521 case DevFmtStereo:
1522 device->RealOut.ChannelName[0] = FrontLeft;
1523 device->RealOut.ChannelName[1] = FrontRight;
1524 break;
1525 case DevFmtQuad:
1526 device->RealOut.ChannelName[0] = FrontLeft;
1527 device->RealOut.ChannelName[1] = FrontRight;
1528 device->RealOut.ChannelName[2] = BackLeft;
1529 device->RealOut.ChannelName[3] = BackRight;
1530 break;
1531 case DevFmtX51:
1532 device->RealOut.ChannelName[0] = FrontLeft;
1533 device->RealOut.ChannelName[1] = FrontRight;
1534 device->RealOut.ChannelName[2] = FrontCenter;
1535 device->RealOut.ChannelName[3] = LFE;
1536 device->RealOut.ChannelName[4] = SideLeft;
1537 device->RealOut.ChannelName[5] = SideRight;
1538 break;
1539 case DevFmtX51Rear:
1540 device->RealOut.ChannelName[0] = FrontLeft;
1541 device->RealOut.ChannelName[1] = FrontRight;
1542 device->RealOut.ChannelName[2] = FrontCenter;
1543 device->RealOut.ChannelName[3] = LFE;
1544 device->RealOut.ChannelName[4] = BackLeft;
1545 device->RealOut.ChannelName[5] = BackRight;
1546 break;
1547 case DevFmtX61:
1548 device->RealOut.ChannelName[0] = FrontLeft;
1549 device->RealOut.ChannelName[1] = FrontRight;
1550 device->RealOut.ChannelName[2] = FrontCenter;
1551 device->RealOut.ChannelName[3] = LFE;
1552 device->RealOut.ChannelName[4] = BackCenter;
1553 device->RealOut.ChannelName[5] = SideLeft;
1554 device->RealOut.ChannelName[6] = SideRight;
1555 break;
1556 case DevFmtX71:
1557 device->RealOut.ChannelName[0] = FrontLeft;
1558 device->RealOut.ChannelName[1] = FrontRight;
1559 device->RealOut.ChannelName[2] = FrontCenter;
1560 device->RealOut.ChannelName[3] = LFE;
1561 device->RealOut.ChannelName[4] = BackLeft;
1562 device->RealOut.ChannelName[5] = BackRight;
1563 device->RealOut.ChannelName[6] = SideLeft;
1564 device->RealOut.ChannelName[7] = SideRight;
1565 break;
1566 case DevFmtAmbi3D:
1567 device->RealOut.ChannelName[0] = Aux0;
1568 if(device->AmbiOrder > 0)
1570 device->RealOut.ChannelName[1] = Aux1;
1571 device->RealOut.ChannelName[2] = Aux2;
1572 device->RealOut.ChannelName[3] = Aux3;
1574 if(device->AmbiOrder > 1)
1576 device->RealOut.ChannelName[4] = Aux4;
1577 device->RealOut.ChannelName[5] = Aux5;
1578 device->RealOut.ChannelName[6] = Aux6;
1579 device->RealOut.ChannelName[7] = Aux7;
1580 device->RealOut.ChannelName[8] = Aux8;
1582 if(device->AmbiOrder > 2)
1584 device->RealOut.ChannelName[9] = Aux9;
1585 device->RealOut.ChannelName[10] = Aux10;
1586 device->RealOut.ChannelName[11] = Aux11;
1587 device->RealOut.ChannelName[12] = Aux12;
1588 device->RealOut.ChannelName[13] = Aux13;
1589 device->RealOut.ChannelName[14] = Aux14;
1590 device->RealOut.ChannelName[15] = Aux15;
1592 break;
1596 /* SetDefaultChannelOrder
1598 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1600 void SetDefaultChannelOrder(ALCdevice *device)
1602 ALsizei i;
1604 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1605 device->RealOut.ChannelName[i] = InvalidChannel;
1607 switch(device->FmtChans)
1609 case DevFmtX51Rear:
1610 device->RealOut.ChannelName[0] = FrontLeft;
1611 device->RealOut.ChannelName[1] = FrontRight;
1612 device->RealOut.ChannelName[2] = BackLeft;
1613 device->RealOut.ChannelName[3] = BackRight;
1614 device->RealOut.ChannelName[4] = FrontCenter;
1615 device->RealOut.ChannelName[5] = LFE;
1616 return;
1617 case DevFmtX71:
1618 device->RealOut.ChannelName[0] = FrontLeft;
1619 device->RealOut.ChannelName[1] = FrontRight;
1620 device->RealOut.ChannelName[2] = BackLeft;
1621 device->RealOut.ChannelName[3] = BackRight;
1622 device->RealOut.ChannelName[4] = FrontCenter;
1623 device->RealOut.ChannelName[5] = LFE;
1624 device->RealOut.ChannelName[6] = SideLeft;
1625 device->RealOut.ChannelName[7] = SideRight;
1626 return;
1628 /* Same as WFX order */
1629 case DevFmtMono:
1630 case DevFmtStereo:
1631 case DevFmtQuad:
1632 case DevFmtX51:
1633 case DevFmtX61:
1634 case DevFmtAmbi3D:
1635 SetDefaultWFXChannelOrder(device);
1636 break;
1640 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1643 /* ALCcontext_DeferUpdates
1645 * Defers/suspends updates for the given context's listener and sources. This
1646 * does *NOT* stop mixing, but rather prevents certain property changes from
1647 * taking effect.
1649 void ALCcontext_DeferUpdates(ALCcontext *context)
1651 ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE);
1654 /* ALCcontext_ProcessUpdates
1656 * Resumes update processing after being deferred.
1658 void ALCcontext_ProcessUpdates(ALCcontext *context)
1660 ReadLock(&context->PropLock);
1661 if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
1663 /* Tell the mixer to stop applying updates, then wait for any active
1664 * updating to finish, before providing updates.
1666 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1667 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1668 althrd_yield();
1670 UpdateListenerProps(context);
1671 UpdateAllEffectSlotProps(context);
1672 UpdateAllSourceProps(context);
1674 /* Now with all updates declared, let the mixer continue applying them
1675 * so they all happen at once.
1677 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1679 ReadUnlock(&context->PropLock);
1683 /* alcSetError
1685 * Stores the latest ALC device error
1687 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1689 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1690 if(TrapALCError)
1692 #ifdef _WIN32
1693 /* DebugBreak() will cause an exception if there is no debugger */
1694 if(IsDebuggerPresent())
1695 DebugBreak();
1696 #elif defined(SIGTRAP)
1697 raise(SIGTRAP);
1698 #endif
1701 if(device)
1702 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1703 else
1704 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1708 struct Compressor *CreateDeviceLimiter(const ALCdevice *device)
1710 return CompressorInit(0.0f, 0.0f, AL_FALSE, AL_TRUE, 0.0f, 0.0f, 0.5f, 2.0f,
1711 0.0f, -3.0f, 3.0f, device->Frequency);
1714 /* UpdateClockBase
1716 * Updates the device's base clock time with however many samples have been
1717 * done. This is used so frequency changes on the device don't cause the time
1718 * to jump forward or back. Must not be called while the device is running/
1719 * mixing.
1721 static inline void UpdateClockBase(ALCdevice *device)
1723 IncrementRef(&device->MixCount);
1724 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1725 device->SamplesDone = 0;
1726 IncrementRef(&device->MixCount);
1729 /* UpdateDeviceParams
1731 * Updates device parameters according to the attribute list (caller is
1732 * responsible for holding the list lock).
1734 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1736 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1737 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1738 ALCenum gainLimiter = device->Limiter ? ALC_TRUE : ALC_FALSE;
1739 const ALsizei old_sends = device->NumAuxSends;
1740 ALsizei new_sends = device->NumAuxSends;
1741 enum DevFmtChannels oldChans;
1742 enum DevFmtType oldType;
1743 ALboolean update_failed;
1744 ALCsizei hrtf_id = -1;
1745 ALCcontext *context;
1746 ALCuint oldFreq;
1747 FPUCtl oldMode;
1748 size_t size;
1749 ALCsizei i;
1750 int val;
1752 // Check for attributes
1753 if(device->Type == Loopback)
1755 ALCsizei numMono, numStereo, numSends;
1756 ALCenum alayout = AL_NONE;
1757 ALCenum ascale = AL_NONE;
1758 ALCenum schans = AL_NONE;
1759 ALCenum stype = AL_NONE;
1760 ALCsizei attrIdx = 0;
1761 ALCsizei aorder = 0;
1762 ALCuint freq = 0;
1764 if(!attrList)
1766 WARN("Missing attributes for loopback device\n");
1767 return ALC_INVALID_VALUE;
1770 numMono = device->NumMonoSources;
1771 numStereo = device->NumStereoSources;
1772 numSends = old_sends;
1774 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1775 while(attrList[attrIdx])
1777 switch(attrList[attrIdx])
1779 case ALC_FORMAT_CHANNELS_SOFT:
1780 schans = attrList[attrIdx + 1];
1781 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1782 if(!IsValidALCChannels(schans))
1783 return ALC_INVALID_VALUE;
1784 break;
1786 case ALC_FORMAT_TYPE_SOFT:
1787 stype = attrList[attrIdx + 1];
1788 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1789 if(!IsValidALCType(stype))
1790 return ALC_INVALID_VALUE;
1791 break;
1793 case ALC_FREQUENCY:
1794 freq = attrList[attrIdx + 1];
1795 TRACE_ATTR(ALC_FREQUENCY, freq);
1796 if(freq < MIN_OUTPUT_RATE)
1797 return ALC_INVALID_VALUE;
1798 break;
1800 case ALC_AMBISONIC_LAYOUT_SOFT:
1801 alayout = attrList[attrIdx + 1];
1802 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1803 if(!IsValidAmbiLayout(alayout))
1804 return ALC_INVALID_VALUE;
1805 break;
1807 case ALC_AMBISONIC_SCALING_SOFT:
1808 ascale = attrList[attrIdx + 1];
1809 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1810 if(!IsValidAmbiScaling(ascale))
1811 return ALC_INVALID_VALUE;
1812 break;
1814 case ALC_AMBISONIC_ORDER_SOFT:
1815 aorder = attrList[attrIdx + 1];
1816 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1817 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1818 return ALC_INVALID_VALUE;
1819 break;
1821 case ALC_MONO_SOURCES:
1822 numMono = attrList[attrIdx + 1];
1823 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1824 numMono = maxi(numMono, 0);
1825 break;
1827 case ALC_STEREO_SOURCES:
1828 numStereo = attrList[attrIdx + 1];
1829 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1830 numStereo = maxi(numStereo, 0);
1831 break;
1833 case ALC_MAX_AUXILIARY_SENDS:
1834 numSends = attrList[attrIdx + 1];
1835 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1836 numSends = clampi(numSends, 0, MAX_SENDS);
1837 break;
1839 case ALC_HRTF_SOFT:
1840 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1841 if(attrList[attrIdx + 1] == ALC_FALSE)
1842 hrtf_appreq = Hrtf_Disable;
1843 else if(attrList[attrIdx + 1] == ALC_TRUE)
1844 hrtf_appreq = Hrtf_Enable;
1845 else
1846 hrtf_appreq = Hrtf_Default;
1847 break;
1849 case ALC_HRTF_ID_SOFT:
1850 hrtf_id = attrList[attrIdx + 1];
1851 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1852 break;
1854 case ALC_OUTPUT_LIMITER_SOFT:
1855 gainLimiter = attrList[attrIdx + 1];
1856 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1857 break;
1859 default:
1860 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList[attrIdx],
1861 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1862 break;
1865 attrIdx += 2;
1867 #undef TRACE_ATTR
1869 if(!schans || !stype || !freq)
1871 WARN("Missing format for loopback device\n");
1872 return ALC_INVALID_VALUE;
1874 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1876 WARN("Missing ambisonic info for loopback device\n");
1877 return ALC_INVALID_VALUE;
1880 if((device->Flags&DEVICE_RUNNING))
1881 V0(device->Backend,stop)();
1882 device->Flags &= ~DEVICE_RUNNING;
1884 UpdateClockBase(device);
1886 device->Frequency = freq;
1887 device->FmtChans = schans;
1888 device->FmtType = stype;
1889 if(schans == ALC_BFORMAT3D_SOFT)
1891 device->AmbiOrder = aorder;
1892 device->AmbiLayout = alayout;
1893 device->AmbiScale = ascale;
1896 if(numMono > INT_MAX-numStereo)
1897 numMono = INT_MAX-numStereo;
1898 numMono += numStereo;
1899 if(ConfigValueInt(NULL, NULL, "sources", &numMono))
1901 if(numMono <= 0)
1902 numMono = 256;
1904 else
1905 numMono = maxi(numMono, 256);
1906 numStereo = mini(numStereo, numMono);
1907 numMono -= numStereo;
1908 device->SourcesMax = numMono + numStereo;
1910 device->NumMonoSources = numMono;
1911 device->NumStereoSources = numStereo;
1913 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1914 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1915 else
1916 new_sends = numSends;
1918 else if(attrList && attrList[0])
1920 ALCsizei numMono, numStereo, numSends;
1921 ALCsizei attrIdx = 0;
1922 ALCuint freq;
1924 /* If a context is already running on the device, stop playback so the
1925 * device attributes can be updated. */
1926 if((device->Flags&DEVICE_RUNNING))
1927 V0(device->Backend,stop)();
1928 device->Flags &= ~DEVICE_RUNNING;
1930 UpdateClockBase(device);
1932 freq = device->Frequency;
1933 numMono = device->NumMonoSources;
1934 numStereo = device->NumStereoSources;
1935 numSends = old_sends;
1937 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1938 while(attrList[attrIdx])
1940 switch(attrList[attrIdx])
1942 case ALC_FREQUENCY:
1943 freq = attrList[attrIdx + 1];
1944 TRACE_ATTR(ALC_FREQUENCY, freq);
1945 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1946 break;
1948 case ALC_MONO_SOURCES:
1949 numMono = attrList[attrIdx + 1];
1950 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1951 numMono = maxi(numMono, 0);
1952 break;
1954 case ALC_STEREO_SOURCES:
1955 numStereo = attrList[attrIdx + 1];
1956 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1957 numStereo = maxi(numStereo, 0);
1958 break;
1960 case ALC_MAX_AUXILIARY_SENDS:
1961 numSends = attrList[attrIdx + 1];
1962 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1963 numSends = clampi(numSends, 0, MAX_SENDS);
1964 break;
1966 case ALC_HRTF_SOFT:
1967 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1968 if(attrList[attrIdx + 1] == ALC_FALSE)
1969 hrtf_appreq = Hrtf_Disable;
1970 else if(attrList[attrIdx + 1] == ALC_TRUE)
1971 hrtf_appreq = Hrtf_Enable;
1972 else
1973 hrtf_appreq = Hrtf_Default;
1974 break;
1976 case ALC_HRTF_ID_SOFT:
1977 hrtf_id = attrList[attrIdx + 1];
1978 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1979 break;
1981 case ALC_OUTPUT_LIMITER_SOFT:
1982 gainLimiter = attrList[attrIdx + 1];
1983 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1984 break;
1986 default:
1987 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
1988 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1989 break;
1992 attrIdx += 2;
1994 #undef TRACE_ATTR
1996 ConfigValueUInt(alstr_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1997 freq = maxu(freq, MIN_OUTPUT_RATE);
1999 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
2000 device->Frequency;
2001 /* SSE and Neon do best with the update size being a multiple of 4 */
2002 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2003 device->UpdateSize = (device->UpdateSize+3)&~3;
2005 device->Frequency = freq;
2007 if(numMono > INT_MAX-numStereo)
2008 numMono = INT_MAX-numStereo;
2009 numMono += numStereo;
2010 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono))
2012 if(numMono <= 0)
2013 numMono = 256;
2015 else
2016 numMono = maxi(numMono, 256);
2017 numStereo = mini(numStereo, numMono);
2018 numMono -= numStereo;
2019 device->SourcesMax = numMono + numStereo;
2021 device->NumMonoSources = numMono;
2022 device->NumStereoSources = numStereo;
2024 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2025 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2026 else
2027 new_sends = numSends;
2030 if((device->Flags&DEVICE_RUNNING))
2031 return ALC_NO_ERROR;
2033 al_free(device->Uhj_Encoder);
2034 device->Uhj_Encoder = NULL;
2036 al_free(device->Bs2b);
2037 device->Bs2b = NULL;
2039 al_free(device->ChannelDelay[0].Buffer);
2040 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2042 device->ChannelDelay[i].Length = 0;
2043 device->ChannelDelay[i].Buffer = NULL;
2046 al_free(device->Dry.Buffer);
2047 device->Dry.Buffer = NULL;
2048 device->Dry.NumChannels = 0;
2049 device->FOAOut.Buffer = NULL;
2050 device->FOAOut.NumChannels = 0;
2051 device->RealOut.Buffer = NULL;
2052 device->RealOut.NumChannels = 0;
2054 UpdateClockBase(device);
2056 device->DitherSeed = DITHER_RNG_SEED;
2058 /*************************************************************************
2059 * Update device format request if HRTF is requested
2061 device->HrtfStatus = ALC_HRTF_DISABLED_SOFT;
2062 if(device->Type != Loopback)
2064 const char *hrtf;
2065 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2067 if(strcasecmp(hrtf, "true") == 0)
2068 hrtf_userreq = Hrtf_Enable;
2069 else if(strcasecmp(hrtf, "false") == 0)
2070 hrtf_userreq = Hrtf_Disable;
2071 else if(strcasecmp(hrtf, "auto") != 0)
2072 ERR("Unexpected hrtf value: %s\n", hrtf);
2075 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2077 struct Hrtf *hrtf = NULL;
2078 if(VECTOR_SIZE(device->HrtfList) == 0)
2080 VECTOR_DEINIT(device->HrtfList);
2081 device->HrtfList = EnumerateHrtf(device->DeviceName);
2083 if(VECTOR_SIZE(device->HrtfList) > 0)
2085 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
2086 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
2087 else
2088 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
2091 if(hrtf)
2093 device->FmtChans = DevFmtStereo;
2094 device->Frequency = hrtf->sampleRate;
2095 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2096 if(device->HrtfHandle)
2097 Hrtf_DecRef(device->HrtfHandle);
2098 device->HrtfHandle = hrtf;
2100 else
2102 hrtf_userreq = Hrtf_Default;
2103 hrtf_appreq = Hrtf_Disable;
2104 device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2109 oldFreq = device->Frequency;
2110 oldChans = device->FmtChans;
2111 oldType = device->FmtType;
2113 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2114 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2115 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2116 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2117 device->UpdateSize, device->NumUpdates
2120 if(V0(device->Backend,reset)() == ALC_FALSE)
2121 return ALC_INVALID_DEVICE;
2123 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2125 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2126 DevFmtChannelsString(device->FmtChans));
2127 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2129 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2131 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2132 DevFmtTypeString(device->FmtType));
2133 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2135 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2137 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2138 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2141 if((device->UpdateSize&3) != 0)
2143 if((CPUCapFlags&CPU_CAP_SSE))
2144 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2145 if((CPUCapFlags&CPU_CAP_NEON))
2146 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2149 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2150 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2151 device->Frequency, device->UpdateSize, device->NumUpdates
2154 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2155 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2156 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2158 /* Allocate extra channels for any post-filter output. */
2159 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2160 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2162 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2163 device->Dry.Buffer = al_calloc(16, size);
2164 if(!device->Dry.Buffer)
2166 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2167 return ALC_INVALID_DEVICE;
2170 if(device->RealOut.NumChannels != 0)
2171 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2172 device->FOAOut.NumChannels;
2173 else
2175 device->RealOut.Buffer = device->Dry.Buffer;
2176 device->RealOut.NumChannels = device->Dry.NumChannels;
2179 if(device->FOAOut.NumChannels != 0)
2180 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2181 else
2183 device->FOAOut.Buffer = device->Dry.Buffer;
2184 device->FOAOut.NumChannels = device->Dry.NumChannels;
2187 device->NumAuxSends = new_sends;
2188 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2189 device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2190 device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2192 device->DitherDepth = 0.0f;
2193 if(GetConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "dither", 1))
2195 ALint depth = 0;
2196 ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "dither-depth", &depth);
2197 if(depth <= 0)
2199 switch(device->FmtType)
2201 case DevFmtByte:
2202 case DevFmtUByte:
2203 depth = 8;
2204 break;
2205 case DevFmtShort:
2206 case DevFmtUShort:
2207 depth = 16;
2208 break;
2209 case DevFmtInt:
2210 case DevFmtUInt:
2211 case DevFmtFloat:
2212 break;
2215 else if(depth > 24)
2216 depth = 24;
2217 device->DitherDepth = (depth > 0) ? powf(2.0f, (ALfloat)(depth-1)) : 0.0f;
2219 if(!(device->DitherDepth > 0.0f))
2220 TRACE("Dithering disabled\n");
2221 else
2222 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device->DitherDepth)+1.0f,
2223 device->DitherDepth);
2225 if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
2226 gainLimiter = val ? ALC_TRUE : ALC_FALSE;
2227 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2228 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2229 * ALC_TRUE.
2231 if(gainLimiter != ALC_FALSE)
2233 if(!device->Limiter || device->Frequency != GetCompressorSampleRate(device->Limiter))
2235 al_free(device->Limiter);
2236 device->Limiter = CreateDeviceLimiter(device);
2239 else
2241 al_free(device->Limiter);
2242 device->Limiter = NULL;
2244 TRACE("Output limiter %s\n", device->Limiter ? "enabled" : "disabled");
2246 /* Need to delay returning failure until replacement Send arrays have been
2247 * allocated with the appropriate size.
2249 update_failed = AL_FALSE;
2250 SetMixerFPUMode(&oldMode);
2251 if(device->DefaultSlot)
2253 ALeffectslot *slot = device->DefaultSlot;
2254 ALeffectState *state = slot->Effect.State;
2256 state->OutBuffer = device->Dry.Buffer;
2257 state->OutChannels = device->Dry.NumChannels;
2258 if(V(state,deviceUpdate)(device) == AL_FALSE)
2259 update_failed = AL_TRUE;
2260 else
2261 UpdateEffectSlotProps(slot);
2264 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2265 while(context)
2267 ALsizei pos;
2269 WriteLock(&context->PropLock);
2270 LockUIntMapRead(&context->EffectSlotMap);
2271 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2273 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2274 ALeffectState *state = slot->Effect.State;
2276 state->OutBuffer = device->Dry.Buffer;
2277 state->OutChannels = device->Dry.NumChannels;
2278 if(V(state,deviceUpdate)(device) == AL_FALSE)
2279 update_failed = AL_TRUE;
2280 else
2281 UpdateEffectSlotProps(slot);
2283 UnlockUIntMapRead(&context->EffectSlotMap);
2285 LockUIntMapRead(&context->SourceMap);
2286 RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax);
2287 for(pos = 0;pos < context->SourceMap.size;pos++)
2289 ALsource *source = context->SourceMap.values[pos];
2291 if(old_sends != device->NumAuxSends)
2293 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2294 ALsizei s;
2296 memcpy(sends, source->Send,
2297 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2299 for(s = device->NumAuxSends;s < old_sends;s++)
2301 if(source->Send[s].Slot)
2302 DecrementRef(&source->Send[s].Slot->ref);
2303 source->Send[s].Slot = NULL;
2305 al_free(source->Send);
2306 source->Send = sends;
2307 for(s = old_sends;s < device->NumAuxSends;s++)
2309 source->Send[s].Slot = NULL;
2310 source->Send[s].Gain = 1.0f;
2311 source->Send[s].GainHF = 1.0f;
2312 source->Send[s].HFReference = LOWPASSFREQREF;
2313 source->Send[s].GainLF = 1.0f;
2314 source->Send[s].LFReference = HIGHPASSFREQREF;
2318 ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
2320 AllocateVoices(context, context->MaxVoices, old_sends);
2321 for(pos = 0;pos < context->VoiceCount;pos++)
2323 ALvoice *voice = context->Voices[pos];
2324 struct ALvoiceProps *props;
2326 /* Clear any pre-existing voice property structs, in case the
2327 * number of auxiliary sends changed. Active sources will have
2328 * updates respecified in UpdateAllSourceProps.
2330 props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed);
2331 al_free(props);
2333 props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
2334 while(props)
2336 struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
2337 al_free(props);
2338 props = next;
2341 if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
2342 continue;
2344 if(device->AvgSpeakerDist > 0.0f)
2346 /* Reinitialize the NFC filters for new parameters. */
2347 ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
2348 (device->AvgSpeakerDist * device->Frequency);
2349 for(i = 0;i < voice->NumChannels;i++)
2351 NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1);
2352 NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1);
2353 NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1);
2357 UnlockUIntMapRead(&context->SourceMap);
2359 UpdateListenerProps(context);
2360 UpdateAllSourceProps(context);
2361 WriteUnlock(&context->PropLock);
2363 context = context->next;
2365 RestoreFPUMode(&oldMode);
2366 if(update_failed)
2367 return ALC_INVALID_DEVICE;
2369 if(!(device->Flags&DEVICE_PAUSED))
2371 if(V0(device->Backend,start)() == ALC_FALSE)
2372 return ALC_INVALID_DEVICE;
2373 device->Flags |= DEVICE_RUNNING;
2376 return ALC_NO_ERROR;
2379 /* FreeDevice
2381 * Frees the device structure, and destroys any objects the app failed to
2382 * delete. Called once there's no more references on the device.
2384 static ALCvoid FreeDevice(ALCdevice *device)
2386 ALsizei i;
2388 TRACE("%p\n", device);
2390 V0(device->Backend,close)();
2391 DELETE_OBJ(device->Backend);
2392 device->Backend = NULL;
2394 almtx_destroy(&device->BackendLock);
2396 if(device->DefaultSlot)
2398 DeinitEffectSlot(device->DefaultSlot);
2399 device->DefaultSlot = NULL;
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->Limiter);
2447 device->Limiter = NULL;
2449 al_free(device->ChannelDelay[0].Buffer);
2450 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2452 device->ChannelDelay[i].Gain = 1.0f;
2453 device->ChannelDelay[i].Length = 0;
2454 device->ChannelDelay[i].Buffer = NULL;
2457 AL_STRING_DEINIT(device->DeviceName);
2459 al_free(device->Dry.Buffer);
2460 device->Dry.Buffer = NULL;
2461 device->Dry.NumChannels = 0;
2462 device->FOAOut.Buffer = NULL;
2463 device->FOAOut.NumChannels = 0;
2464 device->RealOut.Buffer = NULL;
2465 device->RealOut.NumChannels = 0;
2467 al_free(device);
2471 void ALCdevice_IncRef(ALCdevice *device)
2473 uint ref;
2474 ref = IncrementRef(&device->ref);
2475 TRACEREF("%p increasing refcount to %u\n", device, ref);
2478 void ALCdevice_DecRef(ALCdevice *device)
2480 uint ref;
2481 ref = DecrementRef(&device->ref);
2482 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2483 if(ref == 0) FreeDevice(device);
2486 /* VerifyDevice
2488 * Checks if the device handle is valid, and increments its ref count if so.
2490 static ALCboolean VerifyDevice(ALCdevice **device)
2492 ALCdevice *tmpDevice;
2494 LockLists();
2495 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2496 while(tmpDevice)
2498 if(tmpDevice == *device)
2500 ALCdevice_IncRef(tmpDevice);
2501 UnlockLists();
2502 return ALC_TRUE;
2504 tmpDevice = tmpDevice->next;
2506 UnlockLists();
2508 *device = NULL;
2509 return ALC_FALSE;
2513 /* InitContext
2515 * Initializes context fields
2517 static ALvoid InitContext(ALCcontext *Context)
2519 ALlistener *listener = Context->Listener;
2520 struct ALeffectslotArray *auxslots;
2522 //Initialise listener
2523 listener->Gain = 1.0f;
2524 listener->MetersPerUnit = 1.0f;
2525 listener->Position[0] = 0.0f;
2526 listener->Position[1] = 0.0f;
2527 listener->Position[2] = 0.0f;
2528 listener->Velocity[0] = 0.0f;
2529 listener->Velocity[1] = 0.0f;
2530 listener->Velocity[2] = 0.0f;
2531 listener->Forward[0] = 0.0f;
2532 listener->Forward[1] = 0.0f;
2533 listener->Forward[2] = -1.0f;
2534 listener->Up[0] = 0.0f;
2535 listener->Up[1] = 1.0f;
2536 listener->Up[2] = 0.0f;
2538 aluMatrixfSet(&listener->Params.Matrix,
2539 1.0f, 0.0f, 0.0f, 0.0f,
2540 0.0f, 1.0f, 0.0f, 0.0f,
2541 0.0f, 0.0f, 1.0f, 0.0f,
2542 0.0f, 0.0f, 0.0f, 1.0f
2544 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2545 listener->Params.Gain = 1.0f;
2546 listener->Params.MetersPerUnit = 1.0f;
2547 listener->Params.DopplerFactor = 1.0f;
2548 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2550 ATOMIC_INIT(&listener->Update, NULL);
2551 ATOMIC_INIT(&listener->FreeList, NULL);
2553 //Validate Context
2554 InitRef(&Context->UpdateCount, 0);
2555 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2556 Context->GainBoost = 1.0f;
2557 RWLockInit(&Context->PropLock);
2558 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2559 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2560 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2562 auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray));
2563 auxslots->count = 0;
2564 ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots);
2566 //Set globals
2567 Context->DistanceModel = DefaultDistanceModel;
2568 Context->SourceDistanceModel = AL_FALSE;
2569 Context->DopplerFactor = 1.0f;
2570 Context->DopplerVelocity = 1.0f;
2571 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2572 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2574 Context->ExtensionList = alExtList;
2578 /* FreeContext
2580 * Cleans up the context, and destroys any remaining objects the app failed to
2581 * delete. Called once there's no more references on the context.
2583 static void FreeContext(ALCcontext *context)
2585 ALlistener *listener = context->Listener;
2586 struct ALeffectslotArray *auxslots;
2587 struct ALlistenerProps *lprops;
2588 size_t count;
2589 ALsizei i;
2591 TRACE("%p\n", context);
2593 auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
2594 al_free(auxslots);
2596 if(context->SourceMap.size > 0)
2598 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2599 (context->SourceMap.size==1)?"":"s");
2600 ReleaseALSources(context);
2602 ResetUIntMap(&context->SourceMap);
2604 if(context->EffectSlotMap.size > 0)
2606 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2607 (context->EffectSlotMap.size==1)?"":"s");
2608 ReleaseALAuxiliaryEffectSlots(context);
2610 ResetUIntMap(&context->EffectSlotMap);
2612 for(i = 0;i < context->VoiceCount;i++)
2613 DeinitVoice(context->Voices[i]);
2614 al_free(context->Voices);
2615 context->Voices = NULL;
2616 context->VoiceCount = 0;
2617 context->MaxVoices = 0;
2619 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2621 TRACE("Freed unapplied listener update %p\n", lprops);
2622 al_free(lprops);
2624 count = 0;
2625 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
2626 while(lprops)
2628 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2629 al_free(lprops);
2630 lprops = next;
2631 ++count;
2633 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2635 ALCdevice_DecRef(context->Device);
2636 context->Device = NULL;
2638 //Invalidate context
2639 memset(context, 0, sizeof(ALCcontext));
2640 al_free(context);
2643 /* ReleaseContext
2645 * Removes the context reference from the given device and removes it from
2646 * being current on the running thread or globally. Returns true if other
2647 * contexts still exist on the device.
2649 static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
2651 ALCcontext *origctx, *newhead;
2652 bool ret = true;
2654 if(altss_get(LocalContext) == context)
2656 WARN("%p released while current on thread\n", context);
2657 altss_set(LocalContext, NULL);
2658 ALCcontext_DecRef(context);
2661 origctx = context;
2662 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
2663 ALCcontext_DecRef(context);
2665 ALCdevice_Lock(device);
2666 origctx = context;
2667 newhead = context->next;
2668 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
2670 ALCcontext *volatile*list = &origctx->next;
2671 while(*list)
2673 if(*list == context)
2675 *list = (*list)->next;
2676 break;
2678 list = &(*list)->next;
2681 else
2682 ret = !!newhead;
2683 ALCdevice_Unlock(device);
2685 ALCcontext_DecRef(context);
2686 return ret;
2689 void ALCcontext_IncRef(ALCcontext *context)
2691 uint ref = IncrementRef(&context->ref);
2692 TRACEREF("%p increasing refcount to %u\n", context, ref);
2695 void ALCcontext_DecRef(ALCcontext *context)
2697 uint ref = DecrementRef(&context->ref);
2698 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2699 if(ref == 0) FreeContext(context);
2702 static void ReleaseThreadCtx(void *ptr)
2704 ALCcontext *context = ptr;
2705 uint ref = DecrementRef(&context->ref);
2706 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2707 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2710 /* VerifyContext
2712 * Checks that the given context is valid, and increments its reference count.
2714 static ALCboolean VerifyContext(ALCcontext **context)
2716 ALCdevice *dev;
2718 LockLists();
2719 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2720 while(dev)
2722 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2723 while(ctx)
2725 if(ctx == *context)
2727 ALCcontext_IncRef(ctx);
2728 UnlockLists();
2729 return ALC_TRUE;
2731 ctx = ctx->next;
2733 dev = dev->next;
2735 UnlockLists();
2737 *context = NULL;
2738 return ALC_FALSE;
2742 /* GetContextRef
2744 * Returns the currently active context for this thread, and adds a reference
2745 * without locking it.
2747 ALCcontext *GetContextRef(void)
2749 ALCcontext *context;
2751 context = altss_get(LocalContext);
2752 if(context)
2753 ALCcontext_IncRef(context);
2754 else
2756 LockLists();
2757 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2758 if(context)
2759 ALCcontext_IncRef(context);
2760 UnlockLists();
2763 return context;
2767 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2769 ALCdevice *device = context->Device;
2770 ALsizei num_sends = device->NumAuxSends;
2771 struct ALvoiceProps *props;
2772 size_t sizeof_props;
2773 size_t sizeof_voice;
2774 ALvoice **voices;
2775 ALvoice *voice;
2776 ALsizei v = 0;
2777 size_t size;
2779 if(num_voices == context->MaxVoices && num_sends == old_sends)
2780 return;
2782 /* Allocate the voice pointers, voices, and the voices' stored source
2783 * property set (including the dynamically-sized Send[] array) in one
2784 * chunk.
2786 sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
2787 sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
2788 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2790 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2791 /* The voice and property objects are stored interleaved since they're
2792 * paired together.
2794 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2795 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2797 if(context->Voices)
2799 const ALsizei v_count = mini(context->VoiceCount, num_voices);
2800 const ALsizei s_count = mini(old_sends, num_sends);
2802 for(;v < v_count;v++)
2804 ALvoice *old_voice = context->Voices[v];
2805 ALsizei i;
2807 /* Copy the old voice data and source property set to the new
2808 * storage.
2810 *voice = *old_voice;
2811 for(i = 0;i < s_count;i++)
2812 voice->Send[i] = old_voice->Send[i];
2813 *props = *(old_voice->Props);
2814 for(i = 0;i < s_count;i++)
2815 props->Send[i] = old_voice->Props->Send[i];
2817 /* Set this voice's property set pointer and voice reference. */
2818 voice->Props = props;
2819 voices[v] = voice;
2821 /* Increment pointers to the next storage space. */
2822 voice = (ALvoice*)((char*)props + sizeof_props);
2823 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2825 /* Deinit any left over voices that weren't copied over to the new
2826 * array. NOTE: If this does anything, v equals num_voices and
2827 * num_voices is less than VoiceCount, so the following loop won't do
2828 * anything.
2830 for(;v < context->VoiceCount;v++)
2831 DeinitVoice(context->Voices[v]);
2833 /* Finish setting the voices' property set pointers and references. */
2834 for(;v < num_voices;v++)
2836 ATOMIC_INIT(&voice->Update, NULL);
2837 ATOMIC_INIT(&voice->FreeList, NULL);
2839 voice->Props = props;
2840 voices[v] = voice;
2842 voice = (ALvoice*)((char*)props + sizeof_props);
2843 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2846 al_free(context->Voices);
2847 context->Voices = voices;
2848 context->MaxVoices = num_voices;
2849 context->VoiceCount = mini(context->VoiceCount, num_voices);
2853 /************************************************
2854 * Standard ALC functions
2855 ************************************************/
2857 /* alcGetError
2859 * Return last ALC generated error code for the given device
2861 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2863 ALCenum errorCode;
2865 if(VerifyDevice(&device))
2867 errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
2868 ALCdevice_DecRef(device);
2870 else
2871 errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
2873 return errorCode;
2877 /* alcSuspendContext
2879 * Suspends updates for the given context
2881 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2883 if(!SuspendDefers)
2884 return;
2886 if(!VerifyContext(&context))
2887 alcSetError(NULL, ALC_INVALID_CONTEXT);
2888 else
2890 ALCcontext_DeferUpdates(context);
2891 ALCcontext_DecRef(context);
2895 /* alcProcessContext
2897 * Resumes processing updates for the given context
2899 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2901 if(!SuspendDefers)
2902 return;
2904 if(!VerifyContext(&context))
2905 alcSetError(NULL, ALC_INVALID_CONTEXT);
2906 else
2908 ALCcontext_ProcessUpdates(context);
2909 ALCcontext_DecRef(context);
2914 /* alcGetString
2916 * Returns information about the device, and error strings
2918 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2920 const ALCchar *value = NULL;
2922 switch(param)
2924 case ALC_NO_ERROR:
2925 value = alcNoError;
2926 break;
2928 case ALC_INVALID_ENUM:
2929 value = alcErrInvalidEnum;
2930 break;
2932 case ALC_INVALID_VALUE:
2933 value = alcErrInvalidValue;
2934 break;
2936 case ALC_INVALID_DEVICE:
2937 value = alcErrInvalidDevice;
2938 break;
2940 case ALC_INVALID_CONTEXT:
2941 value = alcErrInvalidContext;
2942 break;
2944 case ALC_OUT_OF_MEMORY:
2945 value = alcErrOutOfMemory;
2946 break;
2948 case ALC_DEVICE_SPECIFIER:
2949 value = alcDefaultName;
2950 break;
2952 case ALC_ALL_DEVICES_SPECIFIER:
2953 if(VerifyDevice(&Device))
2955 value = alstr_get_cstr(Device->DeviceName);
2956 ALCdevice_DecRef(Device);
2958 else
2960 ProbeAllDevicesList();
2961 value = alstr_get_cstr(alcAllDevicesList);
2963 break;
2965 case ALC_CAPTURE_DEVICE_SPECIFIER:
2966 if(VerifyDevice(&Device))
2968 value = alstr_get_cstr(Device->DeviceName);
2969 ALCdevice_DecRef(Device);
2971 else
2973 ProbeCaptureDeviceList();
2974 value = alstr_get_cstr(alcCaptureDeviceList);
2976 break;
2978 /* Default devices are always first in the list */
2979 case ALC_DEFAULT_DEVICE_SPECIFIER:
2980 value = alcDefaultName;
2981 break;
2983 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2984 if(alstr_empty(alcAllDevicesList))
2985 ProbeAllDevicesList();
2987 VerifyDevice(&Device);
2989 free(alcDefaultAllDevicesSpecifier);
2990 alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
2991 if(!alcDefaultAllDevicesSpecifier)
2992 alcSetError(Device, ALC_OUT_OF_MEMORY);
2994 value = alcDefaultAllDevicesSpecifier;
2995 if(Device) ALCdevice_DecRef(Device);
2996 break;
2998 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2999 if(alstr_empty(alcCaptureDeviceList))
3000 ProbeCaptureDeviceList();
3002 VerifyDevice(&Device);
3004 free(alcCaptureDefaultDeviceSpecifier);
3005 alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
3006 if(!alcCaptureDefaultDeviceSpecifier)
3007 alcSetError(Device, ALC_OUT_OF_MEMORY);
3009 value = alcCaptureDefaultDeviceSpecifier;
3010 if(Device) ALCdevice_DecRef(Device);
3011 break;
3013 case ALC_EXTENSIONS:
3014 if(!VerifyDevice(&Device))
3015 value = alcNoDeviceExtList;
3016 else
3018 value = alcExtensionList;
3019 ALCdevice_DecRef(Device);
3021 break;
3023 case ALC_HRTF_SPECIFIER_SOFT:
3024 if(!VerifyDevice(&Device))
3025 alcSetError(NULL, ALC_INVALID_DEVICE);
3026 else
3028 almtx_lock(&Device->BackendLock);
3029 value = (Device->HrtfHandle ? alstr_get_cstr(Device->HrtfName) : "");
3030 almtx_unlock(&Device->BackendLock);
3031 ALCdevice_DecRef(Device);
3033 break;
3035 default:
3036 VerifyDevice(&Device);
3037 alcSetError(Device, ALC_INVALID_ENUM);
3038 if(Device) ALCdevice_DecRef(Device);
3039 break;
3042 return value;
3046 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
3048 if(device->Type == Loopback && device->FmtChans == DevFmtAmbi3D)
3049 return 25;
3050 return 19;
3053 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3055 ALCsizei i;
3057 if(size <= 0 || values == NULL)
3059 alcSetError(device, ALC_INVALID_VALUE);
3060 return 0;
3063 if(!device)
3065 switch(param)
3067 case ALC_MAJOR_VERSION:
3068 values[0] = alcMajorVersion;
3069 return 1;
3070 case ALC_MINOR_VERSION:
3071 values[0] = alcMinorVersion;
3072 return 1;
3074 case ALC_ATTRIBUTES_SIZE:
3075 case ALC_ALL_ATTRIBUTES:
3076 case ALC_FREQUENCY:
3077 case ALC_REFRESH:
3078 case ALC_SYNC:
3079 case ALC_MONO_SOURCES:
3080 case ALC_STEREO_SOURCES:
3081 case ALC_CAPTURE_SAMPLES:
3082 case ALC_FORMAT_CHANNELS_SOFT:
3083 case ALC_FORMAT_TYPE_SOFT:
3084 case ALC_AMBISONIC_LAYOUT_SOFT:
3085 case ALC_AMBISONIC_SCALING_SOFT:
3086 case ALC_AMBISONIC_ORDER_SOFT:
3087 alcSetError(NULL, ALC_INVALID_DEVICE);
3088 return 0;
3090 default:
3091 alcSetError(NULL, ALC_INVALID_ENUM);
3092 return 0;
3094 return 0;
3097 if(device->Type == Capture)
3099 switch(param)
3101 case ALC_CAPTURE_SAMPLES:
3102 almtx_lock(&device->BackendLock);
3103 values[0] = V0(device->Backend,availableSamples)();
3104 almtx_unlock(&device->BackendLock);
3105 return 1;
3107 case ALC_CONNECTED:
3108 values[0] = device->Connected;
3109 return 1;
3111 default:
3112 alcSetError(device, ALC_INVALID_ENUM);
3113 return 0;
3115 return 0;
3118 /* render device */
3119 switch(param)
3121 case ALC_MAJOR_VERSION:
3122 values[0] = alcMajorVersion;
3123 return 1;
3125 case ALC_MINOR_VERSION:
3126 values[0] = alcMinorVersion;
3127 return 1;
3129 case ALC_EFX_MAJOR_VERSION:
3130 values[0] = alcEFXMajorVersion;
3131 return 1;
3133 case ALC_EFX_MINOR_VERSION:
3134 values[0] = alcEFXMinorVersion;
3135 return 1;
3137 case ALC_ATTRIBUTES_SIZE:
3138 values[0] = NumAttrsForDevice(device);
3139 return 1;
3141 case ALC_ALL_ATTRIBUTES:
3142 if(size < NumAttrsForDevice(device))
3144 alcSetError(device, ALC_INVALID_VALUE);
3145 return 0;
3148 i = 0;
3149 almtx_lock(&device->BackendLock);
3150 values[i++] = ALC_FREQUENCY;
3151 values[i++] = device->Frequency;
3153 if(device->Type != Loopback)
3155 values[i++] = ALC_REFRESH;
3156 values[i++] = device->Frequency / device->UpdateSize;
3158 values[i++] = ALC_SYNC;
3159 values[i++] = ALC_FALSE;
3161 else
3163 if(device->FmtChans == DevFmtAmbi3D)
3165 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3166 values[i++] = device->AmbiLayout;
3168 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3169 values[i++] = device->AmbiScale;
3171 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3172 values[i++] = device->AmbiOrder;
3175 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3176 values[i++] = device->FmtChans;
3178 values[i++] = ALC_FORMAT_TYPE_SOFT;
3179 values[i++] = device->FmtType;
3182 values[i++] = ALC_MONO_SOURCES;
3183 values[i++] = device->NumMonoSources;
3185 values[i++] = ALC_STEREO_SOURCES;
3186 values[i++] = device->NumStereoSources;
3188 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3189 values[i++] = device->NumAuxSends;
3191 values[i++] = ALC_HRTF_SOFT;
3192 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3194 values[i++] = ALC_HRTF_STATUS_SOFT;
3195 values[i++] = device->HrtfStatus;
3197 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3198 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3199 almtx_unlock(&device->BackendLock);
3201 values[i++] = 0;
3202 return i;
3204 case ALC_FREQUENCY:
3205 values[0] = device->Frequency;
3206 return 1;
3208 case ALC_REFRESH:
3209 if(device->Type == Loopback)
3211 alcSetError(device, ALC_INVALID_DEVICE);
3212 return 0;
3214 almtx_lock(&device->BackendLock);
3215 values[0] = device->Frequency / device->UpdateSize;
3216 almtx_unlock(&device->BackendLock);
3217 return 1;
3219 case ALC_SYNC:
3220 if(device->Type == Loopback)
3222 alcSetError(device, ALC_INVALID_DEVICE);
3223 return 0;
3225 values[0] = ALC_FALSE;
3226 return 1;
3228 case ALC_FORMAT_CHANNELS_SOFT:
3229 if(device->Type != Loopback)
3231 alcSetError(device, ALC_INVALID_DEVICE);
3232 return 0;
3234 values[0] = device->FmtChans;
3235 return 1;
3237 case ALC_FORMAT_TYPE_SOFT:
3238 if(device->Type != Loopback)
3240 alcSetError(device, ALC_INVALID_DEVICE);
3241 return 0;
3243 values[0] = device->FmtType;
3244 return 1;
3246 case ALC_AMBISONIC_LAYOUT_SOFT:
3247 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3249 alcSetError(device, ALC_INVALID_DEVICE);
3250 return 0;
3252 values[0] = device->AmbiLayout;
3253 return 1;
3255 case ALC_AMBISONIC_SCALING_SOFT:
3256 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3258 alcSetError(device, ALC_INVALID_DEVICE);
3259 return 0;
3261 values[0] = device->AmbiScale;
3262 return 1;
3264 case ALC_AMBISONIC_ORDER_SOFT:
3265 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3267 alcSetError(device, ALC_INVALID_DEVICE);
3268 return 0;
3270 values[0] = device->AmbiOrder;
3271 return 1;
3273 case ALC_MONO_SOURCES:
3274 values[0] = device->NumMonoSources;
3275 return 1;
3277 case ALC_STEREO_SOURCES:
3278 values[0] = device->NumStereoSources;
3279 return 1;
3281 case ALC_MAX_AUXILIARY_SENDS:
3282 values[0] = device->NumAuxSends;
3283 return 1;
3285 case ALC_CONNECTED:
3286 values[0] = device->Connected;
3287 return 1;
3289 case ALC_HRTF_SOFT:
3290 values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3291 return 1;
3293 case ALC_HRTF_STATUS_SOFT:
3294 values[0] = device->HrtfStatus;
3295 return 1;
3297 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3298 almtx_lock(&device->BackendLock);
3299 FreeHrtfList(&device->HrtfList);
3300 device->HrtfList = EnumerateHrtf(device->DeviceName);
3301 values[0] = (ALCint)VECTOR_SIZE(device->HrtfList);
3302 almtx_unlock(&device->BackendLock);
3303 return 1;
3305 case ALC_OUTPUT_LIMITER_SOFT:
3306 values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3307 return 1;
3309 default:
3310 alcSetError(device, ALC_INVALID_ENUM);
3311 return 0;
3313 return 0;
3316 /* alcGetIntegerv
3318 * Returns information about the device and the version of OpenAL
3320 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3322 VerifyDevice(&device);
3323 if(size <= 0 || values == NULL)
3324 alcSetError(device, ALC_INVALID_VALUE);
3325 else
3326 GetIntegerv(device, param, size, values);
3327 if(device) ALCdevice_DecRef(device);
3330 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3332 ALCint *ivals;
3333 ALsizei i;
3335 VerifyDevice(&device);
3336 if(size <= 0 || values == NULL)
3337 alcSetError(device, ALC_INVALID_VALUE);
3338 else if(!device || device->Type == Capture)
3340 ivals = malloc(size * sizeof(ALCint));
3341 size = GetIntegerv(device, pname, size, ivals);
3342 for(i = 0;i < size;i++)
3343 values[i] = ivals[i];
3344 free(ivals);
3346 else /* render device */
3348 ClockLatency clock;
3349 ALuint64 basecount;
3350 ALuint samplecount;
3351 ALuint refcount;
3353 switch(pname)
3355 case ALC_ATTRIBUTES_SIZE:
3356 *values = NumAttrsForDevice(device)+4;
3357 break;
3359 case ALC_ALL_ATTRIBUTES:
3360 if(size < NumAttrsForDevice(device)+4)
3361 alcSetError(device, ALC_INVALID_VALUE);
3362 else
3364 i = 0;
3365 almtx_lock(&device->BackendLock);
3366 values[i++] = ALC_FREQUENCY;
3367 values[i++] = device->Frequency;
3369 if(device->Type != Loopback)
3371 values[i++] = ALC_REFRESH;
3372 values[i++] = device->Frequency / device->UpdateSize;
3374 values[i++] = ALC_SYNC;
3375 values[i++] = ALC_FALSE;
3377 else
3379 if(device->FmtChans == DevFmtAmbi3D)
3381 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3382 values[i++] = device->AmbiLayout;
3384 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3385 values[i++] = device->AmbiScale;
3387 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3388 values[i++] = device->AmbiOrder;
3391 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3392 values[i++] = device->FmtChans;
3394 values[i++] = ALC_FORMAT_TYPE_SOFT;
3395 values[i++] = device->FmtType;
3398 values[i++] = ALC_MONO_SOURCES;
3399 values[i++] = device->NumMonoSources;
3401 values[i++] = ALC_STEREO_SOURCES;
3402 values[i++] = device->NumStereoSources;
3404 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3405 values[i++] = device->NumAuxSends;
3407 values[i++] = ALC_HRTF_SOFT;
3408 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3410 values[i++] = ALC_HRTF_STATUS_SOFT;
3411 values[i++] = device->HrtfStatus;
3413 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3414 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3416 clock = V0(device->Backend,getClockLatency)();
3417 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3418 values[i++] = clock.ClockTime;
3420 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3421 values[i++] = clock.Latency;
3422 almtx_unlock(&device->BackendLock);
3424 values[i++] = 0;
3426 break;
3428 case ALC_DEVICE_CLOCK_SOFT:
3429 almtx_lock(&device->BackendLock);
3430 do {
3431 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3432 althrd_yield();
3433 basecount = device->ClockBase;
3434 samplecount = device->SamplesDone;
3435 } while(refcount != ReadRef(&device->MixCount));
3436 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3437 almtx_unlock(&device->BackendLock);
3438 break;
3440 case ALC_DEVICE_LATENCY_SOFT:
3441 almtx_lock(&device->BackendLock);
3442 clock = V0(device->Backend,getClockLatency)();
3443 almtx_unlock(&device->BackendLock);
3444 *values = clock.Latency;
3445 break;
3447 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3448 if(size < 2)
3449 alcSetError(device, ALC_INVALID_VALUE);
3450 else
3452 almtx_lock(&device->BackendLock);
3453 clock = V0(device->Backend,getClockLatency)();
3454 almtx_unlock(&device->BackendLock);
3455 values[0] = clock.ClockTime;
3456 values[1] = clock.Latency;
3458 break;
3460 default:
3461 ivals = malloc(size * sizeof(ALCint));
3462 size = GetIntegerv(device, pname, size, ivals);
3463 for(i = 0;i < size;i++)
3464 values[i] = ivals[i];
3465 free(ivals);
3466 break;
3469 if(device)
3470 ALCdevice_DecRef(device);
3474 /* alcIsExtensionPresent
3476 * Determines if there is support for a particular extension
3478 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3480 ALCboolean bResult = ALC_FALSE;
3482 VerifyDevice(&device);
3484 if(!extName)
3485 alcSetError(device, ALC_INVALID_VALUE);
3486 else
3488 size_t len = strlen(extName);
3489 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3490 while(ptr && *ptr)
3492 if(strncasecmp(ptr, extName, len) == 0 &&
3493 (ptr[len] == '\0' || isspace(ptr[len])))
3495 bResult = ALC_TRUE;
3496 break;
3498 if((ptr=strchr(ptr, ' ')) != NULL)
3500 do {
3501 ++ptr;
3502 } while(isspace(*ptr));
3506 if(device)
3507 ALCdevice_DecRef(device);
3508 return bResult;
3512 /* alcGetProcAddress
3514 * Retrieves the function address for a particular extension function
3516 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3518 ALCvoid *ptr = NULL;
3520 if(!funcName)
3522 VerifyDevice(&device);
3523 alcSetError(device, ALC_INVALID_VALUE);
3524 if(device) ALCdevice_DecRef(device);
3526 else
3528 size_t i = 0;
3529 for(i = 0;i < COUNTOF(alcFunctions);i++)
3531 if(strcmp(alcFunctions[i].funcName, funcName) == 0)
3533 ptr = alcFunctions[i].address;
3534 break;
3539 return ptr;
3543 /* alcGetEnumValue
3545 * Get the value for a particular ALC enumeration name
3547 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3549 ALCenum val = 0;
3551 if(!enumName)
3553 VerifyDevice(&device);
3554 alcSetError(device, ALC_INVALID_VALUE);
3555 if(device) ALCdevice_DecRef(device);
3557 else
3559 size_t i = 0;
3560 for(i = 0;i < COUNTOF(alcEnumerations);i++)
3562 if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
3564 val = alcEnumerations[i].value;
3565 break;
3570 return val;
3574 /* alcCreateContext
3576 * Create and attach a context to the given device.
3578 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3580 ALCcontext *ALContext;
3581 ALfloat valf;
3582 ALCenum err;
3584 /* Explicitly hold the list lock while taking the BackendLock in case the
3585 * device is asynchronously destropyed, to ensure this new context is
3586 * properly cleaned up after being made.
3588 LockLists();
3589 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3591 UnlockLists();
3592 alcSetError(device, ALC_INVALID_DEVICE);
3593 if(device) ALCdevice_DecRef(device);
3594 return NULL;
3596 almtx_lock(&device->BackendLock);
3597 UnlockLists();
3599 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3601 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3602 if(!ALContext)
3604 almtx_unlock(&device->BackendLock);
3606 alcSetError(device, ALC_OUT_OF_MEMORY);
3607 ALCdevice_DecRef(device);
3608 return NULL;
3611 InitRef(&ALContext->ref, 1);
3612 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3614 ALContext->Voices = NULL;
3615 ALContext->VoiceCount = 0;
3616 ALContext->MaxVoices = 0;
3617 ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL);
3618 ALContext->Device = device;
3620 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3622 almtx_unlock(&device->BackendLock);
3624 al_free(ALContext->Voices);
3625 ALContext->Voices = NULL;
3627 al_free(ALContext);
3628 ALContext = NULL;
3630 alcSetError(device, err);
3631 if(err == ALC_INVALID_DEVICE)
3633 V0(device->Backend,lock)();
3634 aluHandleDisconnect(device);
3635 V0(device->Backend,unlock)();
3637 ALCdevice_DecRef(device);
3638 return NULL;
3640 AllocateVoices(ALContext, 256, device->NumAuxSends);
3642 ALCdevice_IncRef(ALContext->Device);
3643 InitContext(ALContext);
3645 if(ConfigValueFloat(alstr_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3647 if(!isfinite(valf))
3648 ERR("volume-adjust must be finite: %f\n", valf);
3649 else
3651 ALfloat db = clampf(valf, -24.0f, 24.0f);
3652 if(db != valf)
3653 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3654 ALContext->GainBoost = powf(10.0f, db/20.0f);
3655 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3658 UpdateListenerProps(ALContext);
3661 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3662 do {
3663 ALContext->next = head;
3664 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
3665 ALContext) == 0);
3667 almtx_unlock(&device->BackendLock);
3669 ALCdevice_DecRef(device);
3671 TRACE("Created context %p\n", ALContext);
3672 return ALContext;
3675 /* alcDestroyContext
3677 * Remove a context from its device
3679 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3681 ALCdevice *Device;
3683 LockLists();
3684 if(!VerifyContext(&context))
3686 UnlockLists();
3687 alcSetError(NULL, ALC_INVALID_CONTEXT);
3688 return;
3691 Device = context->Device;
3692 if(Device)
3694 almtx_lock(&Device->BackendLock);
3695 if(!ReleaseContext(context, Device))
3697 V0(Device->Backend,stop)();
3698 Device->Flags &= ~DEVICE_RUNNING;
3700 almtx_unlock(&Device->BackendLock);
3702 UnlockLists();
3704 ALCcontext_DecRef(context);
3708 /* alcGetCurrentContext
3710 * Returns the currently active context on the calling thread
3712 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3714 ALCcontext *Context = altss_get(LocalContext);
3715 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3716 return Context;
3719 /* alcGetThreadContext
3721 * Returns the currently active thread-local context
3723 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3725 return altss_get(LocalContext);
3729 /* alcMakeContextCurrent
3731 * Makes the given context the active process-wide context, and removes the
3732 * thread-local context for the calling thread.
3734 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3736 /* context must be valid or NULL */
3737 if(context && !VerifyContext(&context))
3739 alcSetError(NULL, ALC_INVALID_CONTEXT);
3740 return ALC_FALSE;
3742 /* context's reference count is already incremented */
3743 context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
3744 if(context) ALCcontext_DecRef(context);
3746 if((context=altss_get(LocalContext)) != NULL)
3748 altss_set(LocalContext, NULL);
3749 ALCcontext_DecRef(context);
3752 return ALC_TRUE;
3755 /* alcSetThreadContext
3757 * Makes the given context the active context for the current thread
3759 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3761 ALCcontext *old;
3763 /* context must be valid or NULL */
3764 if(context && !VerifyContext(&context))
3766 alcSetError(NULL, ALC_INVALID_CONTEXT);
3767 return ALC_FALSE;
3769 /* context's reference count is already incremented */
3770 old = altss_get(LocalContext);
3771 altss_set(LocalContext, context);
3772 if(old) ALCcontext_DecRef(old);
3774 return ALC_TRUE;
3778 /* alcGetContextsDevice
3780 * Returns the device that a particular context is attached to
3782 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3784 ALCdevice *Device;
3786 if(!VerifyContext(&Context))
3788 alcSetError(NULL, ALC_INVALID_CONTEXT);
3789 return NULL;
3791 Device = Context->Device;
3792 ALCcontext_DecRef(Context);
3794 return Device;
3798 /* alcOpenDevice
3800 * Opens the named device.
3802 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3804 ALCbackendFactory *factory;
3805 const ALCchar *fmt;
3806 ALCdevice *device;
3807 ALCenum err;
3808 ALCsizei i;
3810 DO_INITCONFIG();
3812 if(!PlaybackBackend.name)
3814 alcSetError(NULL, ALC_INVALID_VALUE);
3815 return NULL;
3818 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3819 #ifdef _WIN32
3820 /* Some old Windows apps hardcode these expecting OpenAL to use a
3821 * specific audio API, even when they're not enumerated. Creative's
3822 * router effectively ignores them too.
3824 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3825 || strcasecmp(deviceName, "MMSYSTEM") == 0
3826 #endif
3828 deviceName = NULL;
3830 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3831 if(!device)
3833 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3834 return NULL;
3837 //Validate device
3838 InitRef(&device->ref, 1);
3839 device->Connected = ALC_TRUE;
3840 device->Type = Playback;
3841 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3843 device->Flags = 0;
3844 device->Bs2b = NULL;
3845 device->Uhj_Encoder = NULL;
3846 device->Hrtf = NULL;
3847 device->HrtfHandle = NULL;
3848 VECTOR_INIT(device->HrtfList);
3849 AL_STRING_INIT(device->HrtfName);
3850 device->Render_Mode = NormalRender;
3851 AL_STRING_INIT(device->DeviceName);
3852 device->Dry.Buffer = NULL;
3853 device->Dry.NumChannels = 0;
3854 device->FOAOut.Buffer = NULL;
3855 device->FOAOut.NumChannels = 0;
3856 device->RealOut.Buffer = NULL;
3857 device->RealOut.NumChannels = 0;
3858 device->Limiter = NULL;
3859 device->AvgSpeakerDist = 0.0f;
3861 ATOMIC_INIT(&device->ContextList, NULL);
3863 device->ClockBase = 0;
3864 device->SamplesDone = 0;
3866 device->SourcesMax = 256;
3867 device->AuxiliaryEffectSlotMax = 64;
3868 device->NumAuxSends = DEFAULT_SENDS;
3870 InitUIntMap(&device->BufferMap, INT_MAX);
3871 InitUIntMap(&device->EffectMap, INT_MAX);
3872 InitUIntMap(&device->FilterMap, INT_MAX);
3874 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3876 device->ChannelDelay[i].Gain = 1.0f;
3877 device->ChannelDelay[i].Length = 0;
3878 device->ChannelDelay[i].Buffer = NULL;
3881 //Set output format
3882 device->FmtChans = DevFmtChannelsDefault;
3883 device->FmtType = DevFmtTypeDefault;
3884 device->Frequency = DEFAULT_OUTPUT_RATE;
3885 device->IsHeadphones = AL_FALSE;
3886 device->AmbiLayout = AmbiLayout_Default;
3887 device->AmbiScale = AmbiNorm_Default;
3888 device->NumUpdates = 3;
3889 device->UpdateSize = 1024;
3891 factory = PlaybackBackend.getFactory();
3892 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3893 if(!device->Backend)
3895 al_free(device);
3896 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3897 return NULL;
3901 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3903 static const struct {
3904 const char name[16];
3905 enum DevFmtChannels chans;
3906 ALsizei order;
3907 } chanlist[] = {
3908 { "mono", DevFmtMono, 0 },
3909 { "stereo", DevFmtStereo, 0 },
3910 { "quad", DevFmtQuad, 0 },
3911 { "surround51", DevFmtX51, 0 },
3912 { "surround61", DevFmtX61, 0 },
3913 { "surround71", DevFmtX71, 0 },
3914 { "surround51rear", DevFmtX51Rear, 0 },
3915 { "ambi1", DevFmtAmbi3D, 1 },
3916 { "ambi2", DevFmtAmbi3D, 2 },
3917 { "ambi3", DevFmtAmbi3D, 3 },
3919 size_t i;
3921 for(i = 0;i < COUNTOF(chanlist);i++)
3923 if(strcasecmp(chanlist[i].name, fmt) == 0)
3925 device->FmtChans = chanlist[i].chans;
3926 device->AmbiOrder = chanlist[i].order;
3927 device->Flags |= DEVICE_CHANNELS_REQUEST;
3928 break;
3931 if(i == COUNTOF(chanlist))
3932 ERR("Unsupported channels: %s\n", fmt);
3934 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3936 static const struct {
3937 const char name[16];
3938 enum DevFmtType type;
3939 } typelist[] = {
3940 { "int8", DevFmtByte },
3941 { "uint8", DevFmtUByte },
3942 { "int16", DevFmtShort },
3943 { "uint16", DevFmtUShort },
3944 { "int32", DevFmtInt },
3945 { "uint32", DevFmtUInt },
3946 { "float32", DevFmtFloat },
3948 size_t i;
3950 for(i = 0;i < COUNTOF(typelist);i++)
3952 if(strcasecmp(typelist[i].name, fmt) == 0)
3954 device->FmtType = typelist[i].type;
3955 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3956 break;
3959 if(i == COUNTOF(typelist))
3960 ERR("Unsupported sample-type: %s\n", fmt);
3963 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3965 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3966 if(device->Frequency < MIN_OUTPUT_RATE)
3967 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3968 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3971 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3972 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3974 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3975 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3976 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3977 device->UpdateSize = (device->UpdateSize+3)&~3;
3979 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
3980 if(device->SourcesMax == 0) device->SourcesMax = 256;
3982 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3983 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
3985 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
3986 device->NumAuxSends = clampi(
3987 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
3990 device->NumStereoSources = 1;
3991 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
3993 // Find a playback device to open
3994 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3996 DELETE_OBJ(device->Backend);
3997 al_free(device);
3998 alcSetError(NULL, err);
3999 return NULL;
4001 almtx_init(&device->BackendLock, almtx_plain);
4003 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
4005 if(strcasecmp(fmt, "fuma") == 0)
4007 device->AmbiLayout = AmbiLayout_FuMa;
4008 device->AmbiScale = AmbiNorm_FuMa;
4010 else if(strcasecmp(fmt, "acn+sn3d") == 0)
4012 device->AmbiLayout = AmbiLayout_ACN;
4013 device->AmbiScale = AmbiNorm_SN3D;
4015 else if(strcasecmp(fmt, "acn+n3d") == 0)
4017 device->AmbiLayout = AmbiLayout_ACN;
4018 device->AmbiScale = AmbiNorm_N3D;
4020 else
4021 ERR("Unsupported ambi-format: %s\n", fmt);
4024 device->Limiter = CreateDeviceLimiter(device);
4026 if(DefaultEffect.type != AL_EFFECT_NULL)
4028 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
4029 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
4031 device->DefaultSlot = NULL;
4032 ERR("Failed to initialize the default effect slot\n");
4034 else
4036 aluInitEffectPanning(device->DefaultSlot);
4037 if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
4039 DeinitEffectSlot(device->DefaultSlot);
4040 device->DefaultSlot = NULL;
4041 ERR("Failed to initialize the default effect\n");
4047 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4048 do {
4049 device->next = head;
4050 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4053 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4054 return device;
4057 /* alcCloseDevice
4059 * Closes the given device.
4061 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
4063 ALCdevice *iter, *origdev;
4064 ALCcontext *ctx;
4066 LockLists();
4067 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4068 do {
4069 if(iter == device)
4070 break;
4071 } while((iter=iter->next) != NULL);
4072 if(!iter || iter->Type == Capture)
4074 alcSetError(iter, ALC_INVALID_DEVICE);
4075 UnlockLists();
4076 return ALC_FALSE;
4078 almtx_lock(&device->BackendLock);
4080 origdev = device;
4081 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4083 ALCdevice *volatile*list = &origdev->next;
4084 while(*list)
4086 if(*list == device)
4088 *list = (*list)->next;
4089 break;
4091 list = &(*list)->next;
4094 UnlockLists();
4096 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
4097 while(ctx != NULL)
4099 ALCcontext *next = ctx->next;
4100 WARN("Releasing context %p\n", ctx);
4101 ReleaseContext(ctx, device);
4102 ctx = next;
4104 if((device->Flags&DEVICE_RUNNING))
4105 V0(device->Backend,stop)();
4106 device->Flags &= ~DEVICE_RUNNING;
4107 almtx_unlock(&device->BackendLock);
4109 ALCdevice_DecRef(device);
4111 return ALC_TRUE;
4115 /************************************************
4116 * ALC capture functions
4117 ************************************************/
4118 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4120 ALCbackendFactory *factory;
4121 ALCdevice *device = NULL;
4122 ALCenum err;
4123 ALCsizei i;
4125 DO_INITCONFIG();
4127 if(!CaptureBackend.name)
4129 alcSetError(NULL, ALC_INVALID_VALUE);
4130 return NULL;
4133 if(samples <= 0)
4135 alcSetError(NULL, ALC_INVALID_VALUE);
4136 return NULL;
4139 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4140 deviceName = NULL;
4142 device = al_calloc(16, sizeof(ALCdevice));
4143 if(!device)
4145 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4146 return NULL;
4149 //Validate device
4150 InitRef(&device->ref, 1);
4151 device->Connected = ALC_TRUE;
4152 device->Type = Capture;
4154 device->Hrtf = NULL;
4155 device->HrtfHandle = NULL;
4156 VECTOR_INIT(device->HrtfList);
4157 AL_STRING_INIT(device->HrtfName);
4159 AL_STRING_INIT(device->DeviceName);
4160 device->Dry.Buffer = NULL;
4161 device->Dry.NumChannels = 0;
4162 device->FOAOut.Buffer = NULL;
4163 device->FOAOut.NumChannels = 0;
4164 device->RealOut.Buffer = NULL;
4165 device->RealOut.NumChannels = 0;
4167 InitUIntMap(&device->BufferMap, INT_MAX);
4168 InitUIntMap(&device->EffectMap, INT_MAX);
4169 InitUIntMap(&device->FilterMap, INT_MAX);
4171 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4173 device->ChannelDelay[i].Gain = 1.0f;
4174 device->ChannelDelay[i].Length = 0;
4175 device->ChannelDelay[i].Buffer = NULL;
4178 factory = CaptureBackend.getFactory();
4179 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4180 if(!device->Backend)
4182 al_free(device);
4183 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4184 return NULL;
4187 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4188 device->Frequency = frequency;
4190 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4191 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4193 al_free(device);
4194 alcSetError(NULL, ALC_INVALID_ENUM);
4195 return NULL;
4197 device->IsHeadphones = AL_FALSE;
4198 device->AmbiOrder = 0;
4199 device->AmbiLayout = AmbiLayout_Default;
4200 device->AmbiScale = AmbiNorm_Default;
4202 device->UpdateSize = samples;
4203 device->NumUpdates = 1;
4205 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4206 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
4207 device->Frequency, device->UpdateSize, device->NumUpdates
4209 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4211 al_free(device);
4212 alcSetError(NULL, err);
4213 return NULL;
4215 almtx_init(&device->BackendLock, almtx_plain);
4218 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4219 do {
4220 device->next = head;
4221 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4224 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4225 return device;
4228 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4230 ALCdevice *iter, *origdev;
4232 LockLists();
4233 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4234 do {
4235 if(iter == device)
4236 break;
4237 } while((iter=iter->next) != NULL);
4238 if(!iter || iter->Type != Capture)
4240 alcSetError(iter, ALC_INVALID_DEVICE);
4241 UnlockLists();
4242 return ALC_FALSE;
4245 origdev = device;
4246 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4248 ALCdevice *volatile*list = &origdev->next;
4249 while(*list)
4251 if(*list == device)
4253 *list = (*list)->next;
4254 break;
4256 list = &(*list)->next;
4259 UnlockLists();
4261 ALCdevice_DecRef(device);
4263 return ALC_TRUE;
4266 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4268 if(!VerifyDevice(&device) || device->Type != Capture)
4269 alcSetError(device, ALC_INVALID_DEVICE);
4270 else
4272 almtx_lock(&device->BackendLock);
4273 if(!device->Connected)
4274 alcSetError(device, ALC_INVALID_DEVICE);
4275 else if(!(device->Flags&DEVICE_RUNNING))
4277 if(V0(device->Backend,start)())
4278 device->Flags |= DEVICE_RUNNING;
4279 else
4281 aluHandleDisconnect(device);
4282 alcSetError(device, ALC_INVALID_DEVICE);
4285 almtx_unlock(&device->BackendLock);
4288 if(device) ALCdevice_DecRef(device);
4291 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4293 if(!VerifyDevice(&device) || device->Type != Capture)
4294 alcSetError(device, ALC_INVALID_DEVICE);
4295 else
4297 almtx_lock(&device->BackendLock);
4298 if((device->Flags&DEVICE_RUNNING))
4299 V0(device->Backend,stop)();
4300 device->Flags &= ~DEVICE_RUNNING;
4301 almtx_unlock(&device->BackendLock);
4304 if(device) ALCdevice_DecRef(device);
4307 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4309 if(!VerifyDevice(&device) || device->Type != Capture)
4310 alcSetError(device, ALC_INVALID_DEVICE);
4311 else
4313 ALCenum err = ALC_INVALID_VALUE;
4315 almtx_lock(&device->BackendLock);
4316 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4317 err = V(device->Backend,captureSamples)(buffer, samples);
4318 almtx_unlock(&device->BackendLock);
4320 if(err != ALC_NO_ERROR)
4321 alcSetError(device, err);
4323 if(device) ALCdevice_DecRef(device);
4327 /************************************************
4328 * ALC loopback functions
4329 ************************************************/
4331 /* alcLoopbackOpenDeviceSOFT
4333 * Open a loopback device, for manual rendering.
4335 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4337 ALCbackendFactory *factory;
4338 ALCdevice *device;
4339 ALCsizei i;
4341 DO_INITCONFIG();
4343 /* Make sure the device name, if specified, is us. */
4344 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4346 alcSetError(NULL, ALC_INVALID_VALUE);
4347 return NULL;
4350 device = al_calloc(16, sizeof(ALCdevice));
4351 if(!device)
4353 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4354 return NULL;
4357 //Validate device
4358 InitRef(&device->ref, 1);
4359 device->Connected = ALC_TRUE;
4360 device->Type = Loopback;
4361 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4363 device->Flags = 0;
4364 device->Hrtf = NULL;
4365 device->HrtfHandle = NULL;
4366 VECTOR_INIT(device->HrtfList);
4367 AL_STRING_INIT(device->HrtfName);
4368 device->Bs2b = NULL;
4369 device->Uhj_Encoder = NULL;
4370 device->Render_Mode = NormalRender;
4371 AL_STRING_INIT(device->DeviceName);
4372 device->Dry.Buffer = NULL;
4373 device->Dry.NumChannels = 0;
4374 device->FOAOut.Buffer = NULL;
4375 device->FOAOut.NumChannels = 0;
4376 device->RealOut.Buffer = NULL;
4377 device->RealOut.NumChannels = 0;
4378 device->Limiter = NULL;
4379 device->AvgSpeakerDist = 0.0f;
4381 ATOMIC_INIT(&device->ContextList, NULL);
4383 device->ClockBase = 0;
4384 device->SamplesDone = 0;
4386 device->SourcesMax = 256;
4387 device->AuxiliaryEffectSlotMax = 64;
4388 device->NumAuxSends = DEFAULT_SENDS;
4390 InitUIntMap(&device->BufferMap, INT_MAX);
4391 InitUIntMap(&device->EffectMap, INT_MAX);
4392 InitUIntMap(&device->FilterMap, INT_MAX);
4394 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4396 device->ChannelDelay[i].Gain = 1.0f;
4397 device->ChannelDelay[i].Length = 0;
4398 device->ChannelDelay[i].Buffer = NULL;
4401 factory = ALCloopbackFactory_getFactory();
4402 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4403 if(!device->Backend)
4405 al_free(device);
4406 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4407 return NULL;
4409 almtx_init(&device->BackendLock, almtx_plain);
4411 //Set output format
4412 device->NumUpdates = 0;
4413 device->UpdateSize = 0;
4415 device->Frequency = DEFAULT_OUTPUT_RATE;
4416 device->FmtChans = DevFmtChannelsDefault;
4417 device->FmtType = DevFmtTypeDefault;
4418 device->IsHeadphones = AL_FALSE;
4419 device->AmbiLayout = AmbiLayout_Default;
4420 device->AmbiScale = AmbiNorm_Default;
4422 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4423 if(device->SourcesMax == 0) device->SourcesMax = 256;
4425 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4426 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4428 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4429 device->NumAuxSends = clampi(
4430 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4433 device->NumStereoSources = 1;
4434 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4436 // Open the "backend"
4437 V(device->Backend,open)("Loopback");
4439 device->Limiter = CreateDeviceLimiter(device);
4442 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4443 do {
4444 device->next = head;
4445 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4448 TRACE("Created device %p\n", device);
4449 return device;
4452 /* alcIsRenderFormatSupportedSOFT
4454 * Determines if the loopback device supports the given format for rendering.
4456 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4458 ALCboolean ret = ALC_FALSE;
4460 if(!VerifyDevice(&device) || device->Type != Loopback)
4461 alcSetError(device, ALC_INVALID_DEVICE);
4462 else if(freq <= 0)
4463 alcSetError(device, ALC_INVALID_VALUE);
4464 else
4466 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4467 ret = ALC_TRUE;
4469 if(device) ALCdevice_DecRef(device);
4471 return ret;
4474 /* alcRenderSamplesSOFT
4476 * Renders some samples into a buffer, using the format last set by the
4477 * attributes given to alcCreateContext.
4479 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4481 if(!VerifyDevice(&device) || device->Type != Loopback)
4482 alcSetError(device, ALC_INVALID_DEVICE);
4483 else if(samples < 0 || (samples > 0 && buffer == NULL))
4484 alcSetError(device, ALC_INVALID_VALUE);
4485 else
4487 V0(device->Backend,lock)();
4488 aluMixData(device, buffer, samples);
4489 V0(device->Backend,unlock)();
4491 if(device) ALCdevice_DecRef(device);
4495 /************************************************
4496 * ALC loopback2 functions
4497 ************************************************/
4499 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4501 ALCboolean ret = ALC_FALSE;
4503 if(!VerifyDevice(&device) || device->Type != Loopback)
4504 alcSetError(device, ALC_INVALID_DEVICE);
4505 else if(order <= 0)
4506 alcSetError(device, ALC_INVALID_VALUE);
4507 else
4509 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4510 ret = ALC_TRUE;
4512 if(device) ALCdevice_DecRef(device);
4514 return ret;
4517 /************************************************
4518 * ALC DSP pause/resume functions
4519 ************************************************/
4521 /* alcDevicePauseSOFT
4523 * Pause the DSP to stop audio processing.
4525 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4527 if(!VerifyDevice(&device) || device->Type != Playback)
4528 alcSetError(device, ALC_INVALID_DEVICE);
4529 else
4531 almtx_lock(&device->BackendLock);
4532 if((device->Flags&DEVICE_RUNNING))
4533 V0(device->Backend,stop)();
4534 device->Flags &= ~DEVICE_RUNNING;
4535 device->Flags |= DEVICE_PAUSED;
4536 almtx_unlock(&device->BackendLock);
4538 if(device) ALCdevice_DecRef(device);
4541 /* alcDeviceResumeSOFT
4543 * Resume the DSP to restart audio processing.
4545 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4547 if(!VerifyDevice(&device) || device->Type != Playback)
4548 alcSetError(device, ALC_INVALID_DEVICE);
4549 else
4551 almtx_lock(&device->BackendLock);
4552 if((device->Flags&DEVICE_PAUSED))
4554 device->Flags &= ~DEVICE_PAUSED;
4555 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4557 if(V0(device->Backend,start)() != ALC_FALSE)
4558 device->Flags |= DEVICE_RUNNING;
4559 else
4561 alcSetError(device, ALC_INVALID_DEVICE);
4562 V0(device->Backend,lock)();
4563 aluHandleDisconnect(device);
4564 V0(device->Backend,unlock)();
4568 almtx_unlock(&device->BackendLock);
4570 if(device) ALCdevice_DecRef(device);
4574 /************************************************
4575 * ALC HRTF functions
4576 ************************************************/
4578 /* alcGetStringiSOFT
4580 * Gets a string parameter at the given index.
4582 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4584 const ALCchar *str = NULL;
4586 if(!VerifyDevice(&device) || device->Type == Capture)
4587 alcSetError(device, ALC_INVALID_DEVICE);
4588 else switch(paramName)
4590 case ALC_HRTF_SPECIFIER_SOFT:
4591 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList))
4592 str = alstr_get_cstr(VECTOR_ELEM(device->HrtfList, index).name);
4593 else
4594 alcSetError(device, ALC_INVALID_VALUE);
4595 break;
4597 default:
4598 alcSetError(device, ALC_INVALID_ENUM);
4599 break;
4601 if(device) ALCdevice_DecRef(device);
4603 return str;
4606 /* alcResetDeviceSOFT
4608 * Resets the given device output, using the specified attribute list.
4610 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4612 ALCenum err;
4614 LockLists();
4615 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4617 UnlockLists();
4618 alcSetError(device, ALC_INVALID_DEVICE);
4619 if(device) ALCdevice_DecRef(device);
4620 return ALC_FALSE;
4622 almtx_lock(&device->BackendLock);
4623 UnlockLists();
4625 err = UpdateDeviceParams(device, attribs);
4626 almtx_unlock(&device->BackendLock);
4628 if(err != ALC_NO_ERROR)
4630 alcSetError(device, err);
4631 if(err == ALC_INVALID_DEVICE)
4633 V0(device->Backend,lock)();
4634 aluHandleDisconnect(device);
4635 V0(device->Backend,unlock)();
4637 ALCdevice_DecRef(device);
4638 return ALC_FALSE;
4640 ALCdevice_DecRef(device);
4642 return ALC_TRUE;