Finalize AL_SOFT_source_resampler
[openal-soft.git] / Alc / ALc.c
blob40786a42f96cf3cacb366fa2c0093536ee1b49b8
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include "version.h"
25 #include <math.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <memory.h>
29 #include <ctype.h>
30 #include <signal.h>
32 #include "alMain.h"
33 #include "alSource.h"
34 #include "alListener.h"
35 #include "alThunk.h"
36 #include "alSource.h"
37 #include "alBuffer.h"
38 #include "alAuxEffectSlot.h"
39 #include "alError.h"
40 #include "bformatdec.h"
41 #include "alu.h"
43 #include "compat.h"
44 #include "threads.h"
45 #include "alstring.h"
46 #include "almalloc.h"
48 #include "backends/base.h"
51 /************************************************
52 * Backends
53 ************************************************/
54 struct BackendInfo {
55 const char *name;
56 ALCbackendFactory* (*getFactory)(void);
57 ALCboolean (*Init)(BackendFuncs*);
58 void (*Deinit)(void);
59 void (*Probe)(enum DevProbe);
60 BackendFuncs Funcs;
63 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
64 static struct BackendInfo BackendList[] = {
65 #ifdef HAVE_JACK
66 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
67 #endif
68 #ifdef HAVE_PULSEAUDIO
69 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
70 #endif
71 #ifdef HAVE_ALSA
72 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
73 #endif
74 #ifdef HAVE_COREAUDIO
75 { "core", ALCcoreAudioBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
76 #endif
77 #ifdef HAVE_OSS
78 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
79 #endif
80 #ifdef HAVE_SOLARIS
81 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
82 #endif
83 #ifdef HAVE_SNDIO
84 { "sndio", ALCsndioBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
85 #endif
86 #ifdef HAVE_QSA
87 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
88 #endif
89 #ifdef HAVE_MMDEVAPI
90 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
91 #endif
92 #ifdef HAVE_DSOUND
93 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
94 #endif
95 #ifdef HAVE_WINMM
96 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
97 #endif
98 #ifdef HAVE_PORTAUDIO
99 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
100 #endif
101 #ifdef HAVE_OPENSL
102 { "opensl", ALCopenslBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
103 #endif
105 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
106 #ifdef HAVE_WAVE
107 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
108 #endif
110 static ALsizei BackendListSize = COUNTOF(BackendList);
111 #undef EmptyFuncs
113 static struct BackendInfo PlaybackBackend;
114 static struct BackendInfo CaptureBackend;
117 /************************************************
118 * Functions, enums, and errors
119 ************************************************/
120 #define DECL(x) { #x, (ALCvoid*)(x) }
121 static const struct {
122 const ALCchar *funcName;
123 ALCvoid *address;
124 } alcFunctions[] = {
125 DECL(alcCreateContext),
126 DECL(alcMakeContextCurrent),
127 DECL(alcProcessContext),
128 DECL(alcSuspendContext),
129 DECL(alcDestroyContext),
130 DECL(alcGetCurrentContext),
131 DECL(alcGetContextsDevice),
132 DECL(alcOpenDevice),
133 DECL(alcCloseDevice),
134 DECL(alcGetError),
135 DECL(alcIsExtensionPresent),
136 DECL(alcGetProcAddress),
137 DECL(alcGetEnumValue),
138 DECL(alcGetString),
139 DECL(alcGetIntegerv),
140 DECL(alcCaptureOpenDevice),
141 DECL(alcCaptureCloseDevice),
142 DECL(alcCaptureStart),
143 DECL(alcCaptureStop),
144 DECL(alcCaptureSamples),
146 DECL(alcSetThreadContext),
147 DECL(alcGetThreadContext),
149 DECL(alcLoopbackOpenDeviceSOFT),
150 DECL(alcIsRenderFormatSupportedSOFT),
151 DECL(alcRenderSamplesSOFT),
153 DECL(alcIsAmbisonicFormatSupportedSOFT),
155 DECL(alcDevicePauseSOFT),
156 DECL(alcDeviceResumeSOFT),
158 DECL(alcGetStringiSOFT),
159 DECL(alcResetDeviceSOFT),
161 DECL(alcGetInteger64vSOFT),
163 DECL(alEnable),
164 DECL(alDisable),
165 DECL(alIsEnabled),
166 DECL(alGetString),
167 DECL(alGetBooleanv),
168 DECL(alGetIntegerv),
169 DECL(alGetFloatv),
170 DECL(alGetDoublev),
171 DECL(alGetBoolean),
172 DECL(alGetInteger),
173 DECL(alGetFloat),
174 DECL(alGetDouble),
175 DECL(alGetError),
176 DECL(alIsExtensionPresent),
177 DECL(alGetProcAddress),
178 DECL(alGetEnumValue),
179 DECL(alListenerf),
180 DECL(alListener3f),
181 DECL(alListenerfv),
182 DECL(alListeneri),
183 DECL(alListener3i),
184 DECL(alListeneriv),
185 DECL(alGetListenerf),
186 DECL(alGetListener3f),
187 DECL(alGetListenerfv),
188 DECL(alGetListeneri),
189 DECL(alGetListener3i),
190 DECL(alGetListeneriv),
191 DECL(alGenSources),
192 DECL(alDeleteSources),
193 DECL(alIsSource),
194 DECL(alSourcef),
195 DECL(alSource3f),
196 DECL(alSourcefv),
197 DECL(alSourcei),
198 DECL(alSource3i),
199 DECL(alSourceiv),
200 DECL(alGetSourcef),
201 DECL(alGetSource3f),
202 DECL(alGetSourcefv),
203 DECL(alGetSourcei),
204 DECL(alGetSource3i),
205 DECL(alGetSourceiv),
206 DECL(alSourcePlayv),
207 DECL(alSourceStopv),
208 DECL(alSourceRewindv),
209 DECL(alSourcePausev),
210 DECL(alSourcePlay),
211 DECL(alSourceStop),
212 DECL(alSourceRewind),
213 DECL(alSourcePause),
214 DECL(alSourceQueueBuffers),
215 DECL(alSourceUnqueueBuffers),
216 DECL(alGenBuffers),
217 DECL(alDeleteBuffers),
218 DECL(alIsBuffer),
219 DECL(alBufferData),
220 DECL(alBufferf),
221 DECL(alBuffer3f),
222 DECL(alBufferfv),
223 DECL(alBufferi),
224 DECL(alBuffer3i),
225 DECL(alBufferiv),
226 DECL(alGetBufferf),
227 DECL(alGetBuffer3f),
228 DECL(alGetBufferfv),
229 DECL(alGetBufferi),
230 DECL(alGetBuffer3i),
231 DECL(alGetBufferiv),
232 DECL(alDopplerFactor),
233 DECL(alDopplerVelocity),
234 DECL(alSpeedOfSound),
235 DECL(alDistanceModel),
237 DECL(alGenFilters),
238 DECL(alDeleteFilters),
239 DECL(alIsFilter),
240 DECL(alFilteri),
241 DECL(alFilteriv),
242 DECL(alFilterf),
243 DECL(alFilterfv),
244 DECL(alGetFilteri),
245 DECL(alGetFilteriv),
246 DECL(alGetFilterf),
247 DECL(alGetFilterfv),
248 DECL(alGenEffects),
249 DECL(alDeleteEffects),
250 DECL(alIsEffect),
251 DECL(alEffecti),
252 DECL(alEffectiv),
253 DECL(alEffectf),
254 DECL(alEffectfv),
255 DECL(alGetEffecti),
256 DECL(alGetEffectiv),
257 DECL(alGetEffectf),
258 DECL(alGetEffectfv),
259 DECL(alGenAuxiliaryEffectSlots),
260 DECL(alDeleteAuxiliaryEffectSlots),
261 DECL(alIsAuxiliaryEffectSlot),
262 DECL(alAuxiliaryEffectSloti),
263 DECL(alAuxiliaryEffectSlotiv),
264 DECL(alAuxiliaryEffectSlotf),
265 DECL(alAuxiliaryEffectSlotfv),
266 DECL(alGetAuxiliaryEffectSloti),
267 DECL(alGetAuxiliaryEffectSlotiv),
268 DECL(alGetAuxiliaryEffectSlotf),
269 DECL(alGetAuxiliaryEffectSlotfv),
271 DECL(alDeferUpdatesSOFT),
272 DECL(alProcessUpdatesSOFT),
274 DECL(alSourcedSOFT),
275 DECL(alSource3dSOFT),
276 DECL(alSourcedvSOFT),
277 DECL(alGetSourcedSOFT),
278 DECL(alGetSource3dSOFT),
279 DECL(alGetSourcedvSOFT),
280 DECL(alSourcei64SOFT),
281 DECL(alSource3i64SOFT),
282 DECL(alSourcei64vSOFT),
283 DECL(alGetSourcei64SOFT),
284 DECL(alGetSource3i64SOFT),
285 DECL(alGetSourcei64vSOFT),
287 DECL(alBufferSamplesSOFT),
288 DECL(alGetBufferSamplesSOFT),
289 DECL(alIsBufferFormatSupportedSOFT),
291 DECL(alGetStringiSOFT),
293 #undef DECL
295 #define DECL(x) { #x, (x) }
296 static const struct {
297 const ALCchar *enumName;
298 ALCenum value;
299 } alcEnumerations[] = {
300 DECL(ALC_INVALID),
301 DECL(ALC_FALSE),
302 DECL(ALC_TRUE),
304 DECL(ALC_MAJOR_VERSION),
305 DECL(ALC_MINOR_VERSION),
306 DECL(ALC_ATTRIBUTES_SIZE),
307 DECL(ALC_ALL_ATTRIBUTES),
308 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
309 DECL(ALC_DEVICE_SPECIFIER),
310 DECL(ALC_ALL_DEVICES_SPECIFIER),
311 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
312 DECL(ALC_EXTENSIONS),
313 DECL(ALC_FREQUENCY),
314 DECL(ALC_REFRESH),
315 DECL(ALC_SYNC),
316 DECL(ALC_MONO_SOURCES),
317 DECL(ALC_STEREO_SOURCES),
318 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
319 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
320 DECL(ALC_CAPTURE_SAMPLES),
321 DECL(ALC_CONNECTED),
323 DECL(ALC_EFX_MAJOR_VERSION),
324 DECL(ALC_EFX_MINOR_VERSION),
325 DECL(ALC_MAX_AUXILIARY_SENDS),
327 DECL(ALC_FORMAT_CHANNELS_SOFT),
328 DECL(ALC_FORMAT_TYPE_SOFT),
330 DECL(ALC_MONO_SOFT),
331 DECL(ALC_STEREO_SOFT),
332 DECL(ALC_QUAD_SOFT),
333 DECL(ALC_5POINT1_SOFT),
334 DECL(ALC_6POINT1_SOFT),
335 DECL(ALC_7POINT1_SOFT),
336 DECL(ALC_BFORMAT3D_SOFT),
338 DECL(ALC_BYTE_SOFT),
339 DECL(ALC_UNSIGNED_BYTE_SOFT),
340 DECL(ALC_SHORT_SOFT),
341 DECL(ALC_UNSIGNED_SHORT_SOFT),
342 DECL(ALC_INT_SOFT),
343 DECL(ALC_UNSIGNED_INT_SOFT),
344 DECL(ALC_FLOAT_SOFT),
346 DECL(ALC_HRTF_SOFT),
347 DECL(ALC_DONT_CARE_SOFT),
348 DECL(ALC_HRTF_STATUS_SOFT),
349 DECL(ALC_HRTF_DISABLED_SOFT),
350 DECL(ALC_HRTF_ENABLED_SOFT),
351 DECL(ALC_HRTF_DENIED_SOFT),
352 DECL(ALC_HRTF_REQUIRED_SOFT),
353 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
354 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
355 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
356 DECL(ALC_HRTF_SPECIFIER_SOFT),
357 DECL(ALC_HRTF_ID_SOFT),
359 DECL(ALC_AMBISONIC_LAYOUT_SOFT),
360 DECL(ALC_AMBISONIC_SCALING_SOFT),
361 DECL(ALC_AMBISONIC_ORDER_SOFT),
362 DECL(ALC_ACN_SOFT),
363 DECL(ALC_FUMA_SOFT),
364 DECL(ALC_N3D_SOFT),
365 DECL(ALC_SN3D_SOFT),
367 DECL(ALC_OUTPUT_LIMITER_SOFT),
369 DECL(ALC_NO_ERROR),
370 DECL(ALC_INVALID_DEVICE),
371 DECL(ALC_INVALID_CONTEXT),
372 DECL(ALC_INVALID_ENUM),
373 DECL(ALC_INVALID_VALUE),
374 DECL(ALC_OUT_OF_MEMORY),
377 DECL(AL_INVALID),
378 DECL(AL_NONE),
379 DECL(AL_FALSE),
380 DECL(AL_TRUE),
382 DECL(AL_SOURCE_RELATIVE),
383 DECL(AL_CONE_INNER_ANGLE),
384 DECL(AL_CONE_OUTER_ANGLE),
385 DECL(AL_PITCH),
386 DECL(AL_POSITION),
387 DECL(AL_DIRECTION),
388 DECL(AL_VELOCITY),
389 DECL(AL_LOOPING),
390 DECL(AL_BUFFER),
391 DECL(AL_GAIN),
392 DECL(AL_MIN_GAIN),
393 DECL(AL_MAX_GAIN),
394 DECL(AL_ORIENTATION),
395 DECL(AL_REFERENCE_DISTANCE),
396 DECL(AL_ROLLOFF_FACTOR),
397 DECL(AL_CONE_OUTER_GAIN),
398 DECL(AL_MAX_DISTANCE),
399 DECL(AL_SEC_OFFSET),
400 DECL(AL_SAMPLE_OFFSET),
401 DECL(AL_BYTE_OFFSET),
402 DECL(AL_SOURCE_TYPE),
403 DECL(AL_STATIC),
404 DECL(AL_STREAMING),
405 DECL(AL_UNDETERMINED),
406 DECL(AL_METERS_PER_UNIT),
407 DECL(AL_LOOP_POINTS_SOFT),
408 DECL(AL_DIRECT_CHANNELS_SOFT),
410 DECL(AL_DIRECT_FILTER),
411 DECL(AL_AUXILIARY_SEND_FILTER),
412 DECL(AL_AIR_ABSORPTION_FACTOR),
413 DECL(AL_ROOM_ROLLOFF_FACTOR),
414 DECL(AL_CONE_OUTER_GAINHF),
415 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
416 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
417 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
419 DECL(AL_SOURCE_STATE),
420 DECL(AL_INITIAL),
421 DECL(AL_PLAYING),
422 DECL(AL_PAUSED),
423 DECL(AL_STOPPED),
425 DECL(AL_BUFFERS_QUEUED),
426 DECL(AL_BUFFERS_PROCESSED),
428 DECL(AL_FORMAT_MONO8),
429 DECL(AL_FORMAT_MONO16),
430 DECL(AL_FORMAT_MONO_FLOAT32),
431 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
432 DECL(AL_FORMAT_STEREO8),
433 DECL(AL_FORMAT_STEREO16),
434 DECL(AL_FORMAT_STEREO_FLOAT32),
435 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
436 DECL(AL_FORMAT_MONO_IMA4),
437 DECL(AL_FORMAT_STEREO_IMA4),
438 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
439 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
440 DECL(AL_FORMAT_QUAD8_LOKI),
441 DECL(AL_FORMAT_QUAD16_LOKI),
442 DECL(AL_FORMAT_QUAD8),
443 DECL(AL_FORMAT_QUAD16),
444 DECL(AL_FORMAT_QUAD32),
445 DECL(AL_FORMAT_51CHN8),
446 DECL(AL_FORMAT_51CHN16),
447 DECL(AL_FORMAT_51CHN32),
448 DECL(AL_FORMAT_61CHN8),
449 DECL(AL_FORMAT_61CHN16),
450 DECL(AL_FORMAT_61CHN32),
451 DECL(AL_FORMAT_71CHN8),
452 DECL(AL_FORMAT_71CHN16),
453 DECL(AL_FORMAT_71CHN32),
454 DECL(AL_FORMAT_REAR8),
455 DECL(AL_FORMAT_REAR16),
456 DECL(AL_FORMAT_REAR32),
457 DECL(AL_FORMAT_MONO_MULAW),
458 DECL(AL_FORMAT_MONO_MULAW_EXT),
459 DECL(AL_FORMAT_STEREO_MULAW),
460 DECL(AL_FORMAT_STEREO_MULAW_EXT),
461 DECL(AL_FORMAT_QUAD_MULAW),
462 DECL(AL_FORMAT_51CHN_MULAW),
463 DECL(AL_FORMAT_61CHN_MULAW),
464 DECL(AL_FORMAT_71CHN_MULAW),
465 DECL(AL_FORMAT_REAR_MULAW),
466 DECL(AL_FORMAT_MONO_ALAW_EXT),
467 DECL(AL_FORMAT_STEREO_ALAW_EXT),
469 DECL(AL_FORMAT_BFORMAT2D_8),
470 DECL(AL_FORMAT_BFORMAT2D_16),
471 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
472 DECL(AL_FORMAT_BFORMAT2D_MULAW),
473 DECL(AL_FORMAT_BFORMAT3D_8),
474 DECL(AL_FORMAT_BFORMAT3D_16),
475 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
476 DECL(AL_FORMAT_BFORMAT3D_MULAW),
478 DECL(AL_MONO8_SOFT),
479 DECL(AL_MONO16_SOFT),
480 DECL(AL_MONO32F_SOFT),
481 DECL(AL_STEREO8_SOFT),
482 DECL(AL_STEREO16_SOFT),
483 DECL(AL_STEREO32F_SOFT),
484 DECL(AL_QUAD8_SOFT),
485 DECL(AL_QUAD16_SOFT),
486 DECL(AL_QUAD32F_SOFT),
487 DECL(AL_REAR8_SOFT),
488 DECL(AL_REAR16_SOFT),
489 DECL(AL_REAR32F_SOFT),
490 DECL(AL_5POINT1_8_SOFT),
491 DECL(AL_5POINT1_16_SOFT),
492 DECL(AL_5POINT1_32F_SOFT),
493 DECL(AL_6POINT1_8_SOFT),
494 DECL(AL_6POINT1_16_SOFT),
495 DECL(AL_6POINT1_32F_SOFT),
496 DECL(AL_7POINT1_8_SOFT),
497 DECL(AL_7POINT1_16_SOFT),
498 DECL(AL_7POINT1_32F_SOFT),
499 DECL(AL_BFORMAT2D_8_SOFT),
500 DECL(AL_BFORMAT2D_16_SOFT),
501 DECL(AL_BFORMAT2D_32F_SOFT),
502 DECL(AL_BFORMAT3D_8_SOFT),
503 DECL(AL_BFORMAT3D_16_SOFT),
504 DECL(AL_BFORMAT3D_32F_SOFT),
506 DECL(AL_MONO_SOFT),
507 DECL(AL_STEREO_SOFT),
508 DECL(AL_QUAD_SOFT),
509 DECL(AL_REAR_SOFT),
510 DECL(AL_5POINT1_SOFT),
511 DECL(AL_6POINT1_SOFT),
512 DECL(AL_7POINT1_SOFT),
513 DECL(AL_BFORMAT2D_SOFT),
514 DECL(AL_BFORMAT3D_SOFT),
516 DECL(AL_BYTE_SOFT),
517 DECL(AL_UNSIGNED_BYTE_SOFT),
518 DECL(AL_SHORT_SOFT),
519 DECL(AL_UNSIGNED_SHORT_SOFT),
520 DECL(AL_INT_SOFT),
521 DECL(AL_UNSIGNED_INT_SOFT),
522 DECL(AL_FLOAT_SOFT),
523 DECL(AL_DOUBLE_SOFT),
524 DECL(AL_BYTE3_SOFT),
525 DECL(AL_UNSIGNED_BYTE3_SOFT),
526 DECL(AL_MULAW_SOFT),
528 DECL(AL_FREQUENCY),
529 DECL(AL_BITS),
530 DECL(AL_CHANNELS),
531 DECL(AL_SIZE),
532 DECL(AL_INTERNAL_FORMAT_SOFT),
533 DECL(AL_BYTE_LENGTH_SOFT),
534 DECL(AL_SAMPLE_LENGTH_SOFT),
535 DECL(AL_SEC_LENGTH_SOFT),
536 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
537 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
539 DECL(AL_SOURCE_RADIUS),
541 DECL(AL_STEREO_ANGLES),
543 DECL(AL_UNUSED),
544 DECL(AL_PENDING),
545 DECL(AL_PROCESSED),
547 DECL(AL_NO_ERROR),
548 DECL(AL_INVALID_NAME),
549 DECL(AL_INVALID_ENUM),
550 DECL(AL_INVALID_VALUE),
551 DECL(AL_INVALID_OPERATION),
552 DECL(AL_OUT_OF_MEMORY),
554 DECL(AL_VENDOR),
555 DECL(AL_VERSION),
556 DECL(AL_RENDERER),
557 DECL(AL_EXTENSIONS),
559 DECL(AL_DOPPLER_FACTOR),
560 DECL(AL_DOPPLER_VELOCITY),
561 DECL(AL_DISTANCE_MODEL),
562 DECL(AL_SPEED_OF_SOUND),
563 DECL(AL_SOURCE_DISTANCE_MODEL),
564 DECL(AL_DEFERRED_UPDATES_SOFT),
565 DECL(AL_GAIN_LIMIT_SOFT),
567 DECL(AL_INVERSE_DISTANCE),
568 DECL(AL_INVERSE_DISTANCE_CLAMPED),
569 DECL(AL_LINEAR_DISTANCE),
570 DECL(AL_LINEAR_DISTANCE_CLAMPED),
571 DECL(AL_EXPONENT_DISTANCE),
572 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
574 DECL(AL_FILTER_TYPE),
575 DECL(AL_FILTER_NULL),
576 DECL(AL_FILTER_LOWPASS),
577 DECL(AL_FILTER_HIGHPASS),
578 DECL(AL_FILTER_BANDPASS),
580 DECL(AL_LOWPASS_GAIN),
581 DECL(AL_LOWPASS_GAINHF),
583 DECL(AL_HIGHPASS_GAIN),
584 DECL(AL_HIGHPASS_GAINLF),
586 DECL(AL_BANDPASS_GAIN),
587 DECL(AL_BANDPASS_GAINHF),
588 DECL(AL_BANDPASS_GAINLF),
590 DECL(AL_EFFECT_TYPE),
591 DECL(AL_EFFECT_NULL),
592 DECL(AL_EFFECT_REVERB),
593 DECL(AL_EFFECT_EAXREVERB),
594 DECL(AL_EFFECT_CHORUS),
595 DECL(AL_EFFECT_DISTORTION),
596 DECL(AL_EFFECT_ECHO),
597 DECL(AL_EFFECT_FLANGER),
598 #if 0
599 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
600 DECL(AL_EFFECT_VOCAL_MORPHER),
601 DECL(AL_EFFECT_PITCH_SHIFTER),
602 #endif
603 DECL(AL_EFFECT_RING_MODULATOR),
604 #if 0
605 DECL(AL_EFFECT_AUTOWAH),
606 #endif
607 DECL(AL_EFFECT_COMPRESSOR),
608 DECL(AL_EFFECT_EQUALIZER),
609 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
610 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
612 DECL(AL_EFFECTSLOT_EFFECT),
613 DECL(AL_EFFECTSLOT_GAIN),
614 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
615 DECL(AL_EFFECTSLOT_NULL),
617 DECL(AL_EAXREVERB_DENSITY),
618 DECL(AL_EAXREVERB_DIFFUSION),
619 DECL(AL_EAXREVERB_GAIN),
620 DECL(AL_EAXREVERB_GAINHF),
621 DECL(AL_EAXREVERB_GAINLF),
622 DECL(AL_EAXREVERB_DECAY_TIME),
623 DECL(AL_EAXREVERB_DECAY_HFRATIO),
624 DECL(AL_EAXREVERB_DECAY_LFRATIO),
625 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
626 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
627 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
628 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
629 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
630 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
631 DECL(AL_EAXREVERB_ECHO_TIME),
632 DECL(AL_EAXREVERB_ECHO_DEPTH),
633 DECL(AL_EAXREVERB_MODULATION_TIME),
634 DECL(AL_EAXREVERB_MODULATION_DEPTH),
635 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
636 DECL(AL_EAXREVERB_HFREFERENCE),
637 DECL(AL_EAXREVERB_LFREFERENCE),
638 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
639 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
641 DECL(AL_REVERB_DENSITY),
642 DECL(AL_REVERB_DIFFUSION),
643 DECL(AL_REVERB_GAIN),
644 DECL(AL_REVERB_GAINHF),
645 DECL(AL_REVERB_DECAY_TIME),
646 DECL(AL_REVERB_DECAY_HFRATIO),
647 DECL(AL_REVERB_REFLECTIONS_GAIN),
648 DECL(AL_REVERB_REFLECTIONS_DELAY),
649 DECL(AL_REVERB_LATE_REVERB_GAIN),
650 DECL(AL_REVERB_LATE_REVERB_DELAY),
651 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
652 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
653 DECL(AL_REVERB_DECAY_HFLIMIT),
655 DECL(AL_CHORUS_WAVEFORM),
656 DECL(AL_CHORUS_PHASE),
657 DECL(AL_CHORUS_RATE),
658 DECL(AL_CHORUS_DEPTH),
659 DECL(AL_CHORUS_FEEDBACK),
660 DECL(AL_CHORUS_DELAY),
662 DECL(AL_DISTORTION_EDGE),
663 DECL(AL_DISTORTION_GAIN),
664 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
665 DECL(AL_DISTORTION_EQCENTER),
666 DECL(AL_DISTORTION_EQBANDWIDTH),
668 DECL(AL_ECHO_DELAY),
669 DECL(AL_ECHO_LRDELAY),
670 DECL(AL_ECHO_DAMPING),
671 DECL(AL_ECHO_FEEDBACK),
672 DECL(AL_ECHO_SPREAD),
674 DECL(AL_FLANGER_WAVEFORM),
675 DECL(AL_FLANGER_PHASE),
676 DECL(AL_FLANGER_RATE),
677 DECL(AL_FLANGER_DEPTH),
678 DECL(AL_FLANGER_FEEDBACK),
679 DECL(AL_FLANGER_DELAY),
681 DECL(AL_RING_MODULATOR_FREQUENCY),
682 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
683 DECL(AL_RING_MODULATOR_WAVEFORM),
685 DECL(AL_COMPRESSOR_ONOFF),
687 DECL(AL_EQUALIZER_LOW_GAIN),
688 DECL(AL_EQUALIZER_LOW_CUTOFF),
689 DECL(AL_EQUALIZER_MID1_GAIN),
690 DECL(AL_EQUALIZER_MID1_CENTER),
691 DECL(AL_EQUALIZER_MID1_WIDTH),
692 DECL(AL_EQUALIZER_MID2_GAIN),
693 DECL(AL_EQUALIZER_MID2_CENTER),
694 DECL(AL_EQUALIZER_MID2_WIDTH),
695 DECL(AL_EQUALIZER_HIGH_GAIN),
696 DECL(AL_EQUALIZER_HIGH_CUTOFF),
698 DECL(AL_DEDICATED_GAIN),
700 DECL(AL_NUM_RESAMPLERS_SOFT),
701 DECL(AL_DEFAULT_RESAMPLER_SOFT),
702 DECL(AL_SOURCE_RESAMPLER_SOFT),
703 DECL(AL_RESAMPLER_NAME_SOFT),
705 #undef DECL
707 static const ALCchar alcNoError[] = "No Error";
708 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
709 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
710 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
711 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
712 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
715 /************************************************
716 * Global variables
717 ************************************************/
719 /* Enumerated device names */
720 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
722 static al_string alcAllDevicesList;
723 static al_string alcCaptureDeviceList;
725 /* Default is always the first in the list */
726 static ALCchar *alcDefaultAllDevicesSpecifier;
727 static ALCchar *alcCaptureDefaultDeviceSpecifier;
729 /* Default context extensions */
730 static const ALchar alExtList[] =
731 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
732 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
733 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
734 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
735 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
736 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
737 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length "
738 "AL_SOFT_source_resampler";
740 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
742 /* Thread-local current context */
743 static altss_t LocalContext;
744 /* Process-wide current context */
745 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
747 /* Mixing thread piority level */
748 ALint RTPrioLevel;
750 FILE *LogFile;
751 #ifdef _DEBUG
752 enum LogLevel LogLevel = LogWarning;
753 #else
754 enum LogLevel LogLevel = LogError;
755 #endif
757 /* Flag to trap ALC device errors */
758 static ALCboolean TrapALCError = ALC_FALSE;
760 /* One-time configuration init control */
761 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
763 /* Default effect that applies to sources that don't have an effect on send 0 */
764 static ALeffect DefaultEffect;
766 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
767 * updates.
769 static ALCboolean SuspendDefers = ALC_TRUE;
772 /************************************************
773 * ALC information
774 ************************************************/
775 static const ALCchar alcNoDeviceExtList[] =
776 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
777 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
778 static const ALCchar alcExtensionList[] =
779 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
780 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
781 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
782 "ALC_SOFT_loopback ALC_SOFTX_output_limiter ALC_SOFT_pause_device";
783 static const ALCint alcMajorVersion = 1;
784 static const ALCint alcMinorVersion = 1;
786 static const ALCint alcEFXMajorVersion = 1;
787 static const ALCint alcEFXMinorVersion = 0;
790 /************************************************
791 * Device lists
792 ************************************************/
793 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
795 static almtx_t ListLock;
796 static inline void LockLists(void)
798 int ret = almtx_lock(&ListLock);
799 assert(ret == althrd_success);
801 static inline void UnlockLists(void)
803 int ret = almtx_unlock(&ListLock);
804 assert(ret == althrd_success);
807 /************************************************
808 * Library initialization
809 ************************************************/
810 #if defined(_WIN32)
811 static void alc_init(void);
812 static void alc_deinit(void);
813 static void alc_deinit_safe(void);
815 #ifndef AL_LIBTYPE_STATIC
816 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
818 switch(reason)
820 case DLL_PROCESS_ATTACH:
821 /* Pin the DLL so we won't get unloaded until the process terminates */
822 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
823 (WCHAR*)hModule, &hModule);
824 alc_init();
825 break;
827 case DLL_THREAD_DETACH:
828 break;
830 case DLL_PROCESS_DETACH:
831 if(!lpReserved)
832 alc_deinit();
833 else
834 alc_deinit_safe();
835 break;
837 return TRUE;
839 #elif defined(_MSC_VER)
840 #pragma section(".CRT$XCU",read)
841 static void alc_constructor(void);
842 static void alc_destructor(void);
843 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
845 static void alc_constructor(void)
847 atexit(alc_destructor);
848 alc_init();
851 static void alc_destructor(void)
853 alc_deinit();
855 #elif defined(HAVE_GCC_DESTRUCTOR)
856 static void alc_init(void) __attribute__((constructor));
857 static void alc_deinit(void) __attribute__((destructor));
858 #else
859 #error "No static initialization available on this platform!"
860 #endif
862 #elif defined(HAVE_GCC_DESTRUCTOR)
864 static void alc_init(void) __attribute__((constructor));
865 static void alc_deinit(void) __attribute__((destructor));
867 #else
868 #error "No global initialization available on this platform!"
869 #endif
871 static void ReleaseThreadCtx(void *ptr);
872 static void alc_init(void)
874 const char *str;
875 int ret;
877 LogFile = stderr;
879 AL_STRING_INIT(alcAllDevicesList);
880 AL_STRING_INIT(alcCaptureDeviceList);
882 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
883 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
884 ConeScale *= 0.5f;
886 str = getenv("__ALSOFT_REVERSE_Z");
887 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
888 ZScale *= -1.0f;
890 ret = altss_create(&LocalContext, ReleaseThreadCtx);
891 assert(ret == althrd_success);
893 ret = almtx_init(&ListLock, almtx_recursive);
894 assert(ret == althrd_success);
896 ThunkInit();
899 static void alc_initconfig(void)
901 const char *devs, *str;
902 ALuint capfilter;
903 float valf;
904 int i, n;
906 str = getenv("ALSOFT_LOGLEVEL");
907 if(str)
909 long lvl = strtol(str, NULL, 0);
910 if(lvl >= NoLog && lvl <= LogRef)
911 LogLevel = lvl;
914 str = getenv("ALSOFT_LOGFILE");
915 if(str && str[0])
917 FILE *logfile = al_fopen(str, "wt");
918 if(logfile) LogFile = logfile;
919 else ERR("Failed to open log file '%s'\n", str);
922 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION,
923 ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
925 char buf[1024] = "";
926 int len = 0;
928 if(BackendListSize > 0)
929 len += snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
930 for(i = 1;i < BackendListSize;i++)
931 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
932 TRACE("Supported backends: %s\n", buf);
934 ReadALConfig();
936 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
937 if(str && *str)
939 if(strcasecmp(str, "ignore") == 0)
941 SuspendDefers = ALC_FALSE;
942 TRACE("Selected context suspend behavior, \"ignore\"\n");
944 else
945 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
948 capfilter = 0;
949 #if defined(HAVE_SSE4_1)
950 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
951 #elif defined(HAVE_SSE3)
952 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
953 #elif defined(HAVE_SSE2)
954 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
955 #elif defined(HAVE_SSE)
956 capfilter |= CPU_CAP_SSE;
957 #endif
958 #ifdef HAVE_NEON
959 capfilter |= CPU_CAP_NEON;
960 #endif
961 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
963 if(strcasecmp(str, "all") == 0)
964 capfilter = 0;
965 else
967 size_t len;
968 const char *next = str;
970 do {
971 str = next;
972 while(isspace(str[0]))
973 str++;
974 next = strchr(str, ',');
976 if(!str[0] || str[0] == ',')
977 continue;
979 len = (next ? ((size_t)(next-str)) : strlen(str));
980 while(len > 0 && isspace(str[len-1]))
981 len--;
982 if(len == 3 && strncasecmp(str, "sse", len) == 0)
983 capfilter &= ~CPU_CAP_SSE;
984 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
985 capfilter &= ~CPU_CAP_SSE2;
986 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
987 capfilter &= ~CPU_CAP_SSE3;
988 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
989 capfilter &= ~CPU_CAP_SSE4_1;
990 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
991 capfilter &= ~CPU_CAP_NEON;
992 else
993 WARN("Invalid CPU extension \"%s\"\n", str);
994 } while(next++);
997 FillCPUCaps(capfilter);
999 #ifdef _WIN32
1000 RTPrioLevel = 1;
1001 #else
1002 RTPrioLevel = 0;
1003 #endif
1004 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
1006 aluInitMixer();
1008 str = getenv("ALSOFT_TRAP_ERROR");
1009 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1011 TrapALError = AL_TRUE;
1012 TrapALCError = AL_TRUE;
1014 else
1016 str = getenv("ALSOFT_TRAP_AL_ERROR");
1017 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1018 TrapALError = AL_TRUE;
1019 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1021 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1022 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1023 TrapALCError = ALC_TRUE;
1024 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1027 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1028 ReverbBoost *= powf(10.0f, valf / 20.0f);
1030 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1032 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1033 ConfigValueStr(NULL, NULL, "drivers", &devs))
1035 int n;
1036 size_t len;
1037 const char *next = devs;
1038 int endlist, delitem;
1040 i = 0;
1041 do {
1042 devs = next;
1043 while(isspace(devs[0]))
1044 devs++;
1045 next = strchr(devs, ',');
1047 delitem = (devs[0] == '-');
1048 if(devs[0] == '-') devs++;
1050 if(!devs[0] || devs[0] == ',')
1052 endlist = 0;
1053 continue;
1055 endlist = 1;
1057 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1058 while(len > 0 && isspace(devs[len-1]))
1059 len--;
1060 for(n = i;n < BackendListSize;n++)
1062 if(len == strlen(BackendList[n].name) &&
1063 strncmp(BackendList[n].name, devs, len) == 0)
1065 if(delitem)
1067 for(;n+1 < BackendListSize;n++)
1068 BackendList[n] = BackendList[n+1];
1069 BackendListSize--;
1071 else
1073 struct BackendInfo Bkp = BackendList[n];
1074 for(;n > i;n--)
1075 BackendList[n] = BackendList[n-1];
1076 BackendList[n] = Bkp;
1078 i++;
1080 break;
1083 } while(next++);
1085 if(endlist)
1086 BackendListSize = i;
1089 for(i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1091 if(BackendList[i].getFactory)
1093 ALCbackendFactory *factory = BackendList[i].getFactory();
1094 if(!V0(factory,init)())
1096 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1097 continue;
1100 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1101 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1103 PlaybackBackend = BackendList[i];
1104 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1106 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1108 CaptureBackend = BackendList[i];
1109 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1112 continue;
1115 if(!BackendList[i].Init(&BackendList[i].Funcs))
1117 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1118 continue;
1121 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1122 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1124 PlaybackBackend = BackendList[i];
1125 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1127 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1129 CaptureBackend = BackendList[i];
1130 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1134 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1135 V0(factory,init)();
1138 if(!PlaybackBackend.name)
1139 WARN("No playback backend available!\n");
1140 if(!CaptureBackend.name)
1141 WARN("No capture backend available!\n");
1143 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1145 size_t len;
1146 const char *next = str;
1148 do {
1149 str = next;
1150 next = strchr(str, ',');
1152 if(!str[0] || next == str)
1153 continue;
1155 len = (next ? ((size_t)(next-str)) : strlen(str));
1156 for(n = 0;EffectList[n].name;n++)
1158 if(len == strlen(EffectList[n].name) &&
1159 strncmp(EffectList[n].name, str, len) == 0)
1160 DisabledEffects[EffectList[n].type] = AL_TRUE;
1162 } while(next++);
1165 InitEffectFactoryMap();
1167 InitEffect(&DefaultEffect);
1168 str = getenv("ALSOFT_DEFAULT_REVERB");
1169 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1170 LoadReverbPreset(str, &DefaultEffect);
1172 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1174 #ifdef __ANDROID__
1175 #include <jni.h>
1177 static JavaVM *gJavaVM;
1178 static pthread_key_t gJVMThreadKey;
1180 static void CleanupJNIEnv(void* UNUSED(ptr))
1182 JCALL0(gJavaVM,DetachCurrentThread)();
1185 void *Android_GetJNIEnv(void)
1187 if(!gJavaVM)
1189 WARN("gJavaVM is NULL!\n");
1190 return NULL;
1193 /* http://developer.android.com/guide/practices/jni.html
1195 * All threads are Linux threads, scheduled by the kernel. They're usually
1196 * started from managed code (using Thread.start), but they can also be
1197 * created elsewhere and then attached to the JavaVM. For example, a thread
1198 * started with pthread_create can be attached with the JNI
1199 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1200 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1201 * Attaching a natively-created thread causes a java.lang.Thread object to
1202 * be constructed and added to the "main" ThreadGroup, making it visible to
1203 * the debugger. Calling AttachCurrentThread on an already-attached thread
1204 * is a no-op.
1206 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1207 if(!env)
1209 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1210 if(status < 0)
1212 ERR("Failed to attach current thread\n");
1213 return NULL;
1215 pthread_setspecific(gJVMThreadKey, env);
1217 return env;
1220 /* Automatically called by JNI. */
1221 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1223 void *env;
1224 int err;
1226 gJavaVM = jvm;
1227 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1229 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1230 return JNI_ERR;
1233 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1234 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1236 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1237 ERR("pthread_key_create failed: %d\n", err);
1238 pthread_setspecific(gJVMThreadKey, env);
1239 return JNI_VERSION_1_4;
1242 #endif
1245 /************************************************
1246 * Library deinitialization
1247 ************************************************/
1248 static void alc_cleanup(void)
1250 ALCdevice *dev;
1252 AL_STRING_DEINIT(alcAllDevicesList);
1253 AL_STRING_DEINIT(alcCaptureDeviceList);
1255 free(alcDefaultAllDevicesSpecifier);
1256 alcDefaultAllDevicesSpecifier = NULL;
1257 free(alcCaptureDefaultDeviceSpecifier);
1258 alcCaptureDefaultDeviceSpecifier = NULL;
1260 if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL)
1262 ALCuint num = 0;
1263 do {
1264 num++;
1265 } while((dev=dev->next) != NULL);
1266 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1269 DeinitEffectFactoryMap();
1272 static void alc_deinit_safe(void)
1274 alc_cleanup();
1276 FreeHrtfs();
1277 FreeALConfig();
1279 ThunkExit();
1280 almtx_destroy(&ListLock);
1281 altss_delete(LocalContext);
1283 if(LogFile != stderr)
1284 fclose(LogFile);
1285 LogFile = NULL;
1288 static void alc_deinit(void)
1290 int i;
1292 alc_cleanup();
1294 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1295 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1297 for(i = 0;i < BackendListSize;i++)
1299 if(!BackendList[i].getFactory)
1300 BackendList[i].Deinit();
1301 else
1303 ALCbackendFactory *factory = BackendList[i].getFactory();
1304 V0(factory,deinit)();
1308 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1309 V0(factory,deinit)();
1312 alc_deinit_safe();
1316 /************************************************
1317 * Device enumeration
1318 ************************************************/
1319 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1321 DO_INITCONFIG();
1323 LockLists();
1324 alstr_clear(list);
1326 if(backendinfo->Probe)
1327 backendinfo->Probe(type);
1328 else if(backendinfo->getFactory)
1330 ALCbackendFactory *factory = backendinfo->getFactory();
1331 V(factory,probe)(type);
1333 UnlockLists();
1335 static void ProbeAllDevicesList(void)
1336 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1337 static void ProbeCaptureDeviceList(void)
1338 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1340 static void AppendDevice(const ALCchar *name, al_string *devnames)
1342 size_t len = strlen(name);
1343 if(len > 0)
1344 alstr_append_range(devnames, name, name+len+1);
1346 void AppendAllDevicesList(const ALCchar *name)
1347 { AppendDevice(name, &alcAllDevicesList); }
1348 void AppendCaptureDeviceList(const ALCchar *name)
1349 { AppendDevice(name, &alcCaptureDeviceList); }
1352 /************************************************
1353 * Device format information
1354 ************************************************/
1355 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1357 switch(type)
1359 case DevFmtByte: return "Signed Byte";
1360 case DevFmtUByte: return "Unsigned Byte";
1361 case DevFmtShort: return "Signed Short";
1362 case DevFmtUShort: return "Unsigned Short";
1363 case DevFmtInt: return "Signed Int";
1364 case DevFmtUInt: return "Unsigned Int";
1365 case DevFmtFloat: return "Float";
1367 return "(unknown type)";
1369 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1371 switch(chans)
1373 case DevFmtMono: return "Mono";
1374 case DevFmtStereo: return "Stereo";
1375 case DevFmtQuad: return "Quadraphonic";
1376 case DevFmtX51: return "5.1 Surround";
1377 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1378 case DevFmtX61: return "6.1 Surround";
1379 case DevFmtX71: return "7.1 Surround";
1380 case DevFmtAmbi3D: return "Ambisonic 3D";
1382 return "(unknown channels)";
1385 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder);
1386 ALsizei BytesFromDevFmt(enum DevFmtType type)
1388 switch(type)
1390 case DevFmtByte: return sizeof(ALbyte);
1391 case DevFmtUByte: return sizeof(ALubyte);
1392 case DevFmtShort: return sizeof(ALshort);
1393 case DevFmtUShort: return sizeof(ALushort);
1394 case DevFmtInt: return sizeof(ALint);
1395 case DevFmtUInt: return sizeof(ALuint);
1396 case DevFmtFloat: return sizeof(ALfloat);
1398 return 0;
1400 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder)
1402 switch(chans)
1404 case DevFmtMono: return 1;
1405 case DevFmtStereo: return 2;
1406 case DevFmtQuad: return 4;
1407 case DevFmtX51: return 6;
1408 case DevFmtX51Rear: return 6;
1409 case DevFmtX61: return 7;
1410 case DevFmtX71: return 8;
1411 case DevFmtAmbi3D: return (ambiorder >= 3) ? 16 :
1412 (ambiorder == 2) ? 9 :
1413 (ambiorder == 1) ? 4 : 1;
1415 return 0;
1418 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1419 enum DevFmtType *type)
1421 static const struct {
1422 ALenum format;
1423 enum DevFmtChannels channels;
1424 enum DevFmtType type;
1425 } list[] = {
1426 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1427 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1428 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1430 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1431 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1432 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1434 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1435 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1436 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1438 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1439 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1440 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1442 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1443 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1444 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1446 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1447 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1448 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1450 ALuint i;
1452 for(i = 0;i < COUNTOF(list);i++)
1454 if(list[i].format == format)
1456 *chans = list[i].channels;
1457 *type = list[i].type;
1458 return AL_TRUE;
1462 return AL_FALSE;
1465 static ALCboolean IsValidALCType(ALCenum type)
1467 switch(type)
1469 case ALC_BYTE_SOFT:
1470 case ALC_UNSIGNED_BYTE_SOFT:
1471 case ALC_SHORT_SOFT:
1472 case ALC_UNSIGNED_SHORT_SOFT:
1473 case ALC_INT_SOFT:
1474 case ALC_UNSIGNED_INT_SOFT:
1475 case ALC_FLOAT_SOFT:
1476 return ALC_TRUE;
1478 return ALC_FALSE;
1481 static ALCboolean IsValidALCChannels(ALCenum channels)
1483 switch(channels)
1485 case ALC_MONO_SOFT:
1486 case ALC_STEREO_SOFT:
1487 case ALC_QUAD_SOFT:
1488 case ALC_5POINT1_SOFT:
1489 case ALC_6POINT1_SOFT:
1490 case ALC_7POINT1_SOFT:
1491 case ALC_BFORMAT3D_SOFT:
1492 return ALC_TRUE;
1494 return ALC_FALSE;
1497 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1499 switch(layout)
1501 case ALC_ACN_SOFT:
1502 case ALC_FUMA_SOFT:
1503 return ALC_TRUE;
1505 return ALC_FALSE;
1508 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1510 switch(scaling)
1512 case ALC_N3D_SOFT:
1513 case ALC_SN3D_SOFT:
1514 case ALC_FUMA_SOFT:
1515 return ALC_TRUE;
1517 return ALC_FALSE;
1520 /************************************************
1521 * Miscellaneous ALC helpers
1522 ************************************************/
1524 void ALCdevice_Lock(ALCdevice *device)
1526 V0(device->Backend,lock)();
1529 void ALCdevice_Unlock(ALCdevice *device)
1531 V0(device->Backend,unlock)();
1535 /* SetDefaultWFXChannelOrder
1537 * Sets the default channel order used by WaveFormatEx.
1539 void SetDefaultWFXChannelOrder(ALCdevice *device)
1541 ALsizei i;
1543 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1544 device->RealOut.ChannelName[i] = InvalidChannel;
1546 switch(device->FmtChans)
1548 case DevFmtMono:
1549 device->RealOut.ChannelName[0] = FrontCenter;
1550 break;
1551 case DevFmtStereo:
1552 device->RealOut.ChannelName[0] = FrontLeft;
1553 device->RealOut.ChannelName[1] = FrontRight;
1554 break;
1555 case DevFmtQuad:
1556 device->RealOut.ChannelName[0] = FrontLeft;
1557 device->RealOut.ChannelName[1] = FrontRight;
1558 device->RealOut.ChannelName[2] = BackLeft;
1559 device->RealOut.ChannelName[3] = BackRight;
1560 break;
1561 case DevFmtX51:
1562 device->RealOut.ChannelName[0] = FrontLeft;
1563 device->RealOut.ChannelName[1] = FrontRight;
1564 device->RealOut.ChannelName[2] = FrontCenter;
1565 device->RealOut.ChannelName[3] = LFE;
1566 device->RealOut.ChannelName[4] = SideLeft;
1567 device->RealOut.ChannelName[5] = SideRight;
1568 break;
1569 case DevFmtX51Rear:
1570 device->RealOut.ChannelName[0] = FrontLeft;
1571 device->RealOut.ChannelName[1] = FrontRight;
1572 device->RealOut.ChannelName[2] = FrontCenter;
1573 device->RealOut.ChannelName[3] = LFE;
1574 device->RealOut.ChannelName[4] = BackLeft;
1575 device->RealOut.ChannelName[5] = BackRight;
1576 break;
1577 case DevFmtX61:
1578 device->RealOut.ChannelName[0] = FrontLeft;
1579 device->RealOut.ChannelName[1] = FrontRight;
1580 device->RealOut.ChannelName[2] = FrontCenter;
1581 device->RealOut.ChannelName[3] = LFE;
1582 device->RealOut.ChannelName[4] = BackCenter;
1583 device->RealOut.ChannelName[5] = SideLeft;
1584 device->RealOut.ChannelName[6] = SideRight;
1585 break;
1586 case DevFmtX71:
1587 device->RealOut.ChannelName[0] = FrontLeft;
1588 device->RealOut.ChannelName[1] = FrontRight;
1589 device->RealOut.ChannelName[2] = FrontCenter;
1590 device->RealOut.ChannelName[3] = LFE;
1591 device->RealOut.ChannelName[4] = BackLeft;
1592 device->RealOut.ChannelName[5] = BackRight;
1593 device->RealOut.ChannelName[6] = SideLeft;
1594 device->RealOut.ChannelName[7] = SideRight;
1595 break;
1596 case DevFmtAmbi3D:
1597 device->RealOut.ChannelName[0] = Aux0;
1598 if(device->AmbiOrder > 0)
1600 device->RealOut.ChannelName[1] = Aux1;
1601 device->RealOut.ChannelName[2] = Aux2;
1602 device->RealOut.ChannelName[3] = Aux3;
1604 if(device->AmbiOrder > 1)
1606 device->RealOut.ChannelName[4] = Aux4;
1607 device->RealOut.ChannelName[5] = Aux5;
1608 device->RealOut.ChannelName[6] = Aux6;
1609 device->RealOut.ChannelName[7] = Aux7;
1610 device->RealOut.ChannelName[8] = Aux8;
1612 if(device->AmbiOrder > 2)
1614 device->RealOut.ChannelName[9] = Aux9;
1615 device->RealOut.ChannelName[10] = Aux10;
1616 device->RealOut.ChannelName[11] = Aux11;
1617 device->RealOut.ChannelName[12] = Aux12;
1618 device->RealOut.ChannelName[13] = Aux13;
1619 device->RealOut.ChannelName[14] = Aux14;
1620 device->RealOut.ChannelName[15] = Aux15;
1622 break;
1626 /* SetDefaultChannelOrder
1628 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1630 void SetDefaultChannelOrder(ALCdevice *device)
1632 ALsizei i;
1634 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1635 device->RealOut.ChannelName[i] = InvalidChannel;
1637 switch(device->FmtChans)
1639 case DevFmtX51Rear:
1640 device->RealOut.ChannelName[0] = FrontLeft;
1641 device->RealOut.ChannelName[1] = FrontRight;
1642 device->RealOut.ChannelName[2] = BackLeft;
1643 device->RealOut.ChannelName[3] = BackRight;
1644 device->RealOut.ChannelName[4] = FrontCenter;
1645 device->RealOut.ChannelName[5] = LFE;
1646 return;
1647 case DevFmtX71:
1648 device->RealOut.ChannelName[0] = FrontLeft;
1649 device->RealOut.ChannelName[1] = FrontRight;
1650 device->RealOut.ChannelName[2] = BackLeft;
1651 device->RealOut.ChannelName[3] = BackRight;
1652 device->RealOut.ChannelName[4] = FrontCenter;
1653 device->RealOut.ChannelName[5] = LFE;
1654 device->RealOut.ChannelName[6] = SideLeft;
1655 device->RealOut.ChannelName[7] = SideRight;
1656 return;
1658 /* Same as WFX order */
1659 case DevFmtMono:
1660 case DevFmtStereo:
1661 case DevFmtQuad:
1662 case DevFmtX51:
1663 case DevFmtX61:
1664 case DevFmtAmbi3D:
1665 SetDefaultWFXChannelOrder(device);
1666 break;
1670 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1673 /* ALCcontext_DeferUpdates
1675 * Defers/suspends updates for the given context's listener and sources. This
1676 * does *NOT* stop mixing, but rather prevents certain property changes from
1677 * taking effect.
1679 void ALCcontext_DeferUpdates(ALCcontext *context)
1681 ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE);
1684 /* ALCcontext_ProcessUpdates
1686 * Resumes update processing after being deferred.
1688 void ALCcontext_ProcessUpdates(ALCcontext *context)
1690 ReadLock(&context->PropLock);
1691 if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
1693 /* Tell the mixer to stop applying updates, then wait for any active
1694 * updating to finish, before providing updates.
1696 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1697 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1698 althrd_yield();
1700 UpdateListenerProps(context);
1701 UpdateAllEffectSlotProps(context);
1702 UpdateAllSourceProps(context);
1704 /* Now with all updates declared, let the mixer continue applying them
1705 * so they all happen at once.
1707 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1709 ReadUnlock(&context->PropLock);
1713 /* alcSetError
1715 * Stores the latest ALC device error
1717 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1719 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1720 if(TrapALCError)
1722 #ifdef _WIN32
1723 /* DebugBreak() will cause an exception if there is no debugger */
1724 if(IsDebuggerPresent())
1725 DebugBreak();
1726 #elif defined(SIGTRAP)
1727 raise(SIGTRAP);
1728 #endif
1731 if(device)
1732 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1733 else
1734 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1738 /* UpdateClockBase
1740 * Updates the device's base clock time with however many samples have been
1741 * done. This is used so frequency changes on the device don't cause the time
1742 * to jump forward or back. Must not be called while the device is running/
1743 * mixing.
1745 static inline void UpdateClockBase(ALCdevice *device)
1747 IncrementRef(&device->MixCount);
1748 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1749 device->SamplesDone = 0;
1750 IncrementRef(&device->MixCount);
1753 /* UpdateDeviceParams
1755 * Updates device parameters according to the attribute list (caller is
1756 * responsible for holding the list lock).
1758 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1760 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1761 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1762 ALCenum gainLimiter = (device->LimiterGain > 0.0f);
1763 const ALsizei old_sends = device->NumAuxSends;
1764 ALsizei new_sends = device->NumAuxSends;
1765 enum DevFmtChannels oldChans;
1766 enum DevFmtType oldType;
1767 ALboolean update_failed;
1768 ALCsizei hrtf_id = -1;
1769 ALCcontext *context;
1770 ALCuint oldFreq;
1771 FPUCtl oldMode;
1772 size_t size;
1773 ALCsizei i;
1774 int val;
1776 // Check for attributes
1777 if(device->Type == Loopback)
1779 ALCsizei numMono, numStereo, numSends;
1780 ALCenum alayout = AL_NONE;
1781 ALCenum ascale = AL_NONE;
1782 ALCenum schans = AL_NONE;
1783 ALCenum stype = AL_NONE;
1784 ALCsizei attrIdx = 0;
1785 ALCsizei aorder = 0;
1786 ALCuint freq = 0;
1788 if(!attrList)
1790 WARN("Missing attributes for loopback device\n");
1791 return ALC_INVALID_VALUE;
1794 numMono = device->NumMonoSources;
1795 numStereo = device->NumStereoSources;
1796 numSends = old_sends;
1798 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1799 while(attrList[attrIdx])
1801 switch(attrList[attrIdx])
1803 case ALC_FORMAT_CHANNELS_SOFT:
1804 schans = attrList[attrIdx + 1];
1805 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1806 if(!IsValidALCChannels(schans))
1807 return ALC_INVALID_VALUE;
1808 break;
1810 case ALC_FORMAT_TYPE_SOFT:
1811 stype = attrList[attrIdx + 1];
1812 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1813 if(!IsValidALCType(stype))
1814 return ALC_INVALID_VALUE;
1815 break;
1817 case ALC_FREQUENCY:
1818 freq = attrList[attrIdx + 1];
1819 TRACE_ATTR(ALC_FREQUENCY, freq);
1820 if(freq < MIN_OUTPUT_RATE)
1821 return ALC_INVALID_VALUE;
1822 break;
1824 case ALC_AMBISONIC_LAYOUT_SOFT:
1825 alayout = attrList[attrIdx + 1];
1826 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1827 if(!IsValidAmbiLayout(alayout))
1828 return ALC_INVALID_VALUE;
1829 break;
1831 case ALC_AMBISONIC_SCALING_SOFT:
1832 ascale = attrList[attrIdx + 1];
1833 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1834 if(!IsValidAmbiScaling(ascale))
1835 return ALC_INVALID_VALUE;
1836 break;
1838 case ALC_AMBISONIC_ORDER_SOFT:
1839 aorder = attrList[attrIdx + 1];
1840 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1841 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1842 return ALC_INVALID_VALUE;
1843 break;
1845 case ALC_MONO_SOURCES:
1846 numMono = attrList[attrIdx + 1];
1847 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1848 numMono = maxi(numMono, 0);
1849 break;
1851 case ALC_STEREO_SOURCES:
1852 numStereo = attrList[attrIdx + 1];
1853 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1854 numStereo = maxi(numStereo, 0);
1855 break;
1857 case ALC_MAX_AUXILIARY_SENDS:
1858 numSends = attrList[attrIdx + 1];
1859 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1860 numSends = clampi(numSends, 0, MAX_SENDS);
1861 break;
1863 case ALC_HRTF_SOFT:
1864 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1865 if(attrList[attrIdx + 1] == ALC_FALSE)
1866 hrtf_appreq = Hrtf_Disable;
1867 else if(attrList[attrIdx + 1] == ALC_TRUE)
1868 hrtf_appreq = Hrtf_Enable;
1869 else
1870 hrtf_appreq = Hrtf_Default;
1871 break;
1873 case ALC_HRTF_ID_SOFT:
1874 hrtf_id = attrList[attrIdx + 1];
1875 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1876 break;
1878 case ALC_OUTPUT_LIMITER_SOFT:
1879 gainLimiter = attrList[attrIdx + 1];
1880 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1881 break;
1883 default:
1884 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList[attrIdx],
1885 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1886 break;
1889 attrIdx += 2;
1891 #undef TRACE_ATTR
1893 if(!schans || !stype || !freq)
1895 WARN("Missing format for loopback device\n");
1896 return ALC_INVALID_VALUE;
1898 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1900 WARN("Missing ambisonic info for loopback device\n");
1901 return ALC_INVALID_VALUE;
1904 if((device->Flags&DEVICE_RUNNING))
1905 V0(device->Backend,stop)();
1906 device->Flags &= ~DEVICE_RUNNING;
1908 UpdateClockBase(device);
1910 device->Frequency = freq;
1911 device->FmtChans = schans;
1912 device->FmtType = stype;
1913 if(schans == ALC_BFORMAT3D_SOFT)
1915 device->AmbiOrder = aorder;
1916 device->AmbiLayout = alayout;
1917 device->AmbiScale = ascale;
1920 if(numMono > INT_MAX-numStereo)
1921 numMono = INT_MAX-numStereo;
1922 numMono += numStereo;
1923 if(ConfigValueInt(NULL, NULL, "sources", &numMono))
1925 if(numMono <= 0)
1926 numMono = 256;
1928 else
1929 numMono = maxi(numMono, 256);
1930 numStereo = mini(numStereo, numMono);
1931 numMono -= numStereo;
1932 device->SourcesMax = numMono + numStereo;
1934 device->NumMonoSources = numMono;
1935 device->NumStereoSources = numStereo;
1937 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1938 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1939 else
1940 new_sends = numSends;
1942 else if(attrList && attrList[0])
1944 ALCsizei numMono, numStereo, numSends;
1945 ALCsizei attrIdx = 0;
1946 ALCuint freq;
1948 /* If a context is already running on the device, stop playback so the
1949 * device attributes can be updated. */
1950 if((device->Flags&DEVICE_RUNNING))
1951 V0(device->Backend,stop)();
1952 device->Flags &= ~DEVICE_RUNNING;
1954 UpdateClockBase(device);
1956 freq = device->Frequency;
1957 numMono = device->NumMonoSources;
1958 numStereo = device->NumStereoSources;
1959 numSends = old_sends;
1961 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1962 while(attrList[attrIdx])
1964 switch(attrList[attrIdx])
1966 case ALC_FREQUENCY:
1967 freq = attrList[attrIdx + 1];
1968 TRACE_ATTR(ALC_FREQUENCY, freq);
1969 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1970 break;
1972 case ALC_MONO_SOURCES:
1973 numMono = attrList[attrIdx + 1];
1974 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1975 numMono = maxi(numMono, 0);
1976 break;
1978 case ALC_STEREO_SOURCES:
1979 numStereo = attrList[attrIdx + 1];
1980 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1981 numStereo = maxi(numStereo, 0);
1982 break;
1984 case ALC_MAX_AUXILIARY_SENDS:
1985 numSends = attrList[attrIdx + 1];
1986 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1987 numSends = clampi(numSends, 0, MAX_SENDS);
1988 break;
1990 case ALC_HRTF_SOFT:
1991 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1992 if(attrList[attrIdx + 1] == ALC_FALSE)
1993 hrtf_appreq = Hrtf_Disable;
1994 else if(attrList[attrIdx + 1] == ALC_TRUE)
1995 hrtf_appreq = Hrtf_Enable;
1996 else
1997 hrtf_appreq = Hrtf_Default;
1998 break;
2000 case ALC_HRTF_ID_SOFT:
2001 hrtf_id = attrList[attrIdx + 1];
2002 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
2003 break;
2005 case ALC_OUTPUT_LIMITER_SOFT:
2006 gainLimiter = attrList[attrIdx + 1];
2007 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
2008 break;
2010 default:
2011 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
2012 attrList[attrIdx + 1], attrList[attrIdx + 1]);
2013 break;
2016 attrIdx += 2;
2018 #undef TRACE_ATTR
2020 ConfigValueUInt(alstr_get_cstr(device->DeviceName), NULL, "frequency", &freq);
2021 freq = maxu(freq, MIN_OUTPUT_RATE);
2023 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
2024 device->Frequency;
2025 /* SSE and Neon do best with the update size being a multiple of 4 */
2026 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2027 device->UpdateSize = (device->UpdateSize+3)&~3;
2029 device->Frequency = freq;
2031 if(numMono > INT_MAX-numStereo)
2032 numMono = INT_MAX-numStereo;
2033 numMono += numStereo;
2034 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono))
2036 if(numMono <= 0)
2037 numMono = 256;
2039 else
2040 numMono = maxi(numMono, 256);
2041 numStereo = mini(numStereo, numMono);
2042 numMono -= numStereo;
2043 device->SourcesMax = numMono + numStereo;
2045 device->NumMonoSources = numMono;
2046 device->NumStereoSources = numStereo;
2048 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2049 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2050 else
2051 new_sends = numSends;
2054 if((device->Flags&DEVICE_RUNNING))
2055 return ALC_NO_ERROR;
2057 al_free(device->Uhj_Encoder);
2058 device->Uhj_Encoder = NULL;
2060 al_free(device->Bs2b);
2061 device->Bs2b = NULL;
2063 al_free(device->ChannelDelay[0].Buffer);
2064 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2066 device->ChannelDelay[i].Length = 0;
2067 device->ChannelDelay[i].Buffer = NULL;
2070 al_free(device->Dry.Buffer);
2071 device->Dry.Buffer = NULL;
2072 device->Dry.NumChannels = 0;
2073 device->FOAOut.Buffer = NULL;
2074 device->FOAOut.NumChannels = 0;
2075 device->RealOut.Buffer = NULL;
2076 device->RealOut.NumChannels = 0;
2078 UpdateClockBase(device);
2080 /*************************************************************************
2081 * Update device format request if HRTF is requested
2083 device->HrtfStatus = ALC_HRTF_DISABLED_SOFT;
2084 if(device->Type != Loopback)
2086 const char *hrtf;
2087 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2089 if(strcasecmp(hrtf, "true") == 0)
2090 hrtf_userreq = Hrtf_Enable;
2091 else if(strcasecmp(hrtf, "false") == 0)
2092 hrtf_userreq = Hrtf_Disable;
2093 else if(strcasecmp(hrtf, "auto") != 0)
2094 ERR("Unexpected hrtf value: %s\n", hrtf);
2097 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2099 struct Hrtf *hrtf = NULL;
2100 if(VECTOR_SIZE(device->HrtfList) == 0)
2102 VECTOR_DEINIT(device->HrtfList);
2103 device->HrtfList = EnumerateHrtf(device->DeviceName);
2105 if(VECTOR_SIZE(device->HrtfList) > 0)
2107 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
2108 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
2109 else
2110 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
2113 if(hrtf)
2115 device->FmtChans = DevFmtStereo;
2116 device->Frequency = hrtf->sampleRate;
2117 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2118 if(device->HrtfHandle)
2119 Hrtf_DecRef(device->HrtfHandle);
2120 device->HrtfHandle = hrtf;
2122 else
2124 hrtf_userreq = Hrtf_Default;
2125 hrtf_appreq = Hrtf_Disable;
2126 device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2131 oldFreq = device->Frequency;
2132 oldChans = device->FmtChans;
2133 oldType = device->FmtType;
2135 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2136 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2137 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2138 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2139 device->UpdateSize, device->NumUpdates
2142 if(V0(device->Backend,reset)() == ALC_FALSE)
2143 return ALC_INVALID_DEVICE;
2145 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2147 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2148 DevFmtChannelsString(device->FmtChans));
2149 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2151 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2153 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2154 DevFmtTypeString(device->FmtType));
2155 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2157 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2159 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2160 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2163 if((device->UpdateSize&3) != 0)
2165 if((CPUCapFlags&CPU_CAP_SSE))
2166 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2167 if((CPUCapFlags&CPU_CAP_NEON))
2168 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2171 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2172 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2173 device->Frequency, device->UpdateSize, device->NumUpdates
2176 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2177 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2178 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2180 /* Allocate extra channels for any post-filter output. */
2181 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2182 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2184 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2185 device->Dry.Buffer = al_calloc(16, size);
2186 if(!device->Dry.Buffer)
2188 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2189 return ALC_INVALID_DEVICE;
2192 if(device->RealOut.NumChannels != 0)
2193 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2194 device->FOAOut.NumChannels;
2195 else
2197 device->RealOut.Buffer = device->Dry.Buffer;
2198 device->RealOut.NumChannels = device->Dry.NumChannels;
2201 if(device->FOAOut.NumChannels != 0)
2202 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2203 else
2205 device->FOAOut.Buffer = device->Dry.Buffer;
2206 device->FOAOut.NumChannels = device->Dry.NumChannels;
2209 device->NumAuxSends = new_sends;
2210 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2211 device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2212 device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2214 if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
2215 gainLimiter = val;
2216 device->LimiterGain = gainLimiter ? 1.0f : 0.0f;
2218 /* Need to delay returning failure until replacement Send arrays have been
2219 * allocated with the appropriate size.
2221 update_failed = AL_FALSE;
2222 SetMixerFPUMode(&oldMode);
2223 if(device->DefaultSlot)
2225 ALeffectslot *slot = device->DefaultSlot;
2226 ALeffectState *state = slot->Effect.State;
2228 state->OutBuffer = device->Dry.Buffer;
2229 state->OutChannels = device->Dry.NumChannels;
2230 if(V(state,deviceUpdate)(device) == AL_FALSE)
2231 update_failed = AL_TRUE;
2232 else
2233 UpdateEffectSlotProps(slot);
2236 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2237 while(context)
2239 ALsizei pos;
2241 WriteLock(&context->PropLock);
2242 LockUIntMapRead(&context->EffectSlotMap);
2243 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2245 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2246 ALeffectState *state = slot->Effect.State;
2248 state->OutBuffer = device->Dry.Buffer;
2249 state->OutChannels = device->Dry.NumChannels;
2250 if(V(state,deviceUpdate)(device) == AL_FALSE)
2251 update_failed = AL_TRUE;
2252 else
2253 UpdateEffectSlotProps(slot);
2255 UnlockUIntMapRead(&context->EffectSlotMap);
2257 LockUIntMapRead(&context->SourceMap);
2258 RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax);
2259 for(pos = 0;pos < context->SourceMap.size;pos++)
2261 ALsource *source = context->SourceMap.values[pos];
2263 if(old_sends != device->NumAuxSends)
2265 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2266 ALsizei s;
2268 memcpy(sends, source->Send,
2269 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2271 for(s = device->NumAuxSends;s < old_sends;s++)
2273 if(source->Send[s].Slot)
2274 DecrementRef(&source->Send[s].Slot->ref);
2275 source->Send[s].Slot = NULL;
2277 al_free(source->Send);
2278 source->Send = sends;
2279 for(s = old_sends;s < device->NumAuxSends;s++)
2281 source->Send[s].Slot = NULL;
2282 source->Send[s].Gain = 1.0f;
2283 source->Send[s].GainHF = 1.0f;
2284 source->Send[s].HFReference = LOWPASSFREQREF;
2285 source->Send[s].GainLF = 1.0f;
2286 source->Send[s].LFReference = HIGHPASSFREQREF;
2290 ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
2292 AllocateVoices(context, context->MaxVoices, old_sends);
2293 for(pos = 0;pos < context->VoiceCount;pos++)
2295 ALvoice *voice = context->Voices[pos];
2296 struct ALvoiceProps *props;
2298 /* Clear any pre-existing voice property structs, in case the
2299 * number of auxiliary sends changed. Active sources will have
2300 * updates respecified in UpdateAllSourceProps.
2302 props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed);
2303 al_free(props);
2305 props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
2306 while(props)
2308 struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
2309 al_free(props);
2310 props = next;
2313 if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
2314 continue;
2316 if(device->AvgSpeakerDist > 0.0f)
2318 /* Reinitialize the NFC filters for new parameters. */
2319 ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
2320 (device->AvgSpeakerDist * device->Frequency);
2321 for(i = 0;i < voice->NumChannels;i++)
2323 NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1);
2324 NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1);
2325 NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1);
2329 UnlockUIntMapRead(&context->SourceMap);
2331 UpdateListenerProps(context);
2332 UpdateAllSourceProps(context);
2333 WriteUnlock(&context->PropLock);
2335 context = context->next;
2337 RestoreFPUMode(&oldMode);
2338 if(update_failed)
2339 return ALC_INVALID_DEVICE;
2341 if(!(device->Flags&DEVICE_PAUSED))
2343 if(V0(device->Backend,start)() == ALC_FALSE)
2344 return ALC_INVALID_DEVICE;
2345 device->Flags |= DEVICE_RUNNING;
2348 return ALC_NO_ERROR;
2351 /* FreeDevice
2353 * Frees the device structure, and destroys any objects the app failed to
2354 * delete. Called once there's no more references on the device.
2356 static ALCvoid FreeDevice(ALCdevice *device)
2358 ALsizei i;
2360 TRACE("%p\n", device);
2362 V0(device->Backend,close)();
2363 DELETE_OBJ(device->Backend);
2364 device->Backend = NULL;
2366 almtx_destroy(&device->BackendLock);
2368 if(device->DefaultSlot)
2370 DeinitEffectSlot(device->DefaultSlot);
2371 device->DefaultSlot = NULL;
2374 if(device->BufferMap.size > 0)
2376 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2377 (device->BufferMap.size==1)?"":"s");
2378 ReleaseALBuffers(device);
2380 ResetUIntMap(&device->BufferMap);
2382 if(device->EffectMap.size > 0)
2384 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2385 (device->EffectMap.size==1)?"":"s");
2386 ReleaseALEffects(device);
2388 ResetUIntMap(&device->EffectMap);
2390 if(device->FilterMap.size > 0)
2392 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2393 (device->FilterMap.size==1)?"":"s");
2394 ReleaseALFilters(device);
2396 ResetUIntMap(&device->FilterMap);
2398 AL_STRING_DEINIT(device->HrtfName);
2399 FreeHrtfList(&device->HrtfList);
2400 if(device->HrtfHandle)
2401 Hrtf_DecRef(device->HrtfHandle);
2402 device->HrtfHandle = NULL;
2403 al_free(device->Hrtf);
2404 device->Hrtf = NULL;
2406 al_free(device->Bs2b);
2407 device->Bs2b = NULL;
2409 al_free(device->Uhj_Encoder);
2410 device->Uhj_Encoder = NULL;
2412 bformatdec_free(device->AmbiDecoder);
2413 device->AmbiDecoder = NULL;
2415 ambiup_free(device->AmbiUp);
2416 device->AmbiUp = NULL;
2418 al_free(device->ChannelDelay[0].Buffer);
2419 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2421 device->ChannelDelay[i].Gain = 1.0f;
2422 device->ChannelDelay[i].Length = 0;
2423 device->ChannelDelay[i].Buffer = NULL;
2426 AL_STRING_DEINIT(device->DeviceName);
2428 al_free(device->Dry.Buffer);
2429 device->Dry.Buffer = NULL;
2430 device->Dry.NumChannels = 0;
2431 device->FOAOut.Buffer = NULL;
2432 device->FOAOut.NumChannels = 0;
2433 device->RealOut.Buffer = NULL;
2434 device->RealOut.NumChannels = 0;
2436 al_free(device);
2440 void ALCdevice_IncRef(ALCdevice *device)
2442 uint ref;
2443 ref = IncrementRef(&device->ref);
2444 TRACEREF("%p increasing refcount to %u\n", device, ref);
2447 void ALCdevice_DecRef(ALCdevice *device)
2449 uint ref;
2450 ref = DecrementRef(&device->ref);
2451 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2452 if(ref == 0) FreeDevice(device);
2455 /* VerifyDevice
2457 * Checks if the device handle is valid, and increments its ref count if so.
2459 static ALCboolean VerifyDevice(ALCdevice **device)
2461 ALCdevice *tmpDevice;
2463 LockLists();
2464 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2465 while(tmpDevice)
2467 if(tmpDevice == *device)
2469 ALCdevice_IncRef(tmpDevice);
2470 UnlockLists();
2471 return ALC_TRUE;
2473 tmpDevice = tmpDevice->next;
2475 UnlockLists();
2477 *device = NULL;
2478 return ALC_FALSE;
2482 /* InitContext
2484 * Initializes context fields
2486 static ALvoid InitContext(ALCcontext *Context)
2488 ALlistener *listener = Context->Listener;
2489 struct ALeffectslotArray *auxslots;
2491 //Initialise listener
2492 listener->Gain = 1.0f;
2493 listener->MetersPerUnit = 1.0f;
2494 listener->Position[0] = 0.0f;
2495 listener->Position[1] = 0.0f;
2496 listener->Position[2] = 0.0f;
2497 listener->Velocity[0] = 0.0f;
2498 listener->Velocity[1] = 0.0f;
2499 listener->Velocity[2] = 0.0f;
2500 listener->Forward[0] = 0.0f;
2501 listener->Forward[1] = 0.0f;
2502 listener->Forward[2] = -1.0f;
2503 listener->Up[0] = 0.0f;
2504 listener->Up[1] = 1.0f;
2505 listener->Up[2] = 0.0f;
2507 aluMatrixfSet(&listener->Params.Matrix,
2508 1.0f, 0.0f, 0.0f, 0.0f,
2509 0.0f, 1.0f, 0.0f, 0.0f,
2510 0.0f, 0.0f, 1.0f, 0.0f,
2511 0.0f, 0.0f, 0.0f, 1.0f
2513 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2514 listener->Params.Gain = 1.0f;
2515 listener->Params.MetersPerUnit = 1.0f;
2516 listener->Params.DopplerFactor = 1.0f;
2517 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2519 ATOMIC_INIT(&listener->Update, NULL);
2520 ATOMIC_INIT(&listener->FreeList, NULL);
2522 //Validate Context
2523 InitRef(&Context->UpdateCount, 0);
2524 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2525 Context->GainBoost = 1.0f;
2526 RWLockInit(&Context->PropLock);
2527 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2528 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2529 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2531 auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray));
2532 auxslots->count = 0;
2533 ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots);
2535 //Set globals
2536 Context->DistanceModel = DefaultDistanceModel;
2537 Context->SourceDistanceModel = AL_FALSE;
2538 Context->DopplerFactor = 1.0f;
2539 Context->DopplerVelocity = 1.0f;
2540 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2541 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2543 Context->ExtensionList = alExtList;
2547 /* FreeContext
2549 * Cleans up the context, and destroys any remaining objects the app failed to
2550 * delete. Called once there's no more references on the context.
2552 static void FreeContext(ALCcontext *context)
2554 ALlistener *listener = context->Listener;
2555 struct ALeffectslotArray *auxslots;
2556 struct ALlistenerProps *lprops;
2557 size_t count;
2558 ALsizei i;
2560 TRACE("%p\n", context);
2562 auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
2563 al_free(auxslots);
2565 if(context->SourceMap.size > 0)
2567 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2568 (context->SourceMap.size==1)?"":"s");
2569 ReleaseALSources(context);
2571 ResetUIntMap(&context->SourceMap);
2573 if(context->EffectSlotMap.size > 0)
2575 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2576 (context->EffectSlotMap.size==1)?"":"s");
2577 ReleaseALAuxiliaryEffectSlots(context);
2579 ResetUIntMap(&context->EffectSlotMap);
2581 for(i = 0;i < context->VoiceCount;i++)
2582 DeinitVoice(context->Voices[i]);
2583 al_free(context->Voices);
2584 context->Voices = NULL;
2585 context->VoiceCount = 0;
2586 context->MaxVoices = 0;
2588 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2590 TRACE("Freed unapplied listener update %p\n", lprops);
2591 al_free(lprops);
2593 count = 0;
2594 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
2595 while(lprops)
2597 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2598 al_free(lprops);
2599 lprops = next;
2600 ++count;
2602 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2604 ALCdevice_DecRef(context->Device);
2605 context->Device = NULL;
2607 //Invalidate context
2608 memset(context, 0, sizeof(ALCcontext));
2609 al_free(context);
2612 /* ReleaseContext
2614 * Removes the context reference from the given device and removes it from
2615 * being current on the running thread or globally. Returns true if other
2616 * contexts still exist on the device.
2618 static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
2620 ALCcontext *origctx, *newhead;
2621 bool ret = true;
2623 if(altss_get(LocalContext) == context)
2625 WARN("%p released while current on thread\n", context);
2626 altss_set(LocalContext, NULL);
2627 ALCcontext_DecRef(context);
2630 origctx = context;
2631 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
2632 ALCcontext_DecRef(context);
2634 ALCdevice_Lock(device);
2635 origctx = context;
2636 newhead = context->next;
2637 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
2639 ALCcontext *volatile*list = &origctx->next;
2640 while(*list)
2642 if(*list == context)
2644 *list = (*list)->next;
2645 break;
2647 list = &(*list)->next;
2650 else
2651 ret = !!newhead;
2652 ALCdevice_Unlock(device);
2654 ALCcontext_DecRef(context);
2655 return ret;
2658 void ALCcontext_IncRef(ALCcontext *context)
2660 uint ref = IncrementRef(&context->ref);
2661 TRACEREF("%p increasing refcount to %u\n", context, ref);
2664 void ALCcontext_DecRef(ALCcontext *context)
2666 uint ref = DecrementRef(&context->ref);
2667 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2668 if(ref == 0) FreeContext(context);
2671 static void ReleaseThreadCtx(void *ptr)
2673 ALCcontext *context = ptr;
2674 uint ref = DecrementRef(&context->ref);
2675 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2676 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2679 /* VerifyContext
2681 * Checks that the given context is valid, and increments its reference count.
2683 static ALCboolean VerifyContext(ALCcontext **context)
2685 ALCdevice *dev;
2687 LockLists();
2688 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2689 while(dev)
2691 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2692 while(ctx)
2694 if(ctx == *context)
2696 ALCcontext_IncRef(ctx);
2697 UnlockLists();
2698 return ALC_TRUE;
2700 ctx = ctx->next;
2702 dev = dev->next;
2704 UnlockLists();
2706 *context = NULL;
2707 return ALC_FALSE;
2711 /* GetContextRef
2713 * Returns the currently active context for this thread, and adds a reference
2714 * without locking it.
2716 ALCcontext *GetContextRef(void)
2718 ALCcontext *context;
2720 context = altss_get(LocalContext);
2721 if(context)
2722 ALCcontext_IncRef(context);
2723 else
2725 LockLists();
2726 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2727 if(context)
2728 ALCcontext_IncRef(context);
2729 UnlockLists();
2732 return context;
2736 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2738 ALCdevice *device = context->Device;
2739 ALsizei num_sends = device->NumAuxSends;
2740 struct ALvoiceProps *props;
2741 size_t sizeof_props;
2742 size_t sizeof_voice;
2743 ALvoice **voices;
2744 ALvoice *voice;
2745 ALsizei v = 0;
2746 size_t size;
2748 if(num_voices == context->MaxVoices && num_sends == old_sends)
2749 return;
2751 /* Allocate the voice pointers, voices, and the voices' stored source
2752 * property set (including the dynamically-sized Send[] array) in one
2753 * chunk.
2755 sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
2756 sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
2757 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2759 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2760 /* The voice and property objects are stored interleaved since they're
2761 * paired together.
2763 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2764 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2766 if(context->Voices)
2768 const ALsizei v_count = mini(context->VoiceCount, num_voices);
2769 const ALsizei s_count = mini(old_sends, num_sends);
2771 for(;v < v_count;v++)
2773 ALvoice *old_voice = context->Voices[v];
2774 ALsizei i;
2776 /* Copy the old voice data and source property set to the new
2777 * storage.
2779 *voice = *old_voice;
2780 for(i = 0;i < s_count;i++)
2781 voice->Send[i] = old_voice->Send[i];
2782 *props = *(old_voice->Props);
2783 for(i = 0;i < s_count;i++)
2784 props->Send[i] = old_voice->Props->Send[i];
2786 /* Set this voice's property set pointer and voice reference. */
2787 voice->Props = props;
2788 voices[v] = voice;
2790 /* Increment pointers to the next storage space. */
2791 voice = (ALvoice*)((char*)props + sizeof_props);
2792 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2794 /* Deinit any left over voices that weren't copied over to the new
2795 * array. NOTE: If this does anything, v equals num_voices and
2796 * num_voices is less than VoiceCount, so the following loop won't do
2797 * anything.
2799 for(;v < context->VoiceCount;v++)
2800 DeinitVoice(context->Voices[v]);
2802 /* Finish setting the voices' property set pointers and references. */
2803 for(;v < num_voices;v++)
2805 ATOMIC_INIT(&voice->Update, NULL);
2806 ATOMIC_INIT(&voice->FreeList, NULL);
2808 voice->Props = props;
2809 voices[v] = voice;
2811 voice = (ALvoice*)((char*)props + sizeof_props);
2812 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2815 al_free(context->Voices);
2816 context->Voices = voices;
2817 context->MaxVoices = num_voices;
2818 context->VoiceCount = mini(context->VoiceCount, num_voices);
2822 /************************************************
2823 * Standard ALC functions
2824 ************************************************/
2826 /* alcGetError
2828 * Return last ALC generated error code for the given device
2830 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2832 ALCenum errorCode;
2834 if(VerifyDevice(&device))
2836 errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
2837 ALCdevice_DecRef(device);
2839 else
2840 errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
2842 return errorCode;
2846 /* alcSuspendContext
2848 * Suspends updates for the given context
2850 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2852 if(!SuspendDefers)
2853 return;
2855 if(!VerifyContext(&context))
2856 alcSetError(NULL, ALC_INVALID_CONTEXT);
2857 else
2859 ALCcontext_DeferUpdates(context);
2860 ALCcontext_DecRef(context);
2864 /* alcProcessContext
2866 * Resumes processing updates for the given context
2868 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2870 if(!SuspendDefers)
2871 return;
2873 if(!VerifyContext(&context))
2874 alcSetError(NULL, ALC_INVALID_CONTEXT);
2875 else
2877 ALCcontext_ProcessUpdates(context);
2878 ALCcontext_DecRef(context);
2883 /* alcGetString
2885 * Returns information about the device, and error strings
2887 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2889 const ALCchar *value = NULL;
2891 switch(param)
2893 case ALC_NO_ERROR:
2894 value = alcNoError;
2895 break;
2897 case ALC_INVALID_ENUM:
2898 value = alcErrInvalidEnum;
2899 break;
2901 case ALC_INVALID_VALUE:
2902 value = alcErrInvalidValue;
2903 break;
2905 case ALC_INVALID_DEVICE:
2906 value = alcErrInvalidDevice;
2907 break;
2909 case ALC_INVALID_CONTEXT:
2910 value = alcErrInvalidContext;
2911 break;
2913 case ALC_OUT_OF_MEMORY:
2914 value = alcErrOutOfMemory;
2915 break;
2917 case ALC_DEVICE_SPECIFIER:
2918 value = alcDefaultName;
2919 break;
2921 case ALC_ALL_DEVICES_SPECIFIER:
2922 if(VerifyDevice(&Device))
2924 value = alstr_get_cstr(Device->DeviceName);
2925 ALCdevice_DecRef(Device);
2927 else
2929 ProbeAllDevicesList();
2930 value = alstr_get_cstr(alcAllDevicesList);
2932 break;
2934 case ALC_CAPTURE_DEVICE_SPECIFIER:
2935 if(VerifyDevice(&Device))
2937 value = alstr_get_cstr(Device->DeviceName);
2938 ALCdevice_DecRef(Device);
2940 else
2942 ProbeCaptureDeviceList();
2943 value = alstr_get_cstr(alcCaptureDeviceList);
2945 break;
2947 /* Default devices are always first in the list */
2948 case ALC_DEFAULT_DEVICE_SPECIFIER:
2949 value = alcDefaultName;
2950 break;
2952 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2953 if(alstr_empty(alcAllDevicesList))
2954 ProbeAllDevicesList();
2956 VerifyDevice(&Device);
2958 free(alcDefaultAllDevicesSpecifier);
2959 alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
2960 if(!alcDefaultAllDevicesSpecifier)
2961 alcSetError(Device, ALC_OUT_OF_MEMORY);
2963 value = alcDefaultAllDevicesSpecifier;
2964 if(Device) ALCdevice_DecRef(Device);
2965 break;
2967 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2968 if(alstr_empty(alcCaptureDeviceList))
2969 ProbeCaptureDeviceList();
2971 VerifyDevice(&Device);
2973 free(alcCaptureDefaultDeviceSpecifier);
2974 alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
2975 if(!alcCaptureDefaultDeviceSpecifier)
2976 alcSetError(Device, ALC_OUT_OF_MEMORY);
2978 value = alcCaptureDefaultDeviceSpecifier;
2979 if(Device) ALCdevice_DecRef(Device);
2980 break;
2982 case ALC_EXTENSIONS:
2983 if(!VerifyDevice(&Device))
2984 value = alcNoDeviceExtList;
2985 else
2987 value = alcExtensionList;
2988 ALCdevice_DecRef(Device);
2990 break;
2992 case ALC_HRTF_SPECIFIER_SOFT:
2993 if(!VerifyDevice(&Device))
2994 alcSetError(NULL, ALC_INVALID_DEVICE);
2995 else
2997 almtx_lock(&Device->BackendLock);
2998 value = (Device->HrtfHandle ? alstr_get_cstr(Device->HrtfName) : "");
2999 almtx_unlock(&Device->BackendLock);
3000 ALCdevice_DecRef(Device);
3002 break;
3004 default:
3005 VerifyDevice(&Device);
3006 alcSetError(Device, ALC_INVALID_ENUM);
3007 if(Device) ALCdevice_DecRef(Device);
3008 break;
3011 return value;
3015 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
3017 if(device->Type == Loopback && device->FmtChans == DevFmtAmbi3D)
3018 return 25;
3019 return 19;
3022 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3024 ALCsizei i;
3026 if(size <= 0 || values == NULL)
3028 alcSetError(device, ALC_INVALID_VALUE);
3029 return 0;
3032 if(!device)
3034 switch(param)
3036 case ALC_MAJOR_VERSION:
3037 values[0] = alcMajorVersion;
3038 return 1;
3039 case ALC_MINOR_VERSION:
3040 values[0] = alcMinorVersion;
3041 return 1;
3043 case ALC_ATTRIBUTES_SIZE:
3044 case ALC_ALL_ATTRIBUTES:
3045 case ALC_FREQUENCY:
3046 case ALC_REFRESH:
3047 case ALC_SYNC:
3048 case ALC_MONO_SOURCES:
3049 case ALC_STEREO_SOURCES:
3050 case ALC_CAPTURE_SAMPLES:
3051 case ALC_FORMAT_CHANNELS_SOFT:
3052 case ALC_FORMAT_TYPE_SOFT:
3053 case ALC_AMBISONIC_LAYOUT_SOFT:
3054 case ALC_AMBISONIC_SCALING_SOFT:
3055 case ALC_AMBISONIC_ORDER_SOFT:
3056 alcSetError(NULL, ALC_INVALID_DEVICE);
3057 return 0;
3059 default:
3060 alcSetError(NULL, ALC_INVALID_ENUM);
3061 return 0;
3063 return 0;
3066 if(device->Type == Capture)
3068 switch(param)
3070 case ALC_CAPTURE_SAMPLES:
3071 almtx_lock(&device->BackendLock);
3072 values[0] = V0(device->Backend,availableSamples)();
3073 almtx_unlock(&device->BackendLock);
3074 return 1;
3076 case ALC_CONNECTED:
3077 values[0] = device->Connected;
3078 return 1;
3080 default:
3081 alcSetError(device, ALC_INVALID_ENUM);
3082 return 0;
3084 return 0;
3087 /* render device */
3088 switch(param)
3090 case ALC_MAJOR_VERSION:
3091 values[0] = alcMajorVersion;
3092 return 1;
3094 case ALC_MINOR_VERSION:
3095 values[0] = alcMinorVersion;
3096 return 1;
3098 case ALC_EFX_MAJOR_VERSION:
3099 values[0] = alcEFXMajorVersion;
3100 return 1;
3102 case ALC_EFX_MINOR_VERSION:
3103 values[0] = alcEFXMinorVersion;
3104 return 1;
3106 case ALC_ATTRIBUTES_SIZE:
3107 values[0] = NumAttrsForDevice(device);
3108 return 1;
3110 case ALC_ALL_ATTRIBUTES:
3111 if(size < NumAttrsForDevice(device))
3113 alcSetError(device, ALC_INVALID_VALUE);
3114 return 0;
3117 i = 0;
3118 almtx_lock(&device->BackendLock);
3119 values[i++] = ALC_FREQUENCY;
3120 values[i++] = device->Frequency;
3122 if(device->Type != Loopback)
3124 values[i++] = ALC_REFRESH;
3125 values[i++] = device->Frequency / device->UpdateSize;
3127 values[i++] = ALC_SYNC;
3128 values[i++] = ALC_FALSE;
3130 else
3132 if(device->FmtChans == DevFmtAmbi3D)
3134 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3135 values[i++] = device->AmbiLayout;
3137 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3138 values[i++] = device->AmbiScale;
3140 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3141 values[i++] = device->AmbiOrder;
3144 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3145 values[i++] = device->FmtChans;
3147 values[i++] = ALC_FORMAT_TYPE_SOFT;
3148 values[i++] = device->FmtType;
3151 values[i++] = ALC_MONO_SOURCES;
3152 values[i++] = device->NumMonoSources;
3154 values[i++] = ALC_STEREO_SOURCES;
3155 values[i++] = device->NumStereoSources;
3157 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3158 values[i++] = device->NumAuxSends;
3160 values[i++] = ALC_HRTF_SOFT;
3161 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3163 values[i++] = ALC_HRTF_STATUS_SOFT;
3164 values[i++] = device->HrtfStatus;
3166 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3167 values[i++] = (device->LimiterGain > 0.0f) ? ALC_TRUE : ALC_FALSE;
3168 almtx_unlock(&device->BackendLock);
3170 values[i++] = 0;
3171 return i;
3173 case ALC_FREQUENCY:
3174 values[0] = device->Frequency;
3175 return 1;
3177 case ALC_REFRESH:
3178 if(device->Type == Loopback)
3180 alcSetError(device, ALC_INVALID_DEVICE);
3181 return 0;
3183 almtx_lock(&device->BackendLock);
3184 values[0] = device->Frequency / device->UpdateSize;
3185 almtx_unlock(&device->BackendLock);
3186 return 1;
3188 case ALC_SYNC:
3189 if(device->Type == Loopback)
3191 alcSetError(device, ALC_INVALID_DEVICE);
3192 return 0;
3194 values[0] = ALC_FALSE;
3195 return 1;
3197 case ALC_FORMAT_CHANNELS_SOFT:
3198 if(device->Type != Loopback)
3200 alcSetError(device, ALC_INVALID_DEVICE);
3201 return 0;
3203 values[0] = device->FmtChans;
3204 return 1;
3206 case ALC_FORMAT_TYPE_SOFT:
3207 if(device->Type != Loopback)
3209 alcSetError(device, ALC_INVALID_DEVICE);
3210 return 0;
3212 values[0] = device->FmtType;
3213 return 1;
3215 case ALC_AMBISONIC_LAYOUT_SOFT:
3216 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3218 alcSetError(device, ALC_INVALID_DEVICE);
3219 return 0;
3221 values[0] = device->AmbiLayout;
3222 return 1;
3224 case ALC_AMBISONIC_SCALING_SOFT:
3225 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3227 alcSetError(device, ALC_INVALID_DEVICE);
3228 return 0;
3230 values[0] = device->AmbiScale;
3231 return 1;
3233 case ALC_AMBISONIC_ORDER_SOFT:
3234 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3236 alcSetError(device, ALC_INVALID_DEVICE);
3237 return 0;
3239 values[0] = device->AmbiOrder;
3240 return 1;
3242 case ALC_MONO_SOURCES:
3243 values[0] = device->NumMonoSources;
3244 return 1;
3246 case ALC_STEREO_SOURCES:
3247 values[0] = device->NumStereoSources;
3248 return 1;
3250 case ALC_MAX_AUXILIARY_SENDS:
3251 values[0] = device->NumAuxSends;
3252 return 1;
3254 case ALC_CONNECTED:
3255 values[0] = device->Connected;
3256 return 1;
3258 case ALC_HRTF_SOFT:
3259 values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3260 return 1;
3262 case ALC_HRTF_STATUS_SOFT:
3263 values[0] = device->HrtfStatus;
3264 return 1;
3266 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3267 almtx_lock(&device->BackendLock);
3268 FreeHrtfList(&device->HrtfList);
3269 device->HrtfList = EnumerateHrtf(device->DeviceName);
3270 values[0] = (ALCint)VECTOR_SIZE(device->HrtfList);
3271 almtx_unlock(&device->BackendLock);
3272 return 1;
3274 case ALC_OUTPUT_LIMITER_SOFT:
3275 values[0] = (device->LimiterGain > 0.0f) ? ALC_TRUE : ALC_FALSE;
3276 return 1;
3278 default:
3279 alcSetError(device, ALC_INVALID_ENUM);
3280 return 0;
3282 return 0;
3285 /* alcGetIntegerv
3287 * Returns information about the device and the version of OpenAL
3289 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3291 VerifyDevice(&device);
3292 if(size <= 0 || values == NULL)
3293 alcSetError(device, ALC_INVALID_VALUE);
3294 else
3295 GetIntegerv(device, param, size, values);
3296 if(device) ALCdevice_DecRef(device);
3299 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3301 ALCint *ivals;
3302 ALsizei i;
3304 VerifyDevice(&device);
3305 if(size <= 0 || values == NULL)
3306 alcSetError(device, ALC_INVALID_VALUE);
3307 else if(!device || device->Type == Capture)
3309 ivals = malloc(size * sizeof(ALCint));
3310 size = GetIntegerv(device, pname, size, ivals);
3311 for(i = 0;i < size;i++)
3312 values[i] = ivals[i];
3313 free(ivals);
3315 else /* render device */
3317 ClockLatency clock;
3318 ALuint64 basecount;
3319 ALuint samplecount;
3320 ALuint refcount;
3322 switch(pname)
3324 case ALC_ATTRIBUTES_SIZE:
3325 *values = NumAttrsForDevice(device)+4;
3326 break;
3328 case ALC_ALL_ATTRIBUTES:
3329 if(size < NumAttrsForDevice(device)+4)
3330 alcSetError(device, ALC_INVALID_VALUE);
3331 else
3333 i = 0;
3334 almtx_lock(&device->BackendLock);
3335 values[i++] = ALC_FREQUENCY;
3336 values[i++] = device->Frequency;
3338 if(device->Type != Loopback)
3340 values[i++] = ALC_REFRESH;
3341 values[i++] = device->Frequency / device->UpdateSize;
3343 values[i++] = ALC_SYNC;
3344 values[i++] = ALC_FALSE;
3346 else
3348 if(device->FmtChans == DevFmtAmbi3D)
3350 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3351 values[i++] = device->AmbiLayout;
3353 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3354 values[i++] = device->AmbiScale;
3356 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3357 values[i++] = device->AmbiOrder;
3360 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3361 values[i++] = device->FmtChans;
3363 values[i++] = ALC_FORMAT_TYPE_SOFT;
3364 values[i++] = device->FmtType;
3367 values[i++] = ALC_MONO_SOURCES;
3368 values[i++] = device->NumMonoSources;
3370 values[i++] = ALC_STEREO_SOURCES;
3371 values[i++] = device->NumStereoSources;
3373 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3374 values[i++] = device->NumAuxSends;
3376 values[i++] = ALC_HRTF_SOFT;
3377 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3379 values[i++] = ALC_HRTF_STATUS_SOFT;
3380 values[i++] = device->HrtfStatus;
3382 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3383 values[i++] = (device->LimiterGain > 0.0f) ? ALC_TRUE : ALC_FALSE;
3385 clock = V0(device->Backend,getClockLatency)();
3386 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3387 values[i++] = clock.ClockTime;
3389 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3390 values[i++] = clock.Latency;
3391 almtx_unlock(&device->BackendLock);
3393 values[i++] = 0;
3395 break;
3397 case ALC_DEVICE_CLOCK_SOFT:
3398 almtx_lock(&device->BackendLock);
3399 do {
3400 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3401 althrd_yield();
3402 basecount = device->ClockBase;
3403 samplecount = device->SamplesDone;
3404 } while(refcount != ReadRef(&device->MixCount));
3405 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3406 almtx_unlock(&device->BackendLock);
3407 break;
3409 case ALC_DEVICE_LATENCY_SOFT:
3410 almtx_lock(&device->BackendLock);
3411 clock = V0(device->Backend,getClockLatency)();
3412 almtx_unlock(&device->BackendLock);
3413 *values = clock.Latency;
3414 break;
3416 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3417 if(size < 2)
3418 alcSetError(device, ALC_INVALID_VALUE);
3419 else
3421 almtx_lock(&device->BackendLock);
3422 clock = V0(device->Backend,getClockLatency)();
3423 almtx_unlock(&device->BackendLock);
3424 values[0] = clock.ClockTime;
3425 values[1] = clock.Latency;
3427 break;
3429 default:
3430 ivals = malloc(size * sizeof(ALCint));
3431 size = GetIntegerv(device, pname, size, ivals);
3432 for(i = 0;i < size;i++)
3433 values[i] = ivals[i];
3434 free(ivals);
3435 break;
3438 if(device)
3439 ALCdevice_DecRef(device);
3443 /* alcIsExtensionPresent
3445 * Determines if there is support for a particular extension
3447 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3449 ALCboolean bResult = ALC_FALSE;
3451 VerifyDevice(&device);
3453 if(!extName)
3454 alcSetError(device, ALC_INVALID_VALUE);
3455 else
3457 size_t len = strlen(extName);
3458 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3459 while(ptr && *ptr)
3461 if(strncasecmp(ptr, extName, len) == 0 &&
3462 (ptr[len] == '\0' || isspace(ptr[len])))
3464 bResult = ALC_TRUE;
3465 break;
3467 if((ptr=strchr(ptr, ' ')) != NULL)
3469 do {
3470 ++ptr;
3471 } while(isspace(*ptr));
3475 if(device)
3476 ALCdevice_DecRef(device);
3477 return bResult;
3481 /* alcGetProcAddress
3483 * Retrieves the function address for a particular extension function
3485 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3487 ALCvoid *ptr = NULL;
3489 if(!funcName)
3491 VerifyDevice(&device);
3492 alcSetError(device, ALC_INVALID_VALUE);
3493 if(device) ALCdevice_DecRef(device);
3495 else
3497 size_t i = 0;
3498 for(i = 0;i < COUNTOF(alcFunctions);i++)
3500 if(strcmp(alcFunctions[i].funcName, funcName) == 0)
3502 ptr = alcFunctions[i].address;
3503 break;
3508 return ptr;
3512 /* alcGetEnumValue
3514 * Get the value for a particular ALC enumeration name
3516 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3518 ALCenum val = 0;
3520 if(!enumName)
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(alcEnumerations);i++)
3531 if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
3533 val = alcEnumerations[i].value;
3534 break;
3539 return val;
3543 /* alcCreateContext
3545 * Create and attach a context to the given device.
3547 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3549 ALCcontext *ALContext;
3550 ALfloat valf;
3551 ALCenum err;
3553 /* Explicitly hold the list lock while taking the BackendLock in case the
3554 * device is asynchronously destropyed, to ensure this new context is
3555 * properly cleaned up after being made.
3557 LockLists();
3558 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3560 UnlockLists();
3561 alcSetError(device, ALC_INVALID_DEVICE);
3562 if(device) ALCdevice_DecRef(device);
3563 return NULL;
3565 almtx_lock(&device->BackendLock);
3566 UnlockLists();
3568 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3570 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3571 if(!ALContext)
3573 almtx_unlock(&device->BackendLock);
3575 alcSetError(device, ALC_OUT_OF_MEMORY);
3576 ALCdevice_DecRef(device);
3577 return NULL;
3580 InitRef(&ALContext->ref, 1);
3581 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3583 ALContext->Voices = NULL;
3584 ALContext->VoiceCount = 0;
3585 ALContext->MaxVoices = 0;
3586 ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL);
3587 ALContext->Device = device;
3589 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3591 almtx_unlock(&device->BackendLock);
3593 al_free(ALContext->Voices);
3594 ALContext->Voices = NULL;
3596 al_free(ALContext);
3597 ALContext = NULL;
3599 alcSetError(device, err);
3600 if(err == ALC_INVALID_DEVICE)
3602 V0(device->Backend,lock)();
3603 aluHandleDisconnect(device);
3604 V0(device->Backend,unlock)();
3606 ALCdevice_DecRef(device);
3607 return NULL;
3609 AllocateVoices(ALContext, 256, device->NumAuxSends);
3611 ALCdevice_IncRef(ALContext->Device);
3612 InitContext(ALContext);
3614 if(ConfigValueFloat(alstr_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3616 if(!isfinite(valf))
3617 ERR("volume-adjust must be finite: %f\n", valf);
3618 else
3620 ALfloat db = clampf(valf, -24.0f, 24.0f);
3621 if(db != valf)
3622 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3623 ALContext->GainBoost = powf(10.0f, db/20.0f);
3624 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3627 UpdateListenerProps(ALContext);
3630 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3631 do {
3632 ALContext->next = head;
3633 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
3634 ALContext) == 0);
3636 almtx_unlock(&device->BackendLock);
3638 ALCdevice_DecRef(device);
3640 TRACE("Created context %p\n", ALContext);
3641 return ALContext;
3644 /* alcDestroyContext
3646 * Remove a context from its device
3648 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3650 ALCdevice *Device;
3652 LockLists();
3653 if(!VerifyContext(&context))
3655 UnlockLists();
3656 alcSetError(NULL, ALC_INVALID_CONTEXT);
3657 return;
3660 Device = context->Device;
3661 if(Device)
3663 almtx_lock(&Device->BackendLock);
3664 if(!ReleaseContext(context, Device))
3666 V0(Device->Backend,stop)();
3667 Device->Flags &= ~DEVICE_RUNNING;
3669 almtx_unlock(&Device->BackendLock);
3671 UnlockLists();
3673 ALCcontext_DecRef(context);
3677 /* alcGetCurrentContext
3679 * Returns the currently active context on the calling thread
3681 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3683 ALCcontext *Context = altss_get(LocalContext);
3684 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3685 return Context;
3688 /* alcGetThreadContext
3690 * Returns the currently active thread-local context
3692 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3694 return altss_get(LocalContext);
3698 /* alcMakeContextCurrent
3700 * Makes the given context the active process-wide context, and removes the
3701 * thread-local context for the calling thread.
3703 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3705 /* context must be valid or NULL */
3706 if(context && !VerifyContext(&context))
3708 alcSetError(NULL, ALC_INVALID_CONTEXT);
3709 return ALC_FALSE;
3711 /* context's reference count is already incremented */
3712 context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
3713 if(context) ALCcontext_DecRef(context);
3715 if((context=altss_get(LocalContext)) != NULL)
3717 altss_set(LocalContext, NULL);
3718 ALCcontext_DecRef(context);
3721 return ALC_TRUE;
3724 /* alcSetThreadContext
3726 * Makes the given context the active context for the current thread
3728 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3730 ALCcontext *old;
3732 /* context must be valid or NULL */
3733 if(context && !VerifyContext(&context))
3735 alcSetError(NULL, ALC_INVALID_CONTEXT);
3736 return ALC_FALSE;
3738 /* context's reference count is already incremented */
3739 old = altss_get(LocalContext);
3740 altss_set(LocalContext, context);
3741 if(old) ALCcontext_DecRef(old);
3743 return ALC_TRUE;
3747 /* alcGetContextsDevice
3749 * Returns the device that a particular context is attached to
3751 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3753 ALCdevice *Device;
3755 if(!VerifyContext(&Context))
3757 alcSetError(NULL, ALC_INVALID_CONTEXT);
3758 return NULL;
3760 Device = Context->Device;
3761 ALCcontext_DecRef(Context);
3763 return Device;
3767 /* alcOpenDevice
3769 * Opens the named device.
3771 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3773 const ALCchar *fmt;
3774 ALCdevice *device;
3775 ALCenum err;
3776 ALCsizei i;
3778 DO_INITCONFIG();
3780 if(!PlaybackBackend.name)
3782 alcSetError(NULL, ALC_INVALID_VALUE);
3783 return NULL;
3786 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3787 #ifdef _WIN32
3788 /* Some old Windows apps hardcode these expecting OpenAL to use a
3789 * specific audio API, even when they're not enumerated. Creative's
3790 * router effectively ignores them too.
3792 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3793 || strcasecmp(deviceName, "MMSYSTEM") == 0
3794 #endif
3796 deviceName = NULL;
3798 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3799 if(!device)
3801 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3802 return NULL;
3805 //Validate device
3806 InitRef(&device->ref, 1);
3807 device->Connected = ALC_TRUE;
3808 device->Type = Playback;
3809 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3811 device->Flags = 0;
3812 device->Bs2b = NULL;
3813 device->Uhj_Encoder = NULL;
3814 device->Hrtf = NULL;
3815 device->HrtfHandle = NULL;
3816 VECTOR_INIT(device->HrtfList);
3817 AL_STRING_INIT(device->HrtfName);
3818 device->Render_Mode = NormalRender;
3819 AL_STRING_INIT(device->DeviceName);
3820 device->Dry.Buffer = NULL;
3821 device->Dry.NumChannels = 0;
3822 device->FOAOut.Buffer = NULL;
3823 device->FOAOut.NumChannels = 0;
3824 device->RealOut.Buffer = NULL;
3825 device->RealOut.NumChannels = 0;
3826 device->LimiterGain = 1.0f;
3827 device->AvgSpeakerDist = 0.0f;
3829 ATOMIC_INIT(&device->ContextList, NULL);
3831 device->ClockBase = 0;
3832 device->SamplesDone = 0;
3834 device->SourcesMax = 256;
3835 device->AuxiliaryEffectSlotMax = 64;
3836 device->NumAuxSends = DEFAULT_SENDS;
3838 InitUIntMap(&device->BufferMap, INT_MAX);
3839 InitUIntMap(&device->EffectMap, INT_MAX);
3840 InitUIntMap(&device->FilterMap, INT_MAX);
3842 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3844 device->ChannelDelay[i].Gain = 1.0f;
3845 device->ChannelDelay[i].Length = 0;
3846 device->ChannelDelay[i].Buffer = NULL;
3849 //Set output format
3850 device->FmtChans = DevFmtChannelsDefault;
3851 device->FmtType = DevFmtTypeDefault;
3852 device->Frequency = DEFAULT_OUTPUT_RATE;
3853 device->IsHeadphones = AL_FALSE;
3854 device->AmbiLayout = AmbiLayout_Default;
3855 device->AmbiScale = AmbiNorm_Default;
3856 device->NumUpdates = 3;
3857 device->UpdateSize = 1024;
3859 if(!PlaybackBackend.getFactory)
3860 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3861 ALCbackend_Playback);
3862 else
3864 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3865 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3867 if(!device->Backend)
3869 al_free(device);
3870 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3871 return NULL;
3875 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3877 static const struct {
3878 const char name[16];
3879 enum DevFmtChannels chans;
3880 ALsizei order;
3881 } chanlist[] = {
3882 { "mono", DevFmtMono, 0 },
3883 { "stereo", DevFmtStereo, 0 },
3884 { "quad", DevFmtQuad, 0 },
3885 { "surround51", DevFmtX51, 0 },
3886 { "surround61", DevFmtX61, 0 },
3887 { "surround71", DevFmtX71, 0 },
3888 { "surround51rear", DevFmtX51Rear, 0 },
3889 { "ambi1", DevFmtAmbi3D, 1 },
3890 { "ambi2", DevFmtAmbi3D, 2 },
3891 { "ambi3", DevFmtAmbi3D, 3 },
3893 size_t i;
3895 for(i = 0;i < COUNTOF(chanlist);i++)
3897 if(strcasecmp(chanlist[i].name, fmt) == 0)
3899 device->FmtChans = chanlist[i].chans;
3900 device->AmbiOrder = chanlist[i].order;
3901 device->Flags |= DEVICE_CHANNELS_REQUEST;
3902 break;
3905 if(i == COUNTOF(chanlist))
3906 ERR("Unsupported channels: %s\n", fmt);
3908 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3910 static const struct {
3911 const char name[16];
3912 enum DevFmtType type;
3913 } typelist[] = {
3914 { "int8", DevFmtByte },
3915 { "uint8", DevFmtUByte },
3916 { "int16", DevFmtShort },
3917 { "uint16", DevFmtUShort },
3918 { "int32", DevFmtInt },
3919 { "uint32", DevFmtUInt },
3920 { "float32", DevFmtFloat },
3922 size_t i;
3924 for(i = 0;i < COUNTOF(typelist);i++)
3926 if(strcasecmp(typelist[i].name, fmt) == 0)
3928 device->FmtType = typelist[i].type;
3929 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3930 break;
3933 if(i == COUNTOF(typelist))
3934 ERR("Unsupported sample-type: %s\n", fmt);
3937 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3939 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3940 if(device->Frequency < MIN_OUTPUT_RATE)
3941 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3942 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3945 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3946 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3948 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3949 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3950 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3951 device->UpdateSize = (device->UpdateSize+3)&~3;
3953 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
3954 if(device->SourcesMax == 0) device->SourcesMax = 256;
3956 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3957 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
3959 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
3960 device->NumAuxSends = clampi(
3961 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
3964 device->NumStereoSources = 1;
3965 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
3967 // Find a playback device to open
3968 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3970 DELETE_OBJ(device->Backend);
3971 al_free(device);
3972 alcSetError(NULL, err);
3973 return NULL;
3975 almtx_init(&device->BackendLock, almtx_plain);
3977 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
3979 if(strcasecmp(fmt, "fuma") == 0)
3981 device->AmbiLayout = AmbiLayout_FuMa;
3982 device->AmbiScale = AmbiNorm_FuMa;
3984 else if(strcasecmp(fmt, "acn+sn3d") == 0)
3986 device->AmbiLayout = AmbiLayout_ACN;
3987 device->AmbiScale = AmbiNorm_SN3D;
3989 else if(strcasecmp(fmt, "acn+n3d") == 0)
3991 device->AmbiLayout = AmbiLayout_ACN;
3992 device->AmbiScale = AmbiNorm_N3D;
3994 else
3995 ERR("Unsupported ambi-format: %s\n", fmt);
3998 if(DefaultEffect.type != AL_EFFECT_NULL)
4000 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
4001 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
4003 device->DefaultSlot = NULL;
4004 ERR("Failed to initialize the default effect slot\n");
4006 else
4008 aluInitEffectPanning(device->DefaultSlot);
4009 if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
4011 DeinitEffectSlot(device->DefaultSlot);
4012 device->DefaultSlot = NULL;
4013 ERR("Failed to initialize the default effect\n");
4019 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4020 do {
4021 device->next = head;
4022 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4025 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4026 return device;
4029 /* alcCloseDevice
4031 * Closes the given device.
4033 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
4035 ALCdevice *iter, *origdev;
4036 ALCcontext *ctx;
4038 LockLists();
4039 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4040 do {
4041 if(iter == device)
4042 break;
4043 } while((iter=iter->next) != NULL);
4044 if(!iter || iter->Type == Capture)
4046 alcSetError(iter, ALC_INVALID_DEVICE);
4047 UnlockLists();
4048 return ALC_FALSE;
4050 almtx_lock(&device->BackendLock);
4052 origdev = device;
4053 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4055 ALCdevice *volatile*list = &origdev->next;
4056 while(*list)
4058 if(*list == device)
4060 *list = (*list)->next;
4061 break;
4063 list = &(*list)->next;
4066 UnlockLists();
4068 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
4069 while(ctx != NULL)
4071 ALCcontext *next = ctx->next;
4072 WARN("Releasing context %p\n", ctx);
4073 ReleaseContext(ctx, device);
4074 ctx = next;
4076 if((device->Flags&DEVICE_RUNNING))
4077 V0(device->Backend,stop)();
4078 device->Flags &= ~DEVICE_RUNNING;
4079 almtx_unlock(&device->BackendLock);
4081 ALCdevice_DecRef(device);
4083 return ALC_TRUE;
4087 /************************************************
4088 * ALC capture functions
4089 ************************************************/
4090 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4092 ALCdevice *device = NULL;
4093 ALCenum err;
4094 ALCsizei i;
4096 DO_INITCONFIG();
4098 if(!CaptureBackend.name)
4100 alcSetError(NULL, ALC_INVALID_VALUE);
4101 return NULL;
4104 if(samples <= 0)
4106 alcSetError(NULL, ALC_INVALID_VALUE);
4107 return NULL;
4110 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4111 deviceName = NULL;
4113 device = al_calloc(16, sizeof(ALCdevice));
4114 if(!device)
4116 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4117 return NULL;
4120 //Validate device
4121 InitRef(&device->ref, 1);
4122 device->Connected = ALC_TRUE;
4123 device->Type = Capture;
4125 device->Hrtf = NULL;
4126 device->HrtfHandle = NULL;
4127 VECTOR_INIT(device->HrtfList);
4128 AL_STRING_INIT(device->HrtfName);
4130 AL_STRING_INIT(device->DeviceName);
4131 device->Dry.Buffer = NULL;
4132 device->Dry.NumChannels = 0;
4133 device->FOAOut.Buffer = NULL;
4134 device->FOAOut.NumChannels = 0;
4135 device->RealOut.Buffer = NULL;
4136 device->RealOut.NumChannels = 0;
4138 InitUIntMap(&device->BufferMap, INT_MAX);
4139 InitUIntMap(&device->EffectMap, INT_MAX);
4140 InitUIntMap(&device->FilterMap, INT_MAX);
4142 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4144 device->ChannelDelay[i].Gain = 1.0f;
4145 device->ChannelDelay[i].Length = 0;
4146 device->ChannelDelay[i].Buffer = NULL;
4149 if(!CaptureBackend.getFactory)
4150 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
4151 ALCbackend_Capture);
4152 else
4154 ALCbackendFactory *factory = CaptureBackend.getFactory();
4155 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4157 if(!device->Backend)
4159 al_free(device);
4160 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4161 return NULL;
4164 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4165 device->Frequency = frequency;
4167 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4168 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4170 al_free(device);
4171 alcSetError(NULL, ALC_INVALID_ENUM);
4172 return NULL;
4174 device->IsHeadphones = AL_FALSE;
4175 device->AmbiOrder = 0;
4176 device->AmbiLayout = AmbiLayout_Default;
4177 device->AmbiScale = AmbiNorm_Default;
4179 device->UpdateSize = samples;
4180 device->NumUpdates = 1;
4182 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4183 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
4184 device->Frequency, device->UpdateSize, device->NumUpdates
4186 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4188 al_free(device);
4189 alcSetError(NULL, err);
4190 return NULL;
4192 almtx_init(&device->BackendLock, almtx_plain);
4195 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4196 do {
4197 device->next = head;
4198 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4201 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4202 return device;
4205 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4207 ALCdevice *iter, *origdev;
4209 LockLists();
4210 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4211 do {
4212 if(iter == device)
4213 break;
4214 } while((iter=iter->next) != NULL);
4215 if(!iter || iter->Type != Capture)
4217 alcSetError(iter, ALC_INVALID_DEVICE);
4218 UnlockLists();
4219 return ALC_FALSE;
4222 origdev = device;
4223 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4225 ALCdevice *volatile*list = &origdev->next;
4226 while(*list)
4228 if(*list == device)
4230 *list = (*list)->next;
4231 break;
4233 list = &(*list)->next;
4236 UnlockLists();
4238 ALCdevice_DecRef(device);
4240 return ALC_TRUE;
4243 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4245 if(!VerifyDevice(&device) || device->Type != Capture)
4246 alcSetError(device, ALC_INVALID_DEVICE);
4247 else
4249 almtx_lock(&device->BackendLock);
4250 if(!device->Connected)
4251 alcSetError(device, ALC_INVALID_DEVICE);
4252 else if(!(device->Flags&DEVICE_RUNNING))
4254 if(V0(device->Backend,start)())
4255 device->Flags |= DEVICE_RUNNING;
4256 else
4258 aluHandleDisconnect(device);
4259 alcSetError(device, ALC_INVALID_DEVICE);
4262 almtx_unlock(&device->BackendLock);
4265 if(device) ALCdevice_DecRef(device);
4268 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4270 if(!VerifyDevice(&device) || device->Type != Capture)
4271 alcSetError(device, ALC_INVALID_DEVICE);
4272 else
4274 almtx_lock(&device->BackendLock);
4275 if((device->Flags&DEVICE_RUNNING))
4276 V0(device->Backend,stop)();
4277 device->Flags &= ~DEVICE_RUNNING;
4278 almtx_unlock(&device->BackendLock);
4281 if(device) ALCdevice_DecRef(device);
4284 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4286 if(!VerifyDevice(&device) || device->Type != Capture)
4287 alcSetError(device, ALC_INVALID_DEVICE);
4288 else
4290 ALCenum err = ALC_INVALID_VALUE;
4292 almtx_lock(&device->BackendLock);
4293 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4294 err = V(device->Backend,captureSamples)(buffer, samples);
4295 almtx_unlock(&device->BackendLock);
4297 if(err != ALC_NO_ERROR)
4298 alcSetError(device, err);
4300 if(device) ALCdevice_DecRef(device);
4304 /************************************************
4305 * ALC loopback functions
4306 ************************************************/
4308 /* alcLoopbackOpenDeviceSOFT
4310 * Open a loopback device, for manual rendering.
4312 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4314 ALCbackendFactory *factory;
4315 ALCdevice *device;
4316 ALCsizei i;
4318 DO_INITCONFIG();
4320 /* Make sure the device name, if specified, is us. */
4321 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4323 alcSetError(NULL, ALC_INVALID_VALUE);
4324 return NULL;
4327 device = al_calloc(16, sizeof(ALCdevice));
4328 if(!device)
4330 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4331 return NULL;
4334 //Validate device
4335 InitRef(&device->ref, 1);
4336 device->Connected = ALC_TRUE;
4337 device->Type = Loopback;
4338 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4340 device->Flags = 0;
4341 device->Hrtf = NULL;
4342 device->HrtfHandle = NULL;
4343 VECTOR_INIT(device->HrtfList);
4344 AL_STRING_INIT(device->HrtfName);
4345 device->Bs2b = NULL;
4346 device->Uhj_Encoder = NULL;
4347 device->Render_Mode = NormalRender;
4348 AL_STRING_INIT(device->DeviceName);
4349 device->Dry.Buffer = NULL;
4350 device->Dry.NumChannels = 0;
4351 device->FOAOut.Buffer = NULL;
4352 device->FOAOut.NumChannels = 0;
4353 device->RealOut.Buffer = NULL;
4354 device->RealOut.NumChannels = 0;
4355 device->LimiterGain = 1.0f;
4356 device->AvgSpeakerDist = 0.0f;
4358 ATOMIC_INIT(&device->ContextList, NULL);
4360 device->ClockBase = 0;
4361 device->SamplesDone = 0;
4363 device->SourcesMax = 256;
4364 device->AuxiliaryEffectSlotMax = 64;
4365 device->NumAuxSends = DEFAULT_SENDS;
4367 InitUIntMap(&device->BufferMap, INT_MAX);
4368 InitUIntMap(&device->EffectMap, INT_MAX);
4369 InitUIntMap(&device->FilterMap, INT_MAX);
4371 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4373 device->ChannelDelay[i].Gain = 1.0f;
4374 device->ChannelDelay[i].Length = 0;
4375 device->ChannelDelay[i].Buffer = NULL;
4378 factory = ALCloopbackFactory_getFactory();
4379 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4380 if(!device->Backend)
4382 al_free(device);
4383 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4384 return NULL;
4386 almtx_init(&device->BackendLock, almtx_plain);
4388 //Set output format
4389 device->NumUpdates = 0;
4390 device->UpdateSize = 0;
4392 device->Frequency = DEFAULT_OUTPUT_RATE;
4393 device->FmtChans = DevFmtChannelsDefault;
4394 device->FmtType = DevFmtTypeDefault;
4395 device->IsHeadphones = AL_FALSE;
4396 device->AmbiLayout = AmbiLayout_Default;
4397 device->AmbiScale = AmbiNorm_Default;
4399 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4400 if(device->SourcesMax == 0) device->SourcesMax = 256;
4402 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4403 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4405 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4406 device->NumAuxSends = clampi(
4407 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4410 device->NumStereoSources = 1;
4411 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4413 // Open the "backend"
4414 V(device->Backend,open)("Loopback");
4417 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4418 do {
4419 device->next = head;
4420 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4423 TRACE("Created device %p\n", device);
4424 return device;
4427 /* alcIsRenderFormatSupportedSOFT
4429 * Determines if the loopback device supports the given format for rendering.
4431 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4433 ALCboolean ret = ALC_FALSE;
4435 if(!VerifyDevice(&device) || device->Type != Loopback)
4436 alcSetError(device, ALC_INVALID_DEVICE);
4437 else if(freq <= 0)
4438 alcSetError(device, ALC_INVALID_VALUE);
4439 else
4441 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4442 ret = ALC_TRUE;
4444 if(device) ALCdevice_DecRef(device);
4446 return ret;
4449 /* alcRenderSamplesSOFT
4451 * Renders some samples into a buffer, using the format last set by the
4452 * attributes given to alcCreateContext.
4454 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4456 if(!VerifyDevice(&device) || device->Type != Loopback)
4457 alcSetError(device, ALC_INVALID_DEVICE);
4458 else if(samples < 0 || (samples > 0 && buffer == NULL))
4459 alcSetError(device, ALC_INVALID_VALUE);
4460 else
4462 V0(device->Backend,lock)();
4463 aluMixData(device, buffer, samples);
4464 V0(device->Backend,unlock)();
4466 if(device) ALCdevice_DecRef(device);
4470 /************************************************
4471 * ALC loopback2 functions
4472 ************************************************/
4474 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4476 ALCboolean ret = ALC_FALSE;
4478 if(!VerifyDevice(&device) || device->Type != Loopback)
4479 alcSetError(device, ALC_INVALID_DEVICE);
4480 else if(order <= 0)
4481 alcSetError(device, ALC_INVALID_VALUE);
4482 else
4484 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4485 ret = ALC_TRUE;
4487 if(device) ALCdevice_DecRef(device);
4489 return ret;
4492 /************************************************
4493 * ALC DSP pause/resume functions
4494 ************************************************/
4496 /* alcDevicePauseSOFT
4498 * Pause the DSP to stop audio processing.
4500 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4502 if(!VerifyDevice(&device) || device->Type != Playback)
4503 alcSetError(device, ALC_INVALID_DEVICE);
4504 else
4506 almtx_lock(&device->BackendLock);
4507 if((device->Flags&DEVICE_RUNNING))
4508 V0(device->Backend,stop)();
4509 device->Flags &= ~DEVICE_RUNNING;
4510 device->Flags |= DEVICE_PAUSED;
4511 almtx_unlock(&device->BackendLock);
4513 if(device) ALCdevice_DecRef(device);
4516 /* alcDeviceResumeSOFT
4518 * Resume the DSP to restart audio processing.
4520 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4522 if(!VerifyDevice(&device) || device->Type != Playback)
4523 alcSetError(device, ALC_INVALID_DEVICE);
4524 else
4526 almtx_lock(&device->BackendLock);
4527 if((device->Flags&DEVICE_PAUSED))
4529 device->Flags &= ~DEVICE_PAUSED;
4530 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4532 if(V0(device->Backend,start)() != ALC_FALSE)
4533 device->Flags |= DEVICE_RUNNING;
4534 else
4536 alcSetError(device, ALC_INVALID_DEVICE);
4537 V0(device->Backend,lock)();
4538 aluHandleDisconnect(device);
4539 V0(device->Backend,unlock)();
4543 almtx_unlock(&device->BackendLock);
4545 if(device) ALCdevice_DecRef(device);
4549 /************************************************
4550 * ALC HRTF functions
4551 ************************************************/
4553 /* alcGetStringiSOFT
4555 * Gets a string parameter at the given index.
4557 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4559 const ALCchar *str = NULL;
4561 if(!VerifyDevice(&device) || device->Type == Capture)
4562 alcSetError(device, ALC_INVALID_DEVICE);
4563 else switch(paramName)
4565 case ALC_HRTF_SPECIFIER_SOFT:
4566 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList))
4567 str = alstr_get_cstr(VECTOR_ELEM(device->HrtfList, index).name);
4568 else
4569 alcSetError(device, ALC_INVALID_VALUE);
4570 break;
4572 default:
4573 alcSetError(device, ALC_INVALID_ENUM);
4574 break;
4576 if(device) ALCdevice_DecRef(device);
4578 return str;
4581 /* alcResetDeviceSOFT
4583 * Resets the given device output, using the specified attribute list.
4585 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4587 ALCenum err;
4589 LockLists();
4590 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4592 UnlockLists();
4593 alcSetError(device, ALC_INVALID_DEVICE);
4594 if(device) ALCdevice_DecRef(device);
4595 return ALC_FALSE;
4597 almtx_lock(&device->BackendLock);
4598 UnlockLists();
4600 err = UpdateDeviceParams(device, attribs);
4601 almtx_unlock(&device->BackendLock);
4603 if(err != ALC_NO_ERROR)
4605 alcSetError(device, err);
4606 if(err == ALC_INVALID_DEVICE)
4608 V0(device->Backend,lock)();
4609 aluHandleDisconnect(device);
4610 V0(device->Backend,unlock)();
4612 ALCdevice_DecRef(device);
4613 return ALC_FALSE;
4615 ALCdevice_DecRef(device);
4617 return ALC_TRUE;