Re-update effect slots when context properties change
[openal-soft.git] / Alc / ALc.c
blob7b4c1cfc96ff941686680c63353369e31ca819f8
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include "version.h"
25 #include <math.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <memory.h>
29 #include <ctype.h>
30 #include <signal.h>
32 #include "alMain.h"
33 #include "alSource.h"
34 #include "alListener.h"
35 #include "alThunk.h"
36 #include "alSource.h"
37 #include "alBuffer.h"
38 #include "alAuxEffectSlot.h"
39 #include "alError.h"
40 #include "bformatdec.h"
41 #include "alu.h"
43 #include "compat.h"
44 #include "threads.h"
45 #include "alstring.h"
46 #include "almalloc.h"
48 #include "backends/base.h"
51 /************************************************
52 * Backends
53 ************************************************/
54 struct BackendInfo {
55 const char *name;
56 ALCbackendFactory* (*getFactory)(void);
59 static struct BackendInfo BackendList[] = {
60 #ifdef HAVE_JACK
61 { "jack", ALCjackBackendFactory_getFactory },
62 #endif
63 #ifdef HAVE_PULSEAUDIO
64 { "pulse", ALCpulseBackendFactory_getFactory },
65 #endif
66 #ifdef HAVE_ALSA
67 { "alsa", ALCalsaBackendFactory_getFactory },
68 #endif
69 #ifdef HAVE_COREAUDIO
70 { "core", ALCcoreAudioBackendFactory_getFactory },
71 #endif
72 #ifdef HAVE_OSS
73 { "oss", ALCossBackendFactory_getFactory },
74 #endif
75 #ifdef HAVE_SOLARIS
76 { "solaris", ALCsolarisBackendFactory_getFactory },
77 #endif
78 #ifdef HAVE_SNDIO
79 { "sndio", ALCsndioBackendFactory_getFactory },
80 #endif
81 #ifdef HAVE_QSA
82 { "qsa", ALCqsaBackendFactory_getFactory },
83 #endif
84 #ifdef HAVE_MMDEVAPI
85 { "mmdevapi", ALCmmdevBackendFactory_getFactory },
86 #endif
87 #ifdef HAVE_DSOUND
88 { "dsound", ALCdsoundBackendFactory_getFactory },
89 #endif
90 #ifdef HAVE_WINMM
91 { "winmm", ALCwinmmBackendFactory_getFactory },
92 #endif
93 #ifdef HAVE_PORTAUDIO
94 { "port", ALCportBackendFactory_getFactory },
95 #endif
96 #ifdef HAVE_OPENSL
97 { "opensl", ALCopenslBackendFactory_getFactory },
98 #endif
100 { "null", ALCnullBackendFactory_getFactory },
101 #ifdef HAVE_WAVE
102 { "wave", ALCwaveBackendFactory_getFactory },
103 #endif
105 static ALsizei BackendListSize = COUNTOF(BackendList);
106 #undef EmptyFuncs
108 static struct BackendInfo PlaybackBackend;
109 static struct BackendInfo CaptureBackend;
112 /************************************************
113 * Functions, enums, and errors
114 ************************************************/
115 #define DECL(x) { #x, (ALCvoid*)(x) }
116 static const struct {
117 const ALCchar *funcName;
118 ALCvoid *address;
119 } alcFunctions[] = {
120 DECL(alcCreateContext),
121 DECL(alcMakeContextCurrent),
122 DECL(alcProcessContext),
123 DECL(alcSuspendContext),
124 DECL(alcDestroyContext),
125 DECL(alcGetCurrentContext),
126 DECL(alcGetContextsDevice),
127 DECL(alcOpenDevice),
128 DECL(alcCloseDevice),
129 DECL(alcGetError),
130 DECL(alcIsExtensionPresent),
131 DECL(alcGetProcAddress),
132 DECL(alcGetEnumValue),
133 DECL(alcGetString),
134 DECL(alcGetIntegerv),
135 DECL(alcCaptureOpenDevice),
136 DECL(alcCaptureCloseDevice),
137 DECL(alcCaptureStart),
138 DECL(alcCaptureStop),
139 DECL(alcCaptureSamples),
141 DECL(alcSetThreadContext),
142 DECL(alcGetThreadContext),
144 DECL(alcLoopbackOpenDeviceSOFT),
145 DECL(alcIsRenderFormatSupportedSOFT),
146 DECL(alcRenderSamplesSOFT),
148 DECL(alcIsAmbisonicFormatSupportedSOFT),
150 DECL(alcDevicePauseSOFT),
151 DECL(alcDeviceResumeSOFT),
153 DECL(alcGetStringiSOFT),
154 DECL(alcResetDeviceSOFT),
156 DECL(alcGetInteger64vSOFT),
158 DECL(alEnable),
159 DECL(alDisable),
160 DECL(alIsEnabled),
161 DECL(alGetString),
162 DECL(alGetBooleanv),
163 DECL(alGetIntegerv),
164 DECL(alGetFloatv),
165 DECL(alGetDoublev),
166 DECL(alGetBoolean),
167 DECL(alGetInteger),
168 DECL(alGetFloat),
169 DECL(alGetDouble),
170 DECL(alGetError),
171 DECL(alIsExtensionPresent),
172 DECL(alGetProcAddress),
173 DECL(alGetEnumValue),
174 DECL(alListenerf),
175 DECL(alListener3f),
176 DECL(alListenerfv),
177 DECL(alListeneri),
178 DECL(alListener3i),
179 DECL(alListeneriv),
180 DECL(alGetListenerf),
181 DECL(alGetListener3f),
182 DECL(alGetListenerfv),
183 DECL(alGetListeneri),
184 DECL(alGetListener3i),
185 DECL(alGetListeneriv),
186 DECL(alGenSources),
187 DECL(alDeleteSources),
188 DECL(alIsSource),
189 DECL(alSourcef),
190 DECL(alSource3f),
191 DECL(alSourcefv),
192 DECL(alSourcei),
193 DECL(alSource3i),
194 DECL(alSourceiv),
195 DECL(alGetSourcef),
196 DECL(alGetSource3f),
197 DECL(alGetSourcefv),
198 DECL(alGetSourcei),
199 DECL(alGetSource3i),
200 DECL(alGetSourceiv),
201 DECL(alSourcePlayv),
202 DECL(alSourceStopv),
203 DECL(alSourceRewindv),
204 DECL(alSourcePausev),
205 DECL(alSourcePlay),
206 DECL(alSourceStop),
207 DECL(alSourceRewind),
208 DECL(alSourcePause),
209 DECL(alSourceQueueBuffers),
210 DECL(alSourceUnqueueBuffers),
211 DECL(alGenBuffers),
212 DECL(alDeleteBuffers),
213 DECL(alIsBuffer),
214 DECL(alBufferData),
215 DECL(alBufferf),
216 DECL(alBuffer3f),
217 DECL(alBufferfv),
218 DECL(alBufferi),
219 DECL(alBuffer3i),
220 DECL(alBufferiv),
221 DECL(alGetBufferf),
222 DECL(alGetBuffer3f),
223 DECL(alGetBufferfv),
224 DECL(alGetBufferi),
225 DECL(alGetBuffer3i),
226 DECL(alGetBufferiv),
227 DECL(alDopplerFactor),
228 DECL(alDopplerVelocity),
229 DECL(alSpeedOfSound),
230 DECL(alDistanceModel),
232 DECL(alGenFilters),
233 DECL(alDeleteFilters),
234 DECL(alIsFilter),
235 DECL(alFilteri),
236 DECL(alFilteriv),
237 DECL(alFilterf),
238 DECL(alFilterfv),
239 DECL(alGetFilteri),
240 DECL(alGetFilteriv),
241 DECL(alGetFilterf),
242 DECL(alGetFilterfv),
243 DECL(alGenEffects),
244 DECL(alDeleteEffects),
245 DECL(alIsEffect),
246 DECL(alEffecti),
247 DECL(alEffectiv),
248 DECL(alEffectf),
249 DECL(alEffectfv),
250 DECL(alGetEffecti),
251 DECL(alGetEffectiv),
252 DECL(alGetEffectf),
253 DECL(alGetEffectfv),
254 DECL(alGenAuxiliaryEffectSlots),
255 DECL(alDeleteAuxiliaryEffectSlots),
256 DECL(alIsAuxiliaryEffectSlot),
257 DECL(alAuxiliaryEffectSloti),
258 DECL(alAuxiliaryEffectSlotiv),
259 DECL(alAuxiliaryEffectSlotf),
260 DECL(alAuxiliaryEffectSlotfv),
261 DECL(alGetAuxiliaryEffectSloti),
262 DECL(alGetAuxiliaryEffectSlotiv),
263 DECL(alGetAuxiliaryEffectSlotf),
264 DECL(alGetAuxiliaryEffectSlotfv),
266 DECL(alDeferUpdatesSOFT),
267 DECL(alProcessUpdatesSOFT),
269 DECL(alSourcedSOFT),
270 DECL(alSource3dSOFT),
271 DECL(alSourcedvSOFT),
272 DECL(alGetSourcedSOFT),
273 DECL(alGetSource3dSOFT),
274 DECL(alGetSourcedvSOFT),
275 DECL(alSourcei64SOFT),
276 DECL(alSource3i64SOFT),
277 DECL(alSourcei64vSOFT),
278 DECL(alGetSourcei64SOFT),
279 DECL(alGetSource3i64SOFT),
280 DECL(alGetSourcei64vSOFT),
282 DECL(alBufferSamplesSOFT),
283 DECL(alGetBufferSamplesSOFT),
284 DECL(alIsBufferFormatSupportedSOFT),
286 DECL(alGetStringiSOFT),
288 #undef DECL
290 #define DECL(x) { #x, (x) }
291 static const struct {
292 const ALCchar *enumName;
293 ALCenum value;
294 } alcEnumerations[] = {
295 DECL(ALC_INVALID),
296 DECL(ALC_FALSE),
297 DECL(ALC_TRUE),
299 DECL(ALC_MAJOR_VERSION),
300 DECL(ALC_MINOR_VERSION),
301 DECL(ALC_ATTRIBUTES_SIZE),
302 DECL(ALC_ALL_ATTRIBUTES),
303 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
304 DECL(ALC_DEVICE_SPECIFIER),
305 DECL(ALC_ALL_DEVICES_SPECIFIER),
306 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
307 DECL(ALC_EXTENSIONS),
308 DECL(ALC_FREQUENCY),
309 DECL(ALC_REFRESH),
310 DECL(ALC_SYNC),
311 DECL(ALC_MONO_SOURCES),
312 DECL(ALC_STEREO_SOURCES),
313 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
314 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
315 DECL(ALC_CAPTURE_SAMPLES),
316 DECL(ALC_CONNECTED),
318 DECL(ALC_EFX_MAJOR_VERSION),
319 DECL(ALC_EFX_MINOR_VERSION),
320 DECL(ALC_MAX_AUXILIARY_SENDS),
322 DECL(ALC_FORMAT_CHANNELS_SOFT),
323 DECL(ALC_FORMAT_TYPE_SOFT),
325 DECL(ALC_MONO_SOFT),
326 DECL(ALC_STEREO_SOFT),
327 DECL(ALC_QUAD_SOFT),
328 DECL(ALC_5POINT1_SOFT),
329 DECL(ALC_6POINT1_SOFT),
330 DECL(ALC_7POINT1_SOFT),
331 DECL(ALC_BFORMAT3D_SOFT),
333 DECL(ALC_BYTE_SOFT),
334 DECL(ALC_UNSIGNED_BYTE_SOFT),
335 DECL(ALC_SHORT_SOFT),
336 DECL(ALC_UNSIGNED_SHORT_SOFT),
337 DECL(ALC_INT_SOFT),
338 DECL(ALC_UNSIGNED_INT_SOFT),
339 DECL(ALC_FLOAT_SOFT),
341 DECL(ALC_HRTF_SOFT),
342 DECL(ALC_DONT_CARE_SOFT),
343 DECL(ALC_HRTF_STATUS_SOFT),
344 DECL(ALC_HRTF_DISABLED_SOFT),
345 DECL(ALC_HRTF_ENABLED_SOFT),
346 DECL(ALC_HRTF_DENIED_SOFT),
347 DECL(ALC_HRTF_REQUIRED_SOFT),
348 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
349 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
350 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
351 DECL(ALC_HRTF_SPECIFIER_SOFT),
352 DECL(ALC_HRTF_ID_SOFT),
354 DECL(ALC_AMBISONIC_LAYOUT_SOFT),
355 DECL(ALC_AMBISONIC_SCALING_SOFT),
356 DECL(ALC_AMBISONIC_ORDER_SOFT),
357 DECL(ALC_ACN_SOFT),
358 DECL(ALC_FUMA_SOFT),
359 DECL(ALC_N3D_SOFT),
360 DECL(ALC_SN3D_SOFT),
362 DECL(ALC_OUTPUT_LIMITER_SOFT),
364 DECL(ALC_NO_ERROR),
365 DECL(ALC_INVALID_DEVICE),
366 DECL(ALC_INVALID_CONTEXT),
367 DECL(ALC_INVALID_ENUM),
368 DECL(ALC_INVALID_VALUE),
369 DECL(ALC_OUT_OF_MEMORY),
372 DECL(AL_INVALID),
373 DECL(AL_NONE),
374 DECL(AL_FALSE),
375 DECL(AL_TRUE),
377 DECL(AL_SOURCE_RELATIVE),
378 DECL(AL_CONE_INNER_ANGLE),
379 DECL(AL_CONE_OUTER_ANGLE),
380 DECL(AL_PITCH),
381 DECL(AL_POSITION),
382 DECL(AL_DIRECTION),
383 DECL(AL_VELOCITY),
384 DECL(AL_LOOPING),
385 DECL(AL_BUFFER),
386 DECL(AL_GAIN),
387 DECL(AL_MIN_GAIN),
388 DECL(AL_MAX_GAIN),
389 DECL(AL_ORIENTATION),
390 DECL(AL_REFERENCE_DISTANCE),
391 DECL(AL_ROLLOFF_FACTOR),
392 DECL(AL_CONE_OUTER_GAIN),
393 DECL(AL_MAX_DISTANCE),
394 DECL(AL_SEC_OFFSET),
395 DECL(AL_SAMPLE_OFFSET),
396 DECL(AL_BYTE_OFFSET),
397 DECL(AL_SOURCE_TYPE),
398 DECL(AL_STATIC),
399 DECL(AL_STREAMING),
400 DECL(AL_UNDETERMINED),
401 DECL(AL_METERS_PER_UNIT),
402 DECL(AL_LOOP_POINTS_SOFT),
403 DECL(AL_DIRECT_CHANNELS_SOFT),
405 DECL(AL_DIRECT_FILTER),
406 DECL(AL_AUXILIARY_SEND_FILTER),
407 DECL(AL_AIR_ABSORPTION_FACTOR),
408 DECL(AL_ROOM_ROLLOFF_FACTOR),
409 DECL(AL_CONE_OUTER_GAINHF),
410 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
412 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
414 DECL(AL_SOURCE_STATE),
415 DECL(AL_INITIAL),
416 DECL(AL_PLAYING),
417 DECL(AL_PAUSED),
418 DECL(AL_STOPPED),
420 DECL(AL_BUFFERS_QUEUED),
421 DECL(AL_BUFFERS_PROCESSED),
423 DECL(AL_FORMAT_MONO8),
424 DECL(AL_FORMAT_MONO16),
425 DECL(AL_FORMAT_MONO_FLOAT32),
426 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
427 DECL(AL_FORMAT_STEREO8),
428 DECL(AL_FORMAT_STEREO16),
429 DECL(AL_FORMAT_STEREO_FLOAT32),
430 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
431 DECL(AL_FORMAT_MONO_IMA4),
432 DECL(AL_FORMAT_STEREO_IMA4),
433 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
434 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
435 DECL(AL_FORMAT_QUAD8_LOKI),
436 DECL(AL_FORMAT_QUAD16_LOKI),
437 DECL(AL_FORMAT_QUAD8),
438 DECL(AL_FORMAT_QUAD16),
439 DECL(AL_FORMAT_QUAD32),
440 DECL(AL_FORMAT_51CHN8),
441 DECL(AL_FORMAT_51CHN16),
442 DECL(AL_FORMAT_51CHN32),
443 DECL(AL_FORMAT_61CHN8),
444 DECL(AL_FORMAT_61CHN16),
445 DECL(AL_FORMAT_61CHN32),
446 DECL(AL_FORMAT_71CHN8),
447 DECL(AL_FORMAT_71CHN16),
448 DECL(AL_FORMAT_71CHN32),
449 DECL(AL_FORMAT_REAR8),
450 DECL(AL_FORMAT_REAR16),
451 DECL(AL_FORMAT_REAR32),
452 DECL(AL_FORMAT_MONO_MULAW),
453 DECL(AL_FORMAT_MONO_MULAW_EXT),
454 DECL(AL_FORMAT_STEREO_MULAW),
455 DECL(AL_FORMAT_STEREO_MULAW_EXT),
456 DECL(AL_FORMAT_QUAD_MULAW),
457 DECL(AL_FORMAT_51CHN_MULAW),
458 DECL(AL_FORMAT_61CHN_MULAW),
459 DECL(AL_FORMAT_71CHN_MULAW),
460 DECL(AL_FORMAT_REAR_MULAW),
461 DECL(AL_FORMAT_MONO_ALAW_EXT),
462 DECL(AL_FORMAT_STEREO_ALAW_EXT),
464 DECL(AL_FORMAT_BFORMAT2D_8),
465 DECL(AL_FORMAT_BFORMAT2D_16),
466 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
467 DECL(AL_FORMAT_BFORMAT2D_MULAW),
468 DECL(AL_FORMAT_BFORMAT3D_8),
469 DECL(AL_FORMAT_BFORMAT3D_16),
470 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
471 DECL(AL_FORMAT_BFORMAT3D_MULAW),
473 DECL(AL_MONO8_SOFT),
474 DECL(AL_MONO16_SOFT),
475 DECL(AL_MONO32F_SOFT),
476 DECL(AL_STEREO8_SOFT),
477 DECL(AL_STEREO16_SOFT),
478 DECL(AL_STEREO32F_SOFT),
479 DECL(AL_QUAD8_SOFT),
480 DECL(AL_QUAD16_SOFT),
481 DECL(AL_QUAD32F_SOFT),
482 DECL(AL_REAR8_SOFT),
483 DECL(AL_REAR16_SOFT),
484 DECL(AL_REAR32F_SOFT),
485 DECL(AL_5POINT1_8_SOFT),
486 DECL(AL_5POINT1_16_SOFT),
487 DECL(AL_5POINT1_32F_SOFT),
488 DECL(AL_6POINT1_8_SOFT),
489 DECL(AL_6POINT1_16_SOFT),
490 DECL(AL_6POINT1_32F_SOFT),
491 DECL(AL_7POINT1_8_SOFT),
492 DECL(AL_7POINT1_16_SOFT),
493 DECL(AL_7POINT1_32F_SOFT),
494 DECL(AL_BFORMAT2D_8_SOFT),
495 DECL(AL_BFORMAT2D_16_SOFT),
496 DECL(AL_BFORMAT2D_32F_SOFT),
497 DECL(AL_BFORMAT3D_8_SOFT),
498 DECL(AL_BFORMAT3D_16_SOFT),
499 DECL(AL_BFORMAT3D_32F_SOFT),
501 DECL(AL_MONO_SOFT),
502 DECL(AL_STEREO_SOFT),
503 DECL(AL_QUAD_SOFT),
504 DECL(AL_REAR_SOFT),
505 DECL(AL_5POINT1_SOFT),
506 DECL(AL_6POINT1_SOFT),
507 DECL(AL_7POINT1_SOFT),
508 DECL(AL_BFORMAT2D_SOFT),
509 DECL(AL_BFORMAT3D_SOFT),
511 DECL(AL_BYTE_SOFT),
512 DECL(AL_UNSIGNED_BYTE_SOFT),
513 DECL(AL_SHORT_SOFT),
514 DECL(AL_UNSIGNED_SHORT_SOFT),
515 DECL(AL_INT_SOFT),
516 DECL(AL_UNSIGNED_INT_SOFT),
517 DECL(AL_FLOAT_SOFT),
518 DECL(AL_DOUBLE_SOFT),
519 DECL(AL_BYTE3_SOFT),
520 DECL(AL_UNSIGNED_BYTE3_SOFT),
521 DECL(AL_MULAW_SOFT),
523 DECL(AL_FREQUENCY),
524 DECL(AL_BITS),
525 DECL(AL_CHANNELS),
526 DECL(AL_SIZE),
527 DECL(AL_INTERNAL_FORMAT_SOFT),
528 DECL(AL_BYTE_LENGTH_SOFT),
529 DECL(AL_SAMPLE_LENGTH_SOFT),
530 DECL(AL_SEC_LENGTH_SOFT),
531 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
532 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
534 DECL(AL_SOURCE_RADIUS),
536 DECL(AL_STEREO_ANGLES),
538 DECL(AL_UNUSED),
539 DECL(AL_PENDING),
540 DECL(AL_PROCESSED),
542 DECL(AL_NO_ERROR),
543 DECL(AL_INVALID_NAME),
544 DECL(AL_INVALID_ENUM),
545 DECL(AL_INVALID_VALUE),
546 DECL(AL_INVALID_OPERATION),
547 DECL(AL_OUT_OF_MEMORY),
549 DECL(AL_VENDOR),
550 DECL(AL_VERSION),
551 DECL(AL_RENDERER),
552 DECL(AL_EXTENSIONS),
554 DECL(AL_DOPPLER_FACTOR),
555 DECL(AL_DOPPLER_VELOCITY),
556 DECL(AL_DISTANCE_MODEL),
557 DECL(AL_SPEED_OF_SOUND),
558 DECL(AL_SOURCE_DISTANCE_MODEL),
559 DECL(AL_DEFERRED_UPDATES_SOFT),
560 DECL(AL_GAIN_LIMIT_SOFT),
562 DECL(AL_INVERSE_DISTANCE),
563 DECL(AL_INVERSE_DISTANCE_CLAMPED),
564 DECL(AL_LINEAR_DISTANCE),
565 DECL(AL_LINEAR_DISTANCE_CLAMPED),
566 DECL(AL_EXPONENT_DISTANCE),
567 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
569 DECL(AL_FILTER_TYPE),
570 DECL(AL_FILTER_NULL),
571 DECL(AL_FILTER_LOWPASS),
572 DECL(AL_FILTER_HIGHPASS),
573 DECL(AL_FILTER_BANDPASS),
575 DECL(AL_LOWPASS_GAIN),
576 DECL(AL_LOWPASS_GAINHF),
578 DECL(AL_HIGHPASS_GAIN),
579 DECL(AL_HIGHPASS_GAINLF),
581 DECL(AL_BANDPASS_GAIN),
582 DECL(AL_BANDPASS_GAINHF),
583 DECL(AL_BANDPASS_GAINLF),
585 DECL(AL_EFFECT_TYPE),
586 DECL(AL_EFFECT_NULL),
587 DECL(AL_EFFECT_REVERB),
588 DECL(AL_EFFECT_EAXREVERB),
589 DECL(AL_EFFECT_CHORUS),
590 DECL(AL_EFFECT_DISTORTION),
591 DECL(AL_EFFECT_ECHO),
592 DECL(AL_EFFECT_FLANGER),
593 #if 0
594 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
595 DECL(AL_EFFECT_VOCAL_MORPHER),
596 DECL(AL_EFFECT_PITCH_SHIFTER),
597 #endif
598 DECL(AL_EFFECT_RING_MODULATOR),
599 #if 0
600 DECL(AL_EFFECT_AUTOWAH),
601 #endif
602 DECL(AL_EFFECT_COMPRESSOR),
603 DECL(AL_EFFECT_EQUALIZER),
604 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
605 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
607 DECL(AL_EFFECTSLOT_EFFECT),
608 DECL(AL_EFFECTSLOT_GAIN),
609 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
610 DECL(AL_EFFECTSLOT_NULL),
612 DECL(AL_EAXREVERB_DENSITY),
613 DECL(AL_EAXREVERB_DIFFUSION),
614 DECL(AL_EAXREVERB_GAIN),
615 DECL(AL_EAXREVERB_GAINHF),
616 DECL(AL_EAXREVERB_GAINLF),
617 DECL(AL_EAXREVERB_DECAY_TIME),
618 DECL(AL_EAXREVERB_DECAY_HFRATIO),
619 DECL(AL_EAXREVERB_DECAY_LFRATIO),
620 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
621 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
622 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
623 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
624 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
625 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
626 DECL(AL_EAXREVERB_ECHO_TIME),
627 DECL(AL_EAXREVERB_ECHO_DEPTH),
628 DECL(AL_EAXREVERB_MODULATION_TIME),
629 DECL(AL_EAXREVERB_MODULATION_DEPTH),
630 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
631 DECL(AL_EAXREVERB_HFREFERENCE),
632 DECL(AL_EAXREVERB_LFREFERENCE),
633 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
634 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
636 DECL(AL_REVERB_DENSITY),
637 DECL(AL_REVERB_DIFFUSION),
638 DECL(AL_REVERB_GAIN),
639 DECL(AL_REVERB_GAINHF),
640 DECL(AL_REVERB_DECAY_TIME),
641 DECL(AL_REVERB_DECAY_HFRATIO),
642 DECL(AL_REVERB_REFLECTIONS_GAIN),
643 DECL(AL_REVERB_REFLECTIONS_DELAY),
644 DECL(AL_REVERB_LATE_REVERB_GAIN),
645 DECL(AL_REVERB_LATE_REVERB_DELAY),
646 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
647 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
648 DECL(AL_REVERB_DECAY_HFLIMIT),
650 DECL(AL_CHORUS_WAVEFORM),
651 DECL(AL_CHORUS_PHASE),
652 DECL(AL_CHORUS_RATE),
653 DECL(AL_CHORUS_DEPTH),
654 DECL(AL_CHORUS_FEEDBACK),
655 DECL(AL_CHORUS_DELAY),
657 DECL(AL_DISTORTION_EDGE),
658 DECL(AL_DISTORTION_GAIN),
659 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
660 DECL(AL_DISTORTION_EQCENTER),
661 DECL(AL_DISTORTION_EQBANDWIDTH),
663 DECL(AL_ECHO_DELAY),
664 DECL(AL_ECHO_LRDELAY),
665 DECL(AL_ECHO_DAMPING),
666 DECL(AL_ECHO_FEEDBACK),
667 DECL(AL_ECHO_SPREAD),
669 DECL(AL_FLANGER_WAVEFORM),
670 DECL(AL_FLANGER_PHASE),
671 DECL(AL_FLANGER_RATE),
672 DECL(AL_FLANGER_DEPTH),
673 DECL(AL_FLANGER_FEEDBACK),
674 DECL(AL_FLANGER_DELAY),
676 DECL(AL_RING_MODULATOR_FREQUENCY),
677 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
678 DECL(AL_RING_MODULATOR_WAVEFORM),
680 DECL(AL_COMPRESSOR_ONOFF),
682 DECL(AL_EQUALIZER_LOW_GAIN),
683 DECL(AL_EQUALIZER_LOW_CUTOFF),
684 DECL(AL_EQUALIZER_MID1_GAIN),
685 DECL(AL_EQUALIZER_MID1_CENTER),
686 DECL(AL_EQUALIZER_MID1_WIDTH),
687 DECL(AL_EQUALIZER_MID2_GAIN),
688 DECL(AL_EQUALIZER_MID2_CENTER),
689 DECL(AL_EQUALIZER_MID2_WIDTH),
690 DECL(AL_EQUALIZER_HIGH_GAIN),
691 DECL(AL_EQUALIZER_HIGH_CUTOFF),
693 DECL(AL_DEDICATED_GAIN),
695 DECL(AL_NUM_RESAMPLERS_SOFT),
696 DECL(AL_DEFAULT_RESAMPLER_SOFT),
697 DECL(AL_SOURCE_RESAMPLER_SOFT),
698 DECL(AL_RESAMPLER_NAME_SOFT),
700 DECL(AL_SOURCE_SPATIALIZE_SOFT),
701 DECL(AL_AUTO_SOFT),
703 #undef DECL
705 static const ALCchar alcNoError[] = "No Error";
706 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
707 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
708 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
709 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
710 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
713 /************************************************
714 * Global variables
715 ************************************************/
717 /* Enumerated device names */
718 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
720 static al_string alcAllDevicesList;
721 static al_string alcCaptureDeviceList;
723 /* Default is always the first in the list */
724 static ALCchar *alcDefaultAllDevicesSpecifier;
725 static ALCchar *alcCaptureDefaultDeviceSpecifier;
727 /* Default context extensions */
728 static const ALchar alExtList[] =
729 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
730 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
731 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
732 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
733 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
734 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
735 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length "
736 "AL_SOFT_source_resampler AL_SOFT_source_spatialize";
738 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
740 /* Thread-local current context */
741 static altss_t LocalContext;
742 /* Process-wide current context */
743 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
745 /* Mixing thread piority level */
746 ALint RTPrioLevel;
748 FILE *LogFile;
749 #ifdef _DEBUG
750 enum LogLevel LogLevel = LogWarning;
751 #else
752 enum LogLevel LogLevel = LogError;
753 #endif
755 /* Flag to trap ALC device errors */
756 static ALCboolean TrapALCError = ALC_FALSE;
758 /* One-time configuration init control */
759 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
761 /* Default effect that applies to sources that don't have an effect on send 0 */
762 static ALeffect DefaultEffect;
764 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
765 * updates.
767 static ALCboolean SuspendDefers = ALC_TRUE;
770 /************************************************
771 * ALC information
772 ************************************************/
773 static const ALCchar alcNoDeviceExtList[] =
774 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
775 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
776 static const ALCchar alcExtensionList[] =
777 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
778 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
779 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
780 "ALC_SOFT_loopback ALC_SOFT_output_limiter ALC_SOFT_pause_device";
781 static const ALCint alcMajorVersion = 1;
782 static const ALCint alcMinorVersion = 1;
784 static const ALCint alcEFXMajorVersion = 1;
785 static const ALCint alcEFXMinorVersion = 0;
788 /************************************************
789 * Device lists
790 ************************************************/
791 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
793 static almtx_t ListLock;
794 static inline void LockLists(void)
796 int ret = almtx_lock(&ListLock);
797 assert(ret == althrd_success);
799 static inline void UnlockLists(void)
801 int ret = almtx_unlock(&ListLock);
802 assert(ret == althrd_success);
805 /************************************************
806 * Library initialization
807 ************************************************/
808 #if defined(_WIN32)
809 static void alc_init(void);
810 static void alc_deinit(void);
811 static void alc_deinit_safe(void);
813 #ifndef AL_LIBTYPE_STATIC
814 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
816 switch(reason)
818 case DLL_PROCESS_ATTACH:
819 /* Pin the DLL so we won't get unloaded until the process terminates */
820 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
821 (WCHAR*)hModule, &hModule);
822 alc_init();
823 break;
825 case DLL_THREAD_DETACH:
826 break;
828 case DLL_PROCESS_DETACH:
829 if(!lpReserved)
830 alc_deinit();
831 else
832 alc_deinit_safe();
833 break;
835 return TRUE;
837 #elif defined(_MSC_VER)
838 #pragma section(".CRT$XCU",read)
839 static void alc_constructor(void);
840 static void alc_destructor(void);
841 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
843 static void alc_constructor(void)
845 atexit(alc_destructor);
846 alc_init();
849 static void alc_destructor(void)
851 alc_deinit();
853 #elif defined(HAVE_GCC_DESTRUCTOR)
854 static void alc_init(void) __attribute__((constructor));
855 static void alc_deinit(void) __attribute__((destructor));
856 #else
857 #error "No static initialization available on this platform!"
858 #endif
860 #elif defined(HAVE_GCC_DESTRUCTOR)
862 static void alc_init(void) __attribute__((constructor));
863 static void alc_deinit(void) __attribute__((destructor));
865 #else
866 #error "No global initialization available on this platform!"
867 #endif
869 static void ReleaseThreadCtx(void *ptr);
870 static void alc_init(void)
872 const char *str;
873 int ret;
875 LogFile = stderr;
877 AL_STRING_INIT(alcAllDevicesList);
878 AL_STRING_INIT(alcCaptureDeviceList);
880 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
881 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
882 ConeScale *= 0.5f;
884 str = getenv("__ALSOFT_REVERSE_Z");
885 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
886 ZScale *= -1.0f;
888 str = getenv("__ALSOFT_REVERB_IGNORES_SOUND_SPEED");
889 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
890 OverrideReverbSpeedOfSound = AL_TRUE;
892 ret = altss_create(&LocalContext, ReleaseThreadCtx);
893 assert(ret == althrd_success);
895 ret = almtx_init(&ListLock, almtx_recursive);
896 assert(ret == althrd_success);
898 ThunkInit();
901 static void alc_initconfig(void)
903 const char *devs, *str;
904 ALuint capfilter;
905 float valf;
906 int i, n;
908 str = getenv("ALSOFT_LOGLEVEL");
909 if(str)
911 long lvl = strtol(str, NULL, 0);
912 if(lvl >= NoLog && lvl <= LogRef)
913 LogLevel = lvl;
916 str = getenv("ALSOFT_LOGFILE");
917 if(str && str[0])
919 FILE *logfile = al_fopen(str, "wt");
920 if(logfile) LogFile = logfile;
921 else ERR("Failed to open log file '%s'\n", str);
924 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION,
925 ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
927 char buf[1024] = "";
928 int len = 0;
930 if(BackendListSize > 0)
931 len += snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
932 for(i = 1;i < BackendListSize;i++)
933 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
934 TRACE("Supported backends: %s\n", buf);
936 ReadALConfig();
938 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
939 if(str && *str)
941 if(strcasecmp(str, "ignore") == 0)
943 SuspendDefers = ALC_FALSE;
944 TRACE("Selected context suspend behavior, \"ignore\"\n");
946 else
947 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
950 capfilter = 0;
951 #if defined(HAVE_SSE4_1)
952 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
953 #elif defined(HAVE_SSE3)
954 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
955 #elif defined(HAVE_SSE2)
956 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
957 #elif defined(HAVE_SSE)
958 capfilter |= CPU_CAP_SSE;
959 #endif
960 #ifdef HAVE_NEON
961 capfilter |= CPU_CAP_NEON;
962 #endif
963 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
965 if(strcasecmp(str, "all") == 0)
966 capfilter = 0;
967 else
969 size_t len;
970 const char *next = str;
972 do {
973 str = next;
974 while(isspace(str[0]))
975 str++;
976 next = strchr(str, ',');
978 if(!str[0] || str[0] == ',')
979 continue;
981 len = (next ? ((size_t)(next-str)) : strlen(str));
982 while(len > 0 && isspace(str[len-1]))
983 len--;
984 if(len == 3 && strncasecmp(str, "sse", len) == 0)
985 capfilter &= ~CPU_CAP_SSE;
986 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
987 capfilter &= ~CPU_CAP_SSE2;
988 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
989 capfilter &= ~CPU_CAP_SSE3;
990 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
991 capfilter &= ~CPU_CAP_SSE4_1;
992 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
993 capfilter &= ~CPU_CAP_NEON;
994 else
995 WARN("Invalid CPU extension \"%s\"\n", str);
996 } while(next++);
999 FillCPUCaps(capfilter);
1001 #ifdef _WIN32
1002 RTPrioLevel = 1;
1003 #else
1004 RTPrioLevel = 0;
1005 #endif
1006 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
1008 aluInit();
1009 aluInitMixer();
1011 str = getenv("ALSOFT_TRAP_ERROR");
1012 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1014 TrapALError = AL_TRUE;
1015 TrapALCError = AL_TRUE;
1017 else
1019 str = getenv("ALSOFT_TRAP_AL_ERROR");
1020 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1021 TrapALError = AL_TRUE;
1022 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1024 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1025 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1026 TrapALCError = ALC_TRUE;
1027 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1030 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1031 ReverbBoost *= powf(10.0f, valf / 20.0f);
1033 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1035 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1036 ConfigValueStr(NULL, NULL, "drivers", &devs))
1038 int n;
1039 size_t len;
1040 const char *next = devs;
1041 int endlist, delitem;
1043 i = 0;
1044 do {
1045 devs = next;
1046 while(isspace(devs[0]))
1047 devs++;
1048 next = strchr(devs, ',');
1050 delitem = (devs[0] == '-');
1051 if(devs[0] == '-') devs++;
1053 if(!devs[0] || devs[0] == ',')
1055 endlist = 0;
1056 continue;
1058 endlist = 1;
1060 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1061 while(len > 0 && isspace(devs[len-1]))
1062 len--;
1063 for(n = i;n < BackendListSize;n++)
1065 if(len == strlen(BackendList[n].name) &&
1066 strncmp(BackendList[n].name, devs, len) == 0)
1068 if(delitem)
1070 for(;n+1 < BackendListSize;n++)
1071 BackendList[n] = BackendList[n+1];
1072 BackendListSize--;
1074 else
1076 struct BackendInfo Bkp = BackendList[n];
1077 for(;n > i;n--)
1078 BackendList[n] = BackendList[n-1];
1079 BackendList[n] = Bkp;
1081 i++;
1083 break;
1086 } while(next++);
1088 if(endlist)
1089 BackendListSize = i;
1092 for(i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1094 ALCbackendFactory *factory = BackendList[i].getFactory();
1095 if(!V0(factory,init)())
1097 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1098 continue;
1101 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1102 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1104 PlaybackBackend = BackendList[i];
1105 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1107 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1109 CaptureBackend = BackendList[i];
1110 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1114 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1115 V0(factory,init)();
1118 if(!PlaybackBackend.name)
1119 WARN("No playback backend available!\n");
1120 if(!CaptureBackend.name)
1121 WARN("No capture backend available!\n");
1123 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1125 size_t len;
1126 const char *next = str;
1128 do {
1129 str = next;
1130 next = strchr(str, ',');
1132 if(!str[0] || next == str)
1133 continue;
1135 len = (next ? ((size_t)(next-str)) : strlen(str));
1136 for(n = 0;EffectList[n].name;n++)
1138 if(len == strlen(EffectList[n].name) &&
1139 strncmp(EffectList[n].name, str, len) == 0)
1140 DisabledEffects[EffectList[n].type] = AL_TRUE;
1142 } while(next++);
1145 InitEffectFactoryMap();
1147 InitEffect(&DefaultEffect);
1148 str = getenv("ALSOFT_DEFAULT_REVERB");
1149 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1150 LoadReverbPreset(str, &DefaultEffect);
1152 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1154 #ifdef __ANDROID__
1155 #include <jni.h>
1157 static JavaVM *gJavaVM;
1158 static pthread_key_t gJVMThreadKey;
1160 static void CleanupJNIEnv(void* UNUSED(ptr))
1162 JCALL0(gJavaVM,DetachCurrentThread)();
1165 void *Android_GetJNIEnv(void)
1167 if(!gJavaVM)
1169 WARN("gJavaVM is NULL!\n");
1170 return NULL;
1173 /* http://developer.android.com/guide/practices/jni.html
1175 * All threads are Linux threads, scheduled by the kernel. They're usually
1176 * started from managed code (using Thread.start), but they can also be
1177 * created elsewhere and then attached to the JavaVM. For example, a thread
1178 * started with pthread_create can be attached with the JNI
1179 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1180 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1181 * Attaching a natively-created thread causes a java.lang.Thread object to
1182 * be constructed and added to the "main" ThreadGroup, making it visible to
1183 * the debugger. Calling AttachCurrentThread on an already-attached thread
1184 * is a no-op.
1186 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1187 if(!env)
1189 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1190 if(status < 0)
1192 ERR("Failed to attach current thread\n");
1193 return NULL;
1195 pthread_setspecific(gJVMThreadKey, env);
1197 return env;
1200 /* Automatically called by JNI. */
1201 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1203 void *env;
1204 int err;
1206 gJavaVM = jvm;
1207 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1209 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1210 return JNI_ERR;
1213 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1214 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1216 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1217 ERR("pthread_key_create failed: %d\n", err);
1218 pthread_setspecific(gJVMThreadKey, env);
1219 return JNI_VERSION_1_4;
1221 #endif
1224 /************************************************
1225 * Library deinitialization
1226 ************************************************/
1227 static void alc_cleanup(void)
1229 ALCdevice *dev;
1231 AL_STRING_DEINIT(alcAllDevicesList);
1232 AL_STRING_DEINIT(alcCaptureDeviceList);
1234 free(alcDefaultAllDevicesSpecifier);
1235 alcDefaultAllDevicesSpecifier = NULL;
1236 free(alcCaptureDefaultDeviceSpecifier);
1237 alcCaptureDefaultDeviceSpecifier = NULL;
1239 if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL)
1241 ALCuint num = 0;
1242 do {
1243 num++;
1244 } while((dev=dev->next) != NULL);
1245 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1248 DeinitEffectFactoryMap();
1251 static void alc_deinit_safe(void)
1253 alc_cleanup();
1255 FreeHrtfs();
1256 FreeALConfig();
1258 ThunkExit();
1259 almtx_destroy(&ListLock);
1260 altss_delete(LocalContext);
1262 if(LogFile != stderr)
1263 fclose(LogFile);
1264 LogFile = NULL;
1267 static void alc_deinit(void)
1269 int i;
1271 alc_cleanup();
1273 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1274 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1276 for(i = 0;i < BackendListSize;i++)
1278 ALCbackendFactory *factory = BackendList[i].getFactory();
1279 V0(factory,deinit)();
1282 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1283 V0(factory,deinit)();
1286 alc_deinit_safe();
1290 /************************************************
1291 * Device enumeration
1292 ************************************************/
1293 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1295 ALCbackendFactory *factory;
1297 DO_INITCONFIG();
1299 LockLists();
1300 alstr_clear(list);
1302 factory = backendinfo->getFactory();
1303 V(factory,probe)(type);
1305 UnlockLists();
1307 static void ProbeAllDevicesList(void)
1308 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1309 static void ProbeCaptureDeviceList(void)
1310 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1312 static void AppendDevice(const ALCchar *name, al_string *devnames)
1314 size_t len = strlen(name);
1315 if(len > 0)
1316 alstr_append_range(devnames, name, name+len+1);
1318 void AppendAllDevicesList(const ALCchar *name)
1319 { AppendDevice(name, &alcAllDevicesList); }
1320 void AppendCaptureDeviceList(const ALCchar *name)
1321 { AppendDevice(name, &alcCaptureDeviceList); }
1324 /************************************************
1325 * Device format information
1326 ************************************************/
1327 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1329 switch(type)
1331 case DevFmtByte: return "Signed Byte";
1332 case DevFmtUByte: return "Unsigned Byte";
1333 case DevFmtShort: return "Signed Short";
1334 case DevFmtUShort: return "Unsigned Short";
1335 case DevFmtInt: return "Signed Int";
1336 case DevFmtUInt: return "Unsigned Int";
1337 case DevFmtFloat: return "Float";
1339 return "(unknown type)";
1341 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1343 switch(chans)
1345 case DevFmtMono: return "Mono";
1346 case DevFmtStereo: return "Stereo";
1347 case DevFmtQuad: return "Quadraphonic";
1348 case DevFmtX51: return "5.1 Surround";
1349 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1350 case DevFmtX61: return "6.1 Surround";
1351 case DevFmtX71: return "7.1 Surround";
1352 case DevFmtAmbi3D: return "Ambisonic 3D";
1354 return "(unknown channels)";
1357 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder);
1358 ALsizei BytesFromDevFmt(enum DevFmtType type)
1360 switch(type)
1362 case DevFmtByte: return sizeof(ALbyte);
1363 case DevFmtUByte: return sizeof(ALubyte);
1364 case DevFmtShort: return sizeof(ALshort);
1365 case DevFmtUShort: return sizeof(ALushort);
1366 case DevFmtInt: return sizeof(ALint);
1367 case DevFmtUInt: return sizeof(ALuint);
1368 case DevFmtFloat: return sizeof(ALfloat);
1370 return 0;
1372 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder)
1374 switch(chans)
1376 case DevFmtMono: return 1;
1377 case DevFmtStereo: return 2;
1378 case DevFmtQuad: return 4;
1379 case DevFmtX51: return 6;
1380 case DevFmtX51Rear: return 6;
1381 case DevFmtX61: return 7;
1382 case DevFmtX71: return 8;
1383 case DevFmtAmbi3D: return (ambiorder >= 3) ? 16 :
1384 (ambiorder == 2) ? 9 :
1385 (ambiorder == 1) ? 4 : 1;
1387 return 0;
1390 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1391 enum DevFmtType *type)
1393 static const struct {
1394 ALenum format;
1395 enum DevFmtChannels channels;
1396 enum DevFmtType type;
1397 } list[] = {
1398 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1399 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1400 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1402 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1403 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1404 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1406 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1407 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1408 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1410 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1411 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1412 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1414 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1415 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1416 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1418 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1419 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1420 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1422 ALuint i;
1424 for(i = 0;i < COUNTOF(list);i++)
1426 if(list[i].format == format)
1428 *chans = list[i].channels;
1429 *type = list[i].type;
1430 return AL_TRUE;
1434 return AL_FALSE;
1437 static ALCboolean IsValidALCType(ALCenum type)
1439 switch(type)
1441 case ALC_BYTE_SOFT:
1442 case ALC_UNSIGNED_BYTE_SOFT:
1443 case ALC_SHORT_SOFT:
1444 case ALC_UNSIGNED_SHORT_SOFT:
1445 case ALC_INT_SOFT:
1446 case ALC_UNSIGNED_INT_SOFT:
1447 case ALC_FLOAT_SOFT:
1448 return ALC_TRUE;
1450 return ALC_FALSE;
1453 static ALCboolean IsValidALCChannels(ALCenum channels)
1455 switch(channels)
1457 case ALC_MONO_SOFT:
1458 case ALC_STEREO_SOFT:
1459 case ALC_QUAD_SOFT:
1460 case ALC_5POINT1_SOFT:
1461 case ALC_6POINT1_SOFT:
1462 case ALC_7POINT1_SOFT:
1463 case ALC_BFORMAT3D_SOFT:
1464 return ALC_TRUE;
1466 return ALC_FALSE;
1469 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1471 switch(layout)
1473 case ALC_ACN_SOFT:
1474 case ALC_FUMA_SOFT:
1475 return ALC_TRUE;
1477 return ALC_FALSE;
1480 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1482 switch(scaling)
1484 case ALC_N3D_SOFT:
1485 case ALC_SN3D_SOFT:
1486 case ALC_FUMA_SOFT:
1487 return ALC_TRUE;
1489 return ALC_FALSE;
1492 /************************************************
1493 * Miscellaneous ALC helpers
1494 ************************************************/
1496 void ALCdevice_Lock(ALCdevice *device)
1498 V0(device->Backend,lock)();
1501 void ALCdevice_Unlock(ALCdevice *device)
1503 V0(device->Backend,unlock)();
1507 /* SetDefaultWFXChannelOrder
1509 * Sets the default channel order used by WaveFormatEx.
1511 void SetDefaultWFXChannelOrder(ALCdevice *device)
1513 ALsizei i;
1515 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1516 device->RealOut.ChannelName[i] = InvalidChannel;
1518 switch(device->FmtChans)
1520 case DevFmtMono:
1521 device->RealOut.ChannelName[0] = FrontCenter;
1522 break;
1523 case DevFmtStereo:
1524 device->RealOut.ChannelName[0] = FrontLeft;
1525 device->RealOut.ChannelName[1] = FrontRight;
1526 break;
1527 case DevFmtQuad:
1528 device->RealOut.ChannelName[0] = FrontLeft;
1529 device->RealOut.ChannelName[1] = FrontRight;
1530 device->RealOut.ChannelName[2] = BackLeft;
1531 device->RealOut.ChannelName[3] = BackRight;
1532 break;
1533 case DevFmtX51:
1534 device->RealOut.ChannelName[0] = FrontLeft;
1535 device->RealOut.ChannelName[1] = FrontRight;
1536 device->RealOut.ChannelName[2] = FrontCenter;
1537 device->RealOut.ChannelName[3] = LFE;
1538 device->RealOut.ChannelName[4] = SideLeft;
1539 device->RealOut.ChannelName[5] = SideRight;
1540 break;
1541 case DevFmtX51Rear:
1542 device->RealOut.ChannelName[0] = FrontLeft;
1543 device->RealOut.ChannelName[1] = FrontRight;
1544 device->RealOut.ChannelName[2] = FrontCenter;
1545 device->RealOut.ChannelName[3] = LFE;
1546 device->RealOut.ChannelName[4] = BackLeft;
1547 device->RealOut.ChannelName[5] = BackRight;
1548 break;
1549 case DevFmtX61:
1550 device->RealOut.ChannelName[0] = FrontLeft;
1551 device->RealOut.ChannelName[1] = FrontRight;
1552 device->RealOut.ChannelName[2] = FrontCenter;
1553 device->RealOut.ChannelName[3] = LFE;
1554 device->RealOut.ChannelName[4] = BackCenter;
1555 device->RealOut.ChannelName[5] = SideLeft;
1556 device->RealOut.ChannelName[6] = SideRight;
1557 break;
1558 case DevFmtX71:
1559 device->RealOut.ChannelName[0] = FrontLeft;
1560 device->RealOut.ChannelName[1] = FrontRight;
1561 device->RealOut.ChannelName[2] = FrontCenter;
1562 device->RealOut.ChannelName[3] = LFE;
1563 device->RealOut.ChannelName[4] = BackLeft;
1564 device->RealOut.ChannelName[5] = BackRight;
1565 device->RealOut.ChannelName[6] = SideLeft;
1566 device->RealOut.ChannelName[7] = SideRight;
1567 break;
1568 case DevFmtAmbi3D:
1569 device->RealOut.ChannelName[0] = Aux0;
1570 if(device->AmbiOrder > 0)
1572 device->RealOut.ChannelName[1] = Aux1;
1573 device->RealOut.ChannelName[2] = Aux2;
1574 device->RealOut.ChannelName[3] = Aux3;
1576 if(device->AmbiOrder > 1)
1578 device->RealOut.ChannelName[4] = Aux4;
1579 device->RealOut.ChannelName[5] = Aux5;
1580 device->RealOut.ChannelName[6] = Aux6;
1581 device->RealOut.ChannelName[7] = Aux7;
1582 device->RealOut.ChannelName[8] = Aux8;
1584 if(device->AmbiOrder > 2)
1586 device->RealOut.ChannelName[9] = Aux9;
1587 device->RealOut.ChannelName[10] = Aux10;
1588 device->RealOut.ChannelName[11] = Aux11;
1589 device->RealOut.ChannelName[12] = Aux12;
1590 device->RealOut.ChannelName[13] = Aux13;
1591 device->RealOut.ChannelName[14] = Aux14;
1592 device->RealOut.ChannelName[15] = Aux15;
1594 break;
1598 /* SetDefaultChannelOrder
1600 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1602 void SetDefaultChannelOrder(ALCdevice *device)
1604 ALsizei i;
1606 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1607 device->RealOut.ChannelName[i] = InvalidChannel;
1609 switch(device->FmtChans)
1611 case DevFmtX51Rear:
1612 device->RealOut.ChannelName[0] = FrontLeft;
1613 device->RealOut.ChannelName[1] = FrontRight;
1614 device->RealOut.ChannelName[2] = BackLeft;
1615 device->RealOut.ChannelName[3] = BackRight;
1616 device->RealOut.ChannelName[4] = FrontCenter;
1617 device->RealOut.ChannelName[5] = LFE;
1618 return;
1619 case DevFmtX71:
1620 device->RealOut.ChannelName[0] = FrontLeft;
1621 device->RealOut.ChannelName[1] = FrontRight;
1622 device->RealOut.ChannelName[2] = BackLeft;
1623 device->RealOut.ChannelName[3] = BackRight;
1624 device->RealOut.ChannelName[4] = FrontCenter;
1625 device->RealOut.ChannelName[5] = LFE;
1626 device->RealOut.ChannelName[6] = SideLeft;
1627 device->RealOut.ChannelName[7] = SideRight;
1628 return;
1630 /* Same as WFX order */
1631 case DevFmtMono:
1632 case DevFmtStereo:
1633 case DevFmtQuad:
1634 case DevFmtX51:
1635 case DevFmtX61:
1636 case DevFmtAmbi3D:
1637 SetDefaultWFXChannelOrder(device);
1638 break;
1642 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1645 /* ALCcontext_DeferUpdates
1647 * Defers/suspends updates for the given context's listener and sources. This
1648 * does *NOT* stop mixing, but rather prevents certain property changes from
1649 * taking effect.
1651 void ALCcontext_DeferUpdates(ALCcontext *context)
1653 ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE);
1656 /* ALCcontext_ProcessUpdates
1658 * Resumes update processing after being deferred.
1660 void ALCcontext_ProcessUpdates(ALCcontext *context)
1662 ReadLock(&context->PropLock);
1663 if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
1665 /* Tell the mixer to stop applying updates, then wait for any active
1666 * updating to finish, before providing updates.
1668 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1669 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1670 althrd_yield();
1672 if(!ATOMIC_FLAG_TEST_AND_SET(&context->PropsClean, almemory_order_acq_rel))
1673 UpdateContextProps(context);
1674 if(!ATOMIC_FLAG_TEST_AND_SET(&context->Listener->PropsClean, almemory_order_acq_rel))
1675 UpdateListenerProps(context);
1676 UpdateAllEffectSlotProps(context);
1677 UpdateAllSourceProps(context);
1679 /* Now with all updates declared, let the mixer continue applying them
1680 * so they all happen at once.
1682 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1684 ReadUnlock(&context->PropLock);
1688 /* alcSetError
1690 * Stores the latest ALC device error
1692 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1694 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1695 if(TrapALCError)
1697 #ifdef _WIN32
1698 /* DebugBreak() will cause an exception if there is no debugger */
1699 if(IsDebuggerPresent())
1700 DebugBreak();
1701 #elif defined(SIGTRAP)
1702 raise(SIGTRAP);
1703 #endif
1706 if(device)
1707 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1708 else
1709 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1713 struct Compressor *CreateDeviceLimiter(const ALCdevice *device)
1715 return CompressorInit(0.0f, 0.0f, AL_FALSE, AL_TRUE, 0.0f, 0.0f, 0.5f, 2.0f,
1716 0.0f, -3.0f, 3.0f, device->Frequency);
1719 /* UpdateClockBase
1721 * Updates the device's base clock time with however many samples have been
1722 * done. This is used so frequency changes on the device don't cause the time
1723 * to jump forward or back. Must not be called while the device is running/
1724 * mixing.
1726 static inline void UpdateClockBase(ALCdevice *device)
1728 IncrementRef(&device->MixCount);
1729 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1730 device->SamplesDone = 0;
1731 IncrementRef(&device->MixCount);
1734 /* UpdateDeviceParams
1736 * Updates device parameters according to the attribute list (caller is
1737 * responsible for holding the list lock).
1739 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1741 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1742 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1743 ALCenum gainLimiter = device->Limiter ? ALC_TRUE : ALC_FALSE;
1744 const ALsizei old_sends = device->NumAuxSends;
1745 ALsizei new_sends = device->NumAuxSends;
1746 enum DevFmtChannels oldChans;
1747 enum DevFmtType oldType;
1748 ALboolean update_failed;
1749 ALCsizei hrtf_id = -1;
1750 ALCcontext *context;
1751 ALCuint oldFreq;
1752 size_t size;
1753 ALCsizei i;
1754 int val;
1756 // Check for attributes
1757 if(device->Type == Loopback)
1759 ALCsizei numMono, numStereo, numSends;
1760 ALCenum alayout = AL_NONE;
1761 ALCenum ascale = AL_NONE;
1762 ALCenum schans = AL_NONE;
1763 ALCenum stype = AL_NONE;
1764 ALCsizei attrIdx = 0;
1765 ALCsizei aorder = 0;
1766 ALCuint freq = 0;
1768 if(!attrList)
1770 WARN("Missing attributes for loopback device\n");
1771 return ALC_INVALID_VALUE;
1774 numMono = device->NumMonoSources;
1775 numStereo = device->NumStereoSources;
1776 numSends = old_sends;
1778 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1779 while(attrList[attrIdx])
1781 switch(attrList[attrIdx])
1783 case ALC_FORMAT_CHANNELS_SOFT:
1784 schans = attrList[attrIdx + 1];
1785 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1786 if(!IsValidALCChannels(schans))
1787 return ALC_INVALID_VALUE;
1788 break;
1790 case ALC_FORMAT_TYPE_SOFT:
1791 stype = attrList[attrIdx + 1];
1792 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1793 if(!IsValidALCType(stype))
1794 return ALC_INVALID_VALUE;
1795 break;
1797 case ALC_FREQUENCY:
1798 freq = attrList[attrIdx + 1];
1799 TRACE_ATTR(ALC_FREQUENCY, freq);
1800 if(freq < MIN_OUTPUT_RATE)
1801 return ALC_INVALID_VALUE;
1802 break;
1804 case ALC_AMBISONIC_LAYOUT_SOFT:
1805 alayout = attrList[attrIdx + 1];
1806 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1807 if(!IsValidAmbiLayout(alayout))
1808 return ALC_INVALID_VALUE;
1809 break;
1811 case ALC_AMBISONIC_SCALING_SOFT:
1812 ascale = attrList[attrIdx + 1];
1813 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1814 if(!IsValidAmbiScaling(ascale))
1815 return ALC_INVALID_VALUE;
1816 break;
1818 case ALC_AMBISONIC_ORDER_SOFT:
1819 aorder = attrList[attrIdx + 1];
1820 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1821 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1822 return ALC_INVALID_VALUE;
1823 break;
1825 case ALC_MONO_SOURCES:
1826 numMono = attrList[attrIdx + 1];
1827 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1828 numMono = maxi(numMono, 0);
1829 break;
1831 case ALC_STEREO_SOURCES:
1832 numStereo = attrList[attrIdx + 1];
1833 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1834 numStereo = maxi(numStereo, 0);
1835 break;
1837 case ALC_MAX_AUXILIARY_SENDS:
1838 numSends = attrList[attrIdx + 1];
1839 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1840 numSends = clampi(numSends, 0, MAX_SENDS);
1841 break;
1843 case ALC_HRTF_SOFT:
1844 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1845 if(attrList[attrIdx + 1] == ALC_FALSE)
1846 hrtf_appreq = Hrtf_Disable;
1847 else if(attrList[attrIdx + 1] == ALC_TRUE)
1848 hrtf_appreq = Hrtf_Enable;
1849 else
1850 hrtf_appreq = Hrtf_Default;
1851 break;
1853 case ALC_HRTF_ID_SOFT:
1854 hrtf_id = attrList[attrIdx + 1];
1855 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1856 break;
1858 case ALC_OUTPUT_LIMITER_SOFT:
1859 gainLimiter = attrList[attrIdx + 1];
1860 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1861 break;
1863 default:
1864 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList[attrIdx],
1865 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1866 break;
1869 attrIdx += 2;
1871 #undef TRACE_ATTR
1873 if(!schans || !stype || !freq)
1875 WARN("Missing format for loopback device\n");
1876 return ALC_INVALID_VALUE;
1878 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1880 WARN("Missing ambisonic info for loopback device\n");
1881 return ALC_INVALID_VALUE;
1884 if((device->Flags&DEVICE_RUNNING))
1885 V0(device->Backend,stop)();
1886 device->Flags &= ~DEVICE_RUNNING;
1888 UpdateClockBase(device);
1890 device->Frequency = freq;
1891 device->FmtChans = schans;
1892 device->FmtType = stype;
1893 if(schans == ALC_BFORMAT3D_SOFT)
1895 device->AmbiOrder = aorder;
1896 device->AmbiLayout = alayout;
1897 device->AmbiScale = ascale;
1900 if(numMono > INT_MAX-numStereo)
1901 numMono = INT_MAX-numStereo;
1902 numMono += numStereo;
1903 if(ConfigValueInt(NULL, NULL, "sources", &numMono))
1905 if(numMono <= 0)
1906 numMono = 256;
1908 else
1909 numMono = maxi(numMono, 256);
1910 numStereo = mini(numStereo, numMono);
1911 numMono -= numStereo;
1912 device->SourcesMax = numMono + numStereo;
1914 device->NumMonoSources = numMono;
1915 device->NumStereoSources = numStereo;
1917 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1918 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1919 else
1920 new_sends = numSends;
1922 else if(attrList && attrList[0])
1924 ALCsizei numMono, numStereo, numSends;
1925 ALCsizei attrIdx = 0;
1926 ALCuint freq;
1928 /* If a context is already running on the device, stop playback so the
1929 * device attributes can be updated. */
1930 if((device->Flags&DEVICE_RUNNING))
1931 V0(device->Backend,stop)();
1932 device->Flags &= ~DEVICE_RUNNING;
1934 UpdateClockBase(device);
1936 freq = device->Frequency;
1937 numMono = device->NumMonoSources;
1938 numStereo = device->NumStereoSources;
1939 numSends = old_sends;
1941 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1942 while(attrList[attrIdx])
1944 switch(attrList[attrIdx])
1946 case ALC_FREQUENCY:
1947 freq = attrList[attrIdx + 1];
1948 TRACE_ATTR(ALC_FREQUENCY, freq);
1949 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1950 break;
1952 case ALC_MONO_SOURCES:
1953 numMono = attrList[attrIdx + 1];
1954 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1955 numMono = maxi(numMono, 0);
1956 break;
1958 case ALC_STEREO_SOURCES:
1959 numStereo = attrList[attrIdx + 1];
1960 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1961 numStereo = maxi(numStereo, 0);
1962 break;
1964 case ALC_MAX_AUXILIARY_SENDS:
1965 numSends = attrList[attrIdx + 1];
1966 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1967 numSends = clampi(numSends, 0, MAX_SENDS);
1968 break;
1970 case ALC_HRTF_SOFT:
1971 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1972 if(attrList[attrIdx + 1] == ALC_FALSE)
1973 hrtf_appreq = Hrtf_Disable;
1974 else if(attrList[attrIdx + 1] == ALC_TRUE)
1975 hrtf_appreq = Hrtf_Enable;
1976 else
1977 hrtf_appreq = Hrtf_Default;
1978 break;
1980 case ALC_HRTF_ID_SOFT:
1981 hrtf_id = attrList[attrIdx + 1];
1982 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1983 break;
1985 case ALC_OUTPUT_LIMITER_SOFT:
1986 gainLimiter = attrList[attrIdx + 1];
1987 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1988 break;
1990 default:
1991 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
1992 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1993 break;
1996 attrIdx += 2;
1998 #undef TRACE_ATTR
2000 ConfigValueUInt(alstr_get_cstr(device->DeviceName), NULL, "frequency", &freq);
2001 freq = maxu(freq, MIN_OUTPUT_RATE);
2003 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
2004 device->Frequency;
2005 /* SSE and Neon do best with the update size being a multiple of 4 */
2006 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2007 device->UpdateSize = (device->UpdateSize+3)&~3;
2009 device->Frequency = freq;
2011 if(numMono > INT_MAX-numStereo)
2012 numMono = INT_MAX-numStereo;
2013 numMono += numStereo;
2014 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono))
2016 if(numMono <= 0)
2017 numMono = 256;
2019 else
2020 numMono = maxi(numMono, 256);
2021 numStereo = mini(numStereo, numMono);
2022 numMono -= numStereo;
2023 device->SourcesMax = numMono + numStereo;
2025 device->NumMonoSources = numMono;
2026 device->NumStereoSources = numStereo;
2028 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2029 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2030 else
2031 new_sends = numSends;
2034 if((device->Flags&DEVICE_RUNNING))
2035 return ALC_NO_ERROR;
2037 al_free(device->Uhj_Encoder);
2038 device->Uhj_Encoder = NULL;
2040 al_free(device->Bs2b);
2041 device->Bs2b = NULL;
2043 al_free(device->ChannelDelay[0].Buffer);
2044 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2046 device->ChannelDelay[i].Length = 0;
2047 device->ChannelDelay[i].Buffer = NULL;
2050 al_free(device->Dry.Buffer);
2051 device->Dry.Buffer = NULL;
2052 device->Dry.NumChannels = 0;
2053 device->FOAOut.Buffer = NULL;
2054 device->FOAOut.NumChannels = 0;
2055 device->RealOut.Buffer = NULL;
2056 device->RealOut.NumChannels = 0;
2058 UpdateClockBase(device);
2060 device->DitherSeed = DITHER_RNG_SEED;
2062 /*************************************************************************
2063 * Update device format request if HRTF is requested
2065 device->HrtfStatus = ALC_HRTF_DISABLED_SOFT;
2066 if(device->Type != Loopback)
2068 const char *hrtf;
2069 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2071 if(strcasecmp(hrtf, "true") == 0)
2072 hrtf_userreq = Hrtf_Enable;
2073 else if(strcasecmp(hrtf, "false") == 0)
2074 hrtf_userreq = Hrtf_Disable;
2075 else if(strcasecmp(hrtf, "auto") != 0)
2076 ERR("Unexpected hrtf value: %s\n", hrtf);
2079 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2081 struct Hrtf *hrtf = NULL;
2082 if(VECTOR_SIZE(device->HrtfList) == 0)
2084 VECTOR_DEINIT(device->HrtfList);
2085 device->HrtfList = EnumerateHrtf(device->DeviceName);
2087 if(VECTOR_SIZE(device->HrtfList) > 0)
2089 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
2090 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
2091 else
2092 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
2095 if(hrtf)
2097 device->FmtChans = DevFmtStereo;
2098 device->Frequency = hrtf->sampleRate;
2099 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2100 if(device->HrtfHandle)
2101 Hrtf_DecRef(device->HrtfHandle);
2102 device->HrtfHandle = hrtf;
2104 else
2106 hrtf_userreq = Hrtf_Default;
2107 hrtf_appreq = Hrtf_Disable;
2108 device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2113 oldFreq = device->Frequency;
2114 oldChans = device->FmtChans;
2115 oldType = device->FmtType;
2117 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2118 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2119 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2120 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2121 device->UpdateSize, device->NumUpdates
2124 if(V0(device->Backend,reset)() == ALC_FALSE)
2125 return ALC_INVALID_DEVICE;
2127 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2129 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2130 DevFmtChannelsString(device->FmtChans));
2131 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2133 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2135 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2136 DevFmtTypeString(device->FmtType));
2137 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2139 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2141 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2142 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2145 if((device->UpdateSize&3) != 0)
2147 if((CPUCapFlags&CPU_CAP_SSE))
2148 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2149 if((CPUCapFlags&CPU_CAP_NEON))
2150 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2153 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2154 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2155 device->Frequency, device->UpdateSize, device->NumUpdates
2158 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2159 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2160 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2162 /* Allocate extra channels for any post-filter output. */
2163 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2164 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2166 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2167 device->Dry.Buffer = al_calloc(16, size);
2168 if(!device->Dry.Buffer)
2170 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2171 return ALC_INVALID_DEVICE;
2174 if(device->RealOut.NumChannels != 0)
2175 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2176 device->FOAOut.NumChannels;
2177 else
2179 device->RealOut.Buffer = device->Dry.Buffer;
2180 device->RealOut.NumChannels = device->Dry.NumChannels;
2183 if(device->FOAOut.NumChannels != 0)
2184 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2185 else
2187 device->FOAOut.Buffer = device->Dry.Buffer;
2188 device->FOAOut.NumChannels = device->Dry.NumChannels;
2191 device->NumAuxSends = new_sends;
2192 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2193 device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2194 device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2196 device->DitherDepth = 0.0f;
2197 if(GetConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "dither", 1))
2199 ALint depth = 0;
2200 ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "dither-depth", &depth);
2201 if(depth <= 0)
2203 switch(device->FmtType)
2205 case DevFmtByte:
2206 case DevFmtUByte:
2207 depth = 8;
2208 break;
2209 case DevFmtShort:
2210 case DevFmtUShort:
2211 depth = 16;
2212 break;
2213 case DevFmtInt:
2214 case DevFmtUInt:
2215 case DevFmtFloat:
2216 break;
2219 else if(depth > 24)
2220 depth = 24;
2221 device->DitherDepth = (depth > 0) ? powf(2.0f, (ALfloat)(depth-1)) : 0.0f;
2223 if(!(device->DitherDepth > 0.0f))
2224 TRACE("Dithering disabled\n");
2225 else
2226 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device->DitherDepth)+1.0f,
2227 device->DitherDepth);
2229 if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
2230 gainLimiter = val ? ALC_TRUE : ALC_FALSE;
2231 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2232 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2233 * ALC_TRUE.
2235 if(gainLimiter != ALC_FALSE)
2237 if(!device->Limiter || device->Frequency != GetCompressorSampleRate(device->Limiter))
2239 al_free(device->Limiter);
2240 device->Limiter = CreateDeviceLimiter(device);
2243 else
2245 al_free(device->Limiter);
2246 device->Limiter = NULL;
2248 TRACE("Output limiter %s\n", device->Limiter ? "enabled" : "disabled");
2250 /* Need to delay returning failure until replacement Send arrays have been
2251 * allocated with the appropriate size.
2253 update_failed = AL_FALSE;
2254 START_MIXER_MODE();
2255 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2256 while(context)
2258 struct ALvoiceProps *vprops;
2259 ALsizei pos;
2261 if(context->DefaultSlot)
2263 ALeffectslot *slot = context->DefaultSlot;
2264 ALeffectState *state = slot->Effect.State;
2266 state->OutBuffer = device->Dry.Buffer;
2267 state->OutChannels = device->Dry.NumChannels;
2268 if(V(state,deviceUpdate)(device) == AL_FALSE)
2269 update_failed = AL_TRUE;
2270 else
2271 UpdateEffectSlotProps(slot, context);
2274 WriteLock(&context->PropLock);
2275 LockUIntMapRead(&context->EffectSlotMap);
2276 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2278 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2279 ALeffectState *state = slot->Effect.State;
2281 state->OutBuffer = device->Dry.Buffer;
2282 state->OutChannels = device->Dry.NumChannels;
2283 if(V(state,deviceUpdate)(device) == AL_FALSE)
2284 update_failed = AL_TRUE;
2285 else
2286 UpdateEffectSlotProps(slot, context);
2288 UnlockUIntMapRead(&context->EffectSlotMap);
2290 LockUIntMapRead(&context->SourceMap);
2291 RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax);
2292 for(pos = 0;pos < context->SourceMap.size;pos++)
2294 ALsource *source = context->SourceMap.values[pos];
2296 if(old_sends != device->NumAuxSends)
2298 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2299 ALsizei s;
2301 memcpy(sends, source->Send,
2302 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2304 for(s = device->NumAuxSends;s < old_sends;s++)
2306 if(source->Send[s].Slot)
2307 DecrementRef(&source->Send[s].Slot->ref);
2308 source->Send[s].Slot = NULL;
2310 al_free(source->Send);
2311 source->Send = sends;
2312 for(s = old_sends;s < device->NumAuxSends;s++)
2314 source->Send[s].Slot = NULL;
2315 source->Send[s].Gain = 1.0f;
2316 source->Send[s].GainHF = 1.0f;
2317 source->Send[s].HFReference = LOWPASSFREQREF;
2318 source->Send[s].GainLF = 1.0f;
2319 source->Send[s].LFReference = HIGHPASSFREQREF;
2323 ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
2326 /* Clear any pre-existing voice property structs, in case the number of
2327 * auxiliary sends is changing. Active sources will have updates
2328 * respecified in UpdateAllSourceProps.
2330 vprops = ATOMIC_EXCHANGE_PTR(&context->FreeVoiceProps, NULL, almemory_order_acq_rel);
2331 while(vprops)
2333 struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed);
2334 al_free(vprops);
2335 vprops = next;
2338 AllocateVoices(context, context->MaxVoices, old_sends);
2339 for(pos = 0;pos < context->VoiceCount;pos++)
2341 ALvoice *voice = context->Voices[pos];
2343 al_free(ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_acq_rel));
2345 if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
2346 continue;
2348 if(device->AvgSpeakerDist > 0.0f)
2350 /* Reinitialize the NFC filters for new parameters. */
2351 ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
2352 (device->AvgSpeakerDist * device->Frequency);
2353 for(i = 0;i < voice->NumChannels;i++)
2355 NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1);
2356 NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1);
2357 NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1);
2361 UnlockUIntMapRead(&context->SourceMap);
2363 ATOMIC_FLAG_TEST_AND_SET(&context->PropsClean, almemory_order_release);
2364 UpdateContextProps(context);
2365 ATOMIC_FLAG_TEST_AND_SET(&context->Listener->PropsClean, almemory_order_release);
2366 UpdateListenerProps(context);
2367 UpdateAllSourceProps(context);
2368 WriteUnlock(&context->PropLock);
2370 context = context->next;
2372 END_MIXER_MODE();
2373 if(update_failed)
2374 return ALC_INVALID_DEVICE;
2376 if(!(device->Flags&DEVICE_PAUSED))
2378 if(V0(device->Backend,start)() == ALC_FALSE)
2379 return ALC_INVALID_DEVICE;
2380 device->Flags |= DEVICE_RUNNING;
2383 return ALC_NO_ERROR;
2386 /* FreeDevice
2388 * Frees the device structure, and destroys any objects the app failed to
2389 * delete. Called once there's no more references on the device.
2391 static ALCvoid FreeDevice(ALCdevice *device)
2393 ALsizei i;
2395 TRACE("%p\n", device);
2397 V0(device->Backend,close)();
2398 DELETE_OBJ(device->Backend);
2399 device->Backend = NULL;
2401 almtx_destroy(&device->BackendLock);
2403 if(device->BufferMap.size > 0)
2405 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2406 (device->BufferMap.size==1)?"":"s");
2407 ReleaseALBuffers(device);
2409 ResetUIntMap(&device->BufferMap);
2411 if(device->EffectMap.size > 0)
2413 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2414 (device->EffectMap.size==1)?"":"s");
2415 ReleaseALEffects(device);
2417 ResetUIntMap(&device->EffectMap);
2419 if(device->FilterMap.size > 0)
2421 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2422 (device->FilterMap.size==1)?"":"s");
2423 ReleaseALFilters(device);
2425 ResetUIntMap(&device->FilterMap);
2427 AL_STRING_DEINIT(device->HrtfName);
2428 FreeHrtfList(&device->HrtfList);
2429 if(device->HrtfHandle)
2430 Hrtf_DecRef(device->HrtfHandle);
2431 device->HrtfHandle = NULL;
2432 al_free(device->Hrtf);
2433 device->Hrtf = NULL;
2435 al_free(device->Bs2b);
2436 device->Bs2b = NULL;
2438 al_free(device->Uhj_Encoder);
2439 device->Uhj_Encoder = NULL;
2441 bformatdec_free(device->AmbiDecoder);
2442 device->AmbiDecoder = NULL;
2444 ambiup_free(device->AmbiUp);
2445 device->AmbiUp = NULL;
2447 al_free(device->Stablizer);
2448 device->Stablizer = NULL;
2450 al_free(device->Limiter);
2451 device->Limiter = NULL;
2453 al_free(device->ChannelDelay[0].Buffer);
2454 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2456 device->ChannelDelay[i].Gain = 1.0f;
2457 device->ChannelDelay[i].Length = 0;
2458 device->ChannelDelay[i].Buffer = NULL;
2461 AL_STRING_DEINIT(device->DeviceName);
2463 al_free(device->Dry.Buffer);
2464 device->Dry.Buffer = NULL;
2465 device->Dry.NumChannels = 0;
2466 device->FOAOut.Buffer = NULL;
2467 device->FOAOut.NumChannels = 0;
2468 device->RealOut.Buffer = NULL;
2469 device->RealOut.NumChannels = 0;
2471 al_free(device);
2475 void ALCdevice_IncRef(ALCdevice *device)
2477 uint ref;
2478 ref = IncrementRef(&device->ref);
2479 TRACEREF("%p increasing refcount to %u\n", device, ref);
2482 void ALCdevice_DecRef(ALCdevice *device)
2484 uint ref;
2485 ref = DecrementRef(&device->ref);
2486 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2487 if(ref == 0) FreeDevice(device);
2490 /* VerifyDevice
2492 * Checks if the device handle is valid, and increments its ref count if so.
2494 static ALCboolean VerifyDevice(ALCdevice **device)
2496 ALCdevice *tmpDevice;
2498 LockLists();
2499 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2500 while(tmpDevice)
2502 if(tmpDevice == *device)
2504 ALCdevice_IncRef(tmpDevice);
2505 UnlockLists();
2506 return ALC_TRUE;
2508 tmpDevice = tmpDevice->next;
2510 UnlockLists();
2512 *device = NULL;
2513 return ALC_FALSE;
2517 /* InitContext
2519 * Initializes context fields
2521 static ALvoid InitContext(ALCcontext *Context)
2523 ALlistener *listener = Context->Listener;
2524 struct ALeffectslotArray *auxslots;
2526 //Initialise listener
2527 listener->Gain = 1.0f;
2528 listener->Position[0] = 0.0f;
2529 listener->Position[1] = 0.0f;
2530 listener->Position[2] = 0.0f;
2531 listener->Velocity[0] = 0.0f;
2532 listener->Velocity[1] = 0.0f;
2533 listener->Velocity[2] = 0.0f;
2534 listener->Forward[0] = 0.0f;
2535 listener->Forward[1] = 0.0f;
2536 listener->Forward[2] = -1.0f;
2537 listener->Up[0] = 0.0f;
2538 listener->Up[1] = 1.0f;
2539 listener->Up[2] = 0.0f;
2540 ATOMIC_FLAG_TEST_AND_SET(&listener->PropsClean, almemory_order_relaxed);
2542 ATOMIC_INIT(&listener->Update, NULL);
2544 //Validate Context
2545 InitRef(&Context->UpdateCount, 0);
2546 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2547 Context->GainBoost = 1.0f;
2548 RWLockInit(&Context->PropLock);
2549 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2550 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2551 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2553 if(Context->DefaultSlot)
2555 auxslots = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, 1));
2556 auxslots->count = 1;
2557 auxslots->slot[0] = Context->DefaultSlot;
2559 else
2561 auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray));
2562 auxslots->count = 0;
2564 ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots);
2566 //Set globals
2567 Context->DistanceModel = DefaultDistanceModel;
2568 Context->SourceDistanceModel = AL_FALSE;
2569 Context->DopplerFactor = 1.0f;
2570 Context->DopplerVelocity = 1.0f;
2571 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2572 Context->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT;
2573 ATOMIC_FLAG_TEST_AND_SET(&Context->PropsClean, almemory_order_relaxed);
2574 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2576 ATOMIC_INIT(&Context->Update, NULL);
2577 ATOMIC_INIT(&Context->FreeContextProps, NULL);
2578 ATOMIC_INIT(&Context->FreeListenerProps, NULL);
2579 ATOMIC_INIT(&Context->FreeVoiceProps, NULL);
2580 ATOMIC_INIT(&Context->FreeEffectslotProps, NULL);
2582 Context->ExtensionList = alExtList;
2585 aluMatrixfSet(&listener->Params.Matrix,
2586 1.0f, 0.0f, 0.0f, 0.0f,
2587 0.0f, 1.0f, 0.0f, 0.0f,
2588 0.0f, 0.0f, 1.0f, 0.0f,
2589 0.0f, 0.0f, 0.0f, 1.0f
2591 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2592 listener->Params.Gain = listener->Gain;
2593 listener->Params.MetersPerUnit = Context->MetersPerUnit;
2594 listener->Params.DopplerFactor = Context->DopplerFactor;
2595 listener->Params.SpeedOfSound = Context->SpeedOfSound * Context->DopplerVelocity;
2596 listener->Params.ReverbSpeedOfSound = listener->Params.SpeedOfSound *
2597 listener->Params.MetersPerUnit;
2601 /* FreeContext
2603 * Cleans up the context, and destroys any remaining objects the app failed to
2604 * delete. Called once there's no more references on the context.
2606 static void FreeContext(ALCcontext *context)
2608 ALlistener *listener = context->Listener;
2609 struct ALeffectslotArray *auxslots;
2610 struct ALeffectslotProps *eprops;
2611 struct ALlistenerProps *lprops;
2612 struct ALcontextProps *cprops;
2613 struct ALvoiceProps *vprops;
2614 size_t count;
2615 ALsizei i;
2617 TRACE("%p\n", context);
2619 if((cprops=ATOMIC_LOAD(&context->Update, almemory_order_acquire)) != NULL)
2621 TRACE("Freed unapplied context update %p\n", cprops);
2622 al_free(cprops);
2625 count = 0;
2626 cprops = ATOMIC_LOAD(&context->FreeContextProps, almemory_order_acquire);
2627 while(cprops)
2629 struct ALcontextProps *next = ATOMIC_LOAD(&cprops->next, almemory_order_acquire);
2630 al_free(cprops);
2631 cprops = next;
2632 ++count;
2634 TRACE("Freed "SZFMT" context property object%s\n", count, (count==1)?"":"s");
2636 if(context->DefaultSlot)
2638 DeinitEffectSlot(context->DefaultSlot);
2639 context->DefaultSlot = NULL;
2642 auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
2643 al_free(auxslots);
2645 if(context->SourceMap.size > 0)
2647 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2648 (context->SourceMap.size==1)?"":"s");
2649 ReleaseALSources(context);
2651 ResetUIntMap(&context->SourceMap);
2653 count = 0;
2654 eprops = ATOMIC_LOAD(&context->FreeEffectslotProps, almemory_order_relaxed);
2655 while(eprops)
2657 struct ALeffectslotProps *next = ATOMIC_LOAD(&eprops->next, almemory_order_relaxed);
2658 if(eprops->State) ALeffectState_DecRef(eprops->State);
2659 al_free(eprops);
2660 eprops = next;
2661 ++count;
2663 TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s");
2664 if(context->EffectSlotMap.size > 0)
2666 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2667 (context->EffectSlotMap.size==1)?"":"s");
2668 ReleaseALAuxiliaryEffectSlots(context);
2670 ResetUIntMap(&context->EffectSlotMap);
2672 count = 0;
2673 vprops = ATOMIC_LOAD(&context->FreeVoiceProps, almemory_order_relaxed);
2674 while(vprops)
2676 struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed);
2677 al_free(vprops);
2678 vprops = next;
2679 ++count;
2681 TRACE("Freed "SZFMT" voice property object%s\n", count, (count==1)?"":"s");
2683 for(i = 0;i < context->VoiceCount;i++)
2684 DeinitVoice(context->Voices[i]);
2685 al_free(context->Voices);
2686 context->Voices = NULL;
2687 context->VoiceCount = 0;
2688 context->MaxVoices = 0;
2690 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2692 TRACE("Freed unapplied listener update %p\n", lprops);
2693 al_free(lprops);
2695 count = 0;
2696 lprops = ATOMIC_LOAD(&context->FreeListenerProps, almemory_order_acquire);
2697 while(lprops)
2699 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2700 al_free(lprops);
2701 lprops = next;
2702 ++count;
2704 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2706 ALCdevice_DecRef(context->Device);
2707 context->Device = NULL;
2709 //Invalidate context
2710 memset(context, 0, sizeof(ALCcontext));
2711 al_free(context);
2714 /* ReleaseContext
2716 * Removes the context reference from the given device and removes it from
2717 * being current on the running thread or globally. Returns true if other
2718 * contexts still exist on the device.
2720 static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
2722 ALCcontext *origctx, *newhead;
2723 bool ret = true;
2725 if(altss_get(LocalContext) == context)
2727 WARN("%p released while current on thread\n", context);
2728 altss_set(LocalContext, NULL);
2729 ALCcontext_DecRef(context);
2732 origctx = context;
2733 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
2734 ALCcontext_DecRef(context);
2736 ALCdevice_Lock(device);
2737 origctx = context;
2738 newhead = context->next;
2739 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
2741 ALCcontext *volatile*list = &origctx->next;
2742 while(*list)
2744 if(*list == context)
2746 *list = (*list)->next;
2747 break;
2749 list = &(*list)->next;
2752 else
2753 ret = !!newhead;
2754 ALCdevice_Unlock(device);
2756 ALCcontext_DecRef(context);
2757 return ret;
2760 void ALCcontext_IncRef(ALCcontext *context)
2762 uint ref = IncrementRef(&context->ref);
2763 TRACEREF("%p increasing refcount to %u\n", context, ref);
2766 void ALCcontext_DecRef(ALCcontext *context)
2768 uint ref = DecrementRef(&context->ref);
2769 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2770 if(ref == 0) FreeContext(context);
2773 static void ReleaseThreadCtx(void *ptr)
2775 ALCcontext *context = ptr;
2776 uint ref = DecrementRef(&context->ref);
2777 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2778 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2781 /* VerifyContext
2783 * Checks that the given context is valid, and increments its reference count.
2785 static ALCboolean VerifyContext(ALCcontext **context)
2787 ALCdevice *dev;
2789 LockLists();
2790 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2791 while(dev)
2793 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2794 while(ctx)
2796 if(ctx == *context)
2798 ALCcontext_IncRef(ctx);
2799 UnlockLists();
2800 return ALC_TRUE;
2802 ctx = ctx->next;
2804 dev = dev->next;
2806 UnlockLists();
2808 *context = NULL;
2809 return ALC_FALSE;
2813 /* GetContextRef
2815 * Returns the currently active context for this thread, and adds a reference
2816 * without locking it.
2818 ALCcontext *GetContextRef(void)
2820 ALCcontext *context;
2822 context = altss_get(LocalContext);
2823 if(context)
2824 ALCcontext_IncRef(context);
2825 else
2827 LockLists();
2828 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2829 if(context)
2830 ALCcontext_IncRef(context);
2831 UnlockLists();
2834 return context;
2838 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2840 ALCdevice *device = context->Device;
2841 ALsizei num_sends = device->NumAuxSends;
2842 struct ALvoiceProps *props;
2843 size_t sizeof_props;
2844 size_t sizeof_voice;
2845 ALvoice **voices;
2846 ALvoice *voice;
2847 ALsizei v = 0;
2848 size_t size;
2850 if(num_voices == context->MaxVoices && num_sends == old_sends)
2851 return;
2853 /* Allocate the voice pointers, voices, and the voices' stored source
2854 * property set (including the dynamically-sized Send[] array) in one
2855 * chunk.
2857 sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
2858 sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
2859 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2861 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2862 /* The voice and property objects are stored interleaved since they're
2863 * paired together.
2865 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2866 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2868 if(context->Voices)
2870 const ALsizei v_count = mini(context->VoiceCount, num_voices);
2871 const ALsizei s_count = mini(old_sends, num_sends);
2873 for(;v < v_count;v++)
2875 ALvoice *old_voice = context->Voices[v];
2876 ALsizei i;
2878 /* Copy the old voice data and source property set to the new
2879 * storage.
2881 *voice = *old_voice;
2882 for(i = 0;i < s_count;i++)
2883 voice->Send[i] = old_voice->Send[i];
2884 *props = *(old_voice->Props);
2885 for(i = 0;i < s_count;i++)
2886 props->Send[i] = old_voice->Props->Send[i];
2888 /* Set this voice's property set pointer and voice reference. */
2889 voice->Props = props;
2890 voices[v] = voice;
2892 /* Increment pointers to the next storage space. */
2893 voice = (ALvoice*)((char*)props + sizeof_props);
2894 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2896 /* Deinit any left over voices that weren't copied over to the new
2897 * array. NOTE: If this does anything, v equals num_voices and
2898 * num_voices is less than VoiceCount, so the following loop won't do
2899 * anything.
2901 for(;v < context->VoiceCount;v++)
2902 DeinitVoice(context->Voices[v]);
2904 /* Finish setting the voices' property set pointers and references. */
2905 for(;v < num_voices;v++)
2907 ATOMIC_INIT(&voice->Update, NULL);
2909 voice->Props = props;
2910 voices[v] = voice;
2912 voice = (ALvoice*)((char*)props + sizeof_props);
2913 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2916 al_free(context->Voices);
2917 context->Voices = voices;
2918 context->MaxVoices = num_voices;
2919 context->VoiceCount = mini(context->VoiceCount, num_voices);
2923 /************************************************
2924 * Standard ALC functions
2925 ************************************************/
2927 /* alcGetError
2929 * Return last ALC generated error code for the given device
2931 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2933 ALCenum errorCode;
2935 if(VerifyDevice(&device))
2937 errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
2938 ALCdevice_DecRef(device);
2940 else
2941 errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
2943 return errorCode;
2947 /* alcSuspendContext
2949 * Suspends updates for the given context
2951 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2953 if(!SuspendDefers)
2954 return;
2956 if(!VerifyContext(&context))
2957 alcSetError(NULL, ALC_INVALID_CONTEXT);
2958 else
2960 ALCcontext_DeferUpdates(context);
2961 ALCcontext_DecRef(context);
2965 /* alcProcessContext
2967 * Resumes processing updates for the given context
2969 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2971 if(!SuspendDefers)
2972 return;
2974 if(!VerifyContext(&context))
2975 alcSetError(NULL, ALC_INVALID_CONTEXT);
2976 else
2978 ALCcontext_ProcessUpdates(context);
2979 ALCcontext_DecRef(context);
2984 /* alcGetString
2986 * Returns information about the device, and error strings
2988 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2990 const ALCchar *value = NULL;
2992 switch(param)
2994 case ALC_NO_ERROR:
2995 value = alcNoError;
2996 break;
2998 case ALC_INVALID_ENUM:
2999 value = alcErrInvalidEnum;
3000 break;
3002 case ALC_INVALID_VALUE:
3003 value = alcErrInvalidValue;
3004 break;
3006 case ALC_INVALID_DEVICE:
3007 value = alcErrInvalidDevice;
3008 break;
3010 case ALC_INVALID_CONTEXT:
3011 value = alcErrInvalidContext;
3012 break;
3014 case ALC_OUT_OF_MEMORY:
3015 value = alcErrOutOfMemory;
3016 break;
3018 case ALC_DEVICE_SPECIFIER:
3019 value = alcDefaultName;
3020 break;
3022 case ALC_ALL_DEVICES_SPECIFIER:
3023 if(VerifyDevice(&Device))
3025 value = alstr_get_cstr(Device->DeviceName);
3026 ALCdevice_DecRef(Device);
3028 else
3030 ProbeAllDevicesList();
3031 value = alstr_get_cstr(alcAllDevicesList);
3033 break;
3035 case ALC_CAPTURE_DEVICE_SPECIFIER:
3036 if(VerifyDevice(&Device))
3038 value = alstr_get_cstr(Device->DeviceName);
3039 ALCdevice_DecRef(Device);
3041 else
3043 ProbeCaptureDeviceList();
3044 value = alstr_get_cstr(alcCaptureDeviceList);
3046 break;
3048 /* Default devices are always first in the list */
3049 case ALC_DEFAULT_DEVICE_SPECIFIER:
3050 value = alcDefaultName;
3051 break;
3053 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
3054 if(alstr_empty(alcAllDevicesList))
3055 ProbeAllDevicesList();
3057 VerifyDevice(&Device);
3059 free(alcDefaultAllDevicesSpecifier);
3060 alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
3061 if(!alcDefaultAllDevicesSpecifier)
3062 alcSetError(Device, ALC_OUT_OF_MEMORY);
3064 value = alcDefaultAllDevicesSpecifier;
3065 if(Device) ALCdevice_DecRef(Device);
3066 break;
3068 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
3069 if(alstr_empty(alcCaptureDeviceList))
3070 ProbeCaptureDeviceList();
3072 VerifyDevice(&Device);
3074 free(alcCaptureDefaultDeviceSpecifier);
3075 alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
3076 if(!alcCaptureDefaultDeviceSpecifier)
3077 alcSetError(Device, ALC_OUT_OF_MEMORY);
3079 value = alcCaptureDefaultDeviceSpecifier;
3080 if(Device) ALCdevice_DecRef(Device);
3081 break;
3083 case ALC_EXTENSIONS:
3084 if(!VerifyDevice(&Device))
3085 value = alcNoDeviceExtList;
3086 else
3088 value = alcExtensionList;
3089 ALCdevice_DecRef(Device);
3091 break;
3093 case ALC_HRTF_SPECIFIER_SOFT:
3094 if(!VerifyDevice(&Device))
3095 alcSetError(NULL, ALC_INVALID_DEVICE);
3096 else
3098 almtx_lock(&Device->BackendLock);
3099 value = (Device->HrtfHandle ? alstr_get_cstr(Device->HrtfName) : "");
3100 almtx_unlock(&Device->BackendLock);
3101 ALCdevice_DecRef(Device);
3103 break;
3105 default:
3106 VerifyDevice(&Device);
3107 alcSetError(Device, ALC_INVALID_ENUM);
3108 if(Device) ALCdevice_DecRef(Device);
3109 break;
3112 return value;
3116 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
3118 if(device->Type == Loopback && device->FmtChans == DevFmtAmbi3D)
3119 return 25;
3120 return 19;
3123 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3125 ALCsizei i;
3127 if(size <= 0 || values == NULL)
3129 alcSetError(device, ALC_INVALID_VALUE);
3130 return 0;
3133 if(!device)
3135 switch(param)
3137 case ALC_MAJOR_VERSION:
3138 values[0] = alcMajorVersion;
3139 return 1;
3140 case ALC_MINOR_VERSION:
3141 values[0] = alcMinorVersion;
3142 return 1;
3144 case ALC_ATTRIBUTES_SIZE:
3145 case ALC_ALL_ATTRIBUTES:
3146 case ALC_FREQUENCY:
3147 case ALC_REFRESH:
3148 case ALC_SYNC:
3149 case ALC_MONO_SOURCES:
3150 case ALC_STEREO_SOURCES:
3151 case ALC_CAPTURE_SAMPLES:
3152 case ALC_FORMAT_CHANNELS_SOFT:
3153 case ALC_FORMAT_TYPE_SOFT:
3154 case ALC_AMBISONIC_LAYOUT_SOFT:
3155 case ALC_AMBISONIC_SCALING_SOFT:
3156 case ALC_AMBISONIC_ORDER_SOFT:
3157 alcSetError(NULL, ALC_INVALID_DEVICE);
3158 return 0;
3160 default:
3161 alcSetError(NULL, ALC_INVALID_ENUM);
3162 return 0;
3164 return 0;
3167 if(device->Type == Capture)
3169 switch(param)
3171 case ALC_CAPTURE_SAMPLES:
3172 almtx_lock(&device->BackendLock);
3173 values[0] = V0(device->Backend,availableSamples)();
3174 almtx_unlock(&device->BackendLock);
3175 return 1;
3177 case ALC_CONNECTED:
3178 values[0] = device->Connected;
3179 return 1;
3181 default:
3182 alcSetError(device, ALC_INVALID_ENUM);
3183 return 0;
3185 return 0;
3188 /* render device */
3189 switch(param)
3191 case ALC_MAJOR_VERSION:
3192 values[0] = alcMajorVersion;
3193 return 1;
3195 case ALC_MINOR_VERSION:
3196 values[0] = alcMinorVersion;
3197 return 1;
3199 case ALC_EFX_MAJOR_VERSION:
3200 values[0] = alcEFXMajorVersion;
3201 return 1;
3203 case ALC_EFX_MINOR_VERSION:
3204 values[0] = alcEFXMinorVersion;
3205 return 1;
3207 case ALC_ATTRIBUTES_SIZE:
3208 values[0] = NumAttrsForDevice(device);
3209 return 1;
3211 case ALC_ALL_ATTRIBUTES:
3212 if(size < NumAttrsForDevice(device))
3214 alcSetError(device, ALC_INVALID_VALUE);
3215 return 0;
3218 i = 0;
3219 almtx_lock(&device->BackendLock);
3220 values[i++] = ALC_FREQUENCY;
3221 values[i++] = device->Frequency;
3223 if(device->Type != Loopback)
3225 values[i++] = ALC_REFRESH;
3226 values[i++] = device->Frequency / device->UpdateSize;
3228 values[i++] = ALC_SYNC;
3229 values[i++] = ALC_FALSE;
3231 else
3233 if(device->FmtChans == DevFmtAmbi3D)
3235 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3236 values[i++] = device->AmbiLayout;
3238 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3239 values[i++] = device->AmbiScale;
3241 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3242 values[i++] = device->AmbiOrder;
3245 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3246 values[i++] = device->FmtChans;
3248 values[i++] = ALC_FORMAT_TYPE_SOFT;
3249 values[i++] = device->FmtType;
3252 values[i++] = ALC_MONO_SOURCES;
3253 values[i++] = device->NumMonoSources;
3255 values[i++] = ALC_STEREO_SOURCES;
3256 values[i++] = device->NumStereoSources;
3258 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3259 values[i++] = device->NumAuxSends;
3261 values[i++] = ALC_HRTF_SOFT;
3262 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3264 values[i++] = ALC_HRTF_STATUS_SOFT;
3265 values[i++] = device->HrtfStatus;
3267 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3268 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3269 almtx_unlock(&device->BackendLock);
3271 values[i++] = 0;
3272 return i;
3274 case ALC_FREQUENCY:
3275 values[0] = device->Frequency;
3276 return 1;
3278 case ALC_REFRESH:
3279 if(device->Type == Loopback)
3281 alcSetError(device, ALC_INVALID_DEVICE);
3282 return 0;
3284 almtx_lock(&device->BackendLock);
3285 values[0] = device->Frequency / device->UpdateSize;
3286 almtx_unlock(&device->BackendLock);
3287 return 1;
3289 case ALC_SYNC:
3290 if(device->Type == Loopback)
3292 alcSetError(device, ALC_INVALID_DEVICE);
3293 return 0;
3295 values[0] = ALC_FALSE;
3296 return 1;
3298 case ALC_FORMAT_CHANNELS_SOFT:
3299 if(device->Type != Loopback)
3301 alcSetError(device, ALC_INVALID_DEVICE);
3302 return 0;
3304 values[0] = device->FmtChans;
3305 return 1;
3307 case ALC_FORMAT_TYPE_SOFT:
3308 if(device->Type != Loopback)
3310 alcSetError(device, ALC_INVALID_DEVICE);
3311 return 0;
3313 values[0] = device->FmtType;
3314 return 1;
3316 case ALC_AMBISONIC_LAYOUT_SOFT:
3317 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3319 alcSetError(device, ALC_INVALID_DEVICE);
3320 return 0;
3322 values[0] = device->AmbiLayout;
3323 return 1;
3325 case ALC_AMBISONIC_SCALING_SOFT:
3326 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3328 alcSetError(device, ALC_INVALID_DEVICE);
3329 return 0;
3331 values[0] = device->AmbiScale;
3332 return 1;
3334 case ALC_AMBISONIC_ORDER_SOFT:
3335 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3337 alcSetError(device, ALC_INVALID_DEVICE);
3338 return 0;
3340 values[0] = device->AmbiOrder;
3341 return 1;
3343 case ALC_MONO_SOURCES:
3344 values[0] = device->NumMonoSources;
3345 return 1;
3347 case ALC_STEREO_SOURCES:
3348 values[0] = device->NumStereoSources;
3349 return 1;
3351 case ALC_MAX_AUXILIARY_SENDS:
3352 values[0] = device->NumAuxSends;
3353 return 1;
3355 case ALC_CONNECTED:
3356 values[0] = device->Connected;
3357 return 1;
3359 case ALC_HRTF_SOFT:
3360 values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3361 return 1;
3363 case ALC_HRTF_STATUS_SOFT:
3364 values[0] = device->HrtfStatus;
3365 return 1;
3367 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3368 almtx_lock(&device->BackendLock);
3369 FreeHrtfList(&device->HrtfList);
3370 device->HrtfList = EnumerateHrtf(device->DeviceName);
3371 values[0] = (ALCint)VECTOR_SIZE(device->HrtfList);
3372 almtx_unlock(&device->BackendLock);
3373 return 1;
3375 case ALC_OUTPUT_LIMITER_SOFT:
3376 values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3377 return 1;
3379 default:
3380 alcSetError(device, ALC_INVALID_ENUM);
3381 return 0;
3383 return 0;
3386 /* alcGetIntegerv
3388 * Returns information about the device and the version of OpenAL
3390 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3392 VerifyDevice(&device);
3393 if(size <= 0 || values == NULL)
3394 alcSetError(device, ALC_INVALID_VALUE);
3395 else
3396 GetIntegerv(device, param, size, values);
3397 if(device) ALCdevice_DecRef(device);
3400 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3402 ALCint *ivals;
3403 ALsizei i;
3405 VerifyDevice(&device);
3406 if(size <= 0 || values == NULL)
3407 alcSetError(device, ALC_INVALID_VALUE);
3408 else if(!device || device->Type == Capture)
3410 ivals = malloc(size * sizeof(ALCint));
3411 size = GetIntegerv(device, pname, size, ivals);
3412 for(i = 0;i < size;i++)
3413 values[i] = ivals[i];
3414 free(ivals);
3416 else /* render device */
3418 ClockLatency clock;
3419 ALuint64 basecount;
3420 ALuint samplecount;
3421 ALuint refcount;
3423 switch(pname)
3425 case ALC_ATTRIBUTES_SIZE:
3426 *values = NumAttrsForDevice(device)+4;
3427 break;
3429 case ALC_ALL_ATTRIBUTES:
3430 if(size < NumAttrsForDevice(device)+4)
3431 alcSetError(device, ALC_INVALID_VALUE);
3432 else
3434 i = 0;
3435 almtx_lock(&device->BackendLock);
3436 values[i++] = ALC_FREQUENCY;
3437 values[i++] = device->Frequency;
3439 if(device->Type != Loopback)
3441 values[i++] = ALC_REFRESH;
3442 values[i++] = device->Frequency / device->UpdateSize;
3444 values[i++] = ALC_SYNC;
3445 values[i++] = ALC_FALSE;
3447 else
3449 if(device->FmtChans == DevFmtAmbi3D)
3451 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3452 values[i++] = device->AmbiLayout;
3454 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3455 values[i++] = device->AmbiScale;
3457 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3458 values[i++] = device->AmbiOrder;
3461 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3462 values[i++] = device->FmtChans;
3464 values[i++] = ALC_FORMAT_TYPE_SOFT;
3465 values[i++] = device->FmtType;
3468 values[i++] = ALC_MONO_SOURCES;
3469 values[i++] = device->NumMonoSources;
3471 values[i++] = ALC_STEREO_SOURCES;
3472 values[i++] = device->NumStereoSources;
3474 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3475 values[i++] = device->NumAuxSends;
3477 values[i++] = ALC_HRTF_SOFT;
3478 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3480 values[i++] = ALC_HRTF_STATUS_SOFT;
3481 values[i++] = device->HrtfStatus;
3483 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3484 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3486 clock = V0(device->Backend,getClockLatency)();
3487 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3488 values[i++] = clock.ClockTime;
3490 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3491 values[i++] = clock.Latency;
3492 almtx_unlock(&device->BackendLock);
3494 values[i++] = 0;
3496 break;
3498 case ALC_DEVICE_CLOCK_SOFT:
3499 almtx_lock(&device->BackendLock);
3500 do {
3501 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3502 althrd_yield();
3503 basecount = device->ClockBase;
3504 samplecount = device->SamplesDone;
3505 } while(refcount != ReadRef(&device->MixCount));
3506 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3507 almtx_unlock(&device->BackendLock);
3508 break;
3510 case ALC_DEVICE_LATENCY_SOFT:
3511 almtx_lock(&device->BackendLock);
3512 clock = V0(device->Backend,getClockLatency)();
3513 almtx_unlock(&device->BackendLock);
3514 *values = clock.Latency;
3515 break;
3517 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3518 if(size < 2)
3519 alcSetError(device, ALC_INVALID_VALUE);
3520 else
3522 almtx_lock(&device->BackendLock);
3523 clock = V0(device->Backend,getClockLatency)();
3524 almtx_unlock(&device->BackendLock);
3525 values[0] = clock.ClockTime;
3526 values[1] = clock.Latency;
3528 break;
3530 default:
3531 ivals = malloc(size * sizeof(ALCint));
3532 size = GetIntegerv(device, pname, size, ivals);
3533 for(i = 0;i < size;i++)
3534 values[i] = ivals[i];
3535 free(ivals);
3536 break;
3539 if(device)
3540 ALCdevice_DecRef(device);
3544 /* alcIsExtensionPresent
3546 * Determines if there is support for a particular extension
3548 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3550 ALCboolean bResult = ALC_FALSE;
3552 VerifyDevice(&device);
3554 if(!extName)
3555 alcSetError(device, ALC_INVALID_VALUE);
3556 else
3558 size_t len = strlen(extName);
3559 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3560 while(ptr && *ptr)
3562 if(strncasecmp(ptr, extName, len) == 0 &&
3563 (ptr[len] == '\0' || isspace(ptr[len])))
3565 bResult = ALC_TRUE;
3566 break;
3568 if((ptr=strchr(ptr, ' ')) != NULL)
3570 do {
3571 ++ptr;
3572 } while(isspace(*ptr));
3576 if(device)
3577 ALCdevice_DecRef(device);
3578 return bResult;
3582 /* alcGetProcAddress
3584 * Retrieves the function address for a particular extension function
3586 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3588 ALCvoid *ptr = NULL;
3590 if(!funcName)
3592 VerifyDevice(&device);
3593 alcSetError(device, ALC_INVALID_VALUE);
3594 if(device) ALCdevice_DecRef(device);
3596 else
3598 size_t i = 0;
3599 for(i = 0;i < COUNTOF(alcFunctions);i++)
3601 if(strcmp(alcFunctions[i].funcName, funcName) == 0)
3603 ptr = alcFunctions[i].address;
3604 break;
3609 return ptr;
3613 /* alcGetEnumValue
3615 * Get the value for a particular ALC enumeration name
3617 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3619 ALCenum val = 0;
3621 if(!enumName)
3623 VerifyDevice(&device);
3624 alcSetError(device, ALC_INVALID_VALUE);
3625 if(device) ALCdevice_DecRef(device);
3627 else
3629 size_t i = 0;
3630 for(i = 0;i < COUNTOF(alcEnumerations);i++)
3632 if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
3634 val = alcEnumerations[i].value;
3635 break;
3640 return val;
3644 /* alcCreateContext
3646 * Create and attach a context to the given device.
3648 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3650 ALCcontext *ALContext;
3651 ALfloat valf;
3652 ALCenum err;
3654 /* Explicitly hold the list lock while taking the BackendLock in case the
3655 * device is asynchronously destropyed, to ensure this new context is
3656 * properly cleaned up after being made.
3658 LockLists();
3659 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3661 UnlockLists();
3662 alcSetError(device, ALC_INVALID_DEVICE);
3663 if(device) ALCdevice_DecRef(device);
3664 return NULL;
3666 almtx_lock(&device->BackendLock);
3667 UnlockLists();
3669 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3671 if(device->Type == Playback && DefaultEffect.type != AL_EFFECT_NULL)
3672 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener)+sizeof(ALeffectslot));
3673 else
3674 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3675 if(!ALContext)
3677 almtx_unlock(&device->BackendLock);
3679 alcSetError(device, ALC_OUT_OF_MEMORY);
3680 ALCdevice_DecRef(device);
3681 return NULL;
3684 InitRef(&ALContext->ref, 1);
3685 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3686 ALContext->DefaultSlot = NULL;
3688 ALContext->Voices = NULL;
3689 ALContext->VoiceCount = 0;
3690 ALContext->MaxVoices = 0;
3691 ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL);
3692 ALContext->Device = device;
3694 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3696 almtx_unlock(&device->BackendLock);
3698 al_free(ALContext);
3699 ALContext = NULL;
3701 alcSetError(device, err);
3702 if(err == ALC_INVALID_DEVICE)
3704 V0(device->Backend,lock)();
3705 aluHandleDisconnect(device);
3706 V0(device->Backend,unlock)();
3708 ALCdevice_DecRef(device);
3709 return NULL;
3711 AllocateVoices(ALContext, 256, device->NumAuxSends);
3713 if(DefaultEffect.type != AL_EFFECT_NULL && device->Type == Playback)
3715 ALContext->DefaultSlot = (ALeffectslot*)(ALContext->_listener_mem + sizeof(ALlistener));
3716 if(InitEffectSlot(ALContext->DefaultSlot) == AL_NO_ERROR)
3717 aluInitEffectPanning(ALContext->DefaultSlot);
3718 else
3720 ALContext->DefaultSlot = NULL;
3721 ERR("Failed to initialize the default effect slot\n");
3725 ALCdevice_IncRef(ALContext->Device);
3726 InitContext(ALContext);
3728 if(ConfigValueFloat(alstr_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3730 if(!isfinite(valf))
3731 ERR("volume-adjust must be finite: %f\n", valf);
3732 else
3734 ALfloat db = clampf(valf, -24.0f, 24.0f);
3735 if(db != valf)
3736 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3737 ALContext->GainBoost = powf(10.0f, db/20.0f);
3738 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3741 UpdateListenerProps(ALContext);
3744 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3745 do {
3746 ALContext->next = head;
3747 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
3748 ALContext) == 0);
3750 almtx_unlock(&device->BackendLock);
3752 if(ALContext->DefaultSlot)
3754 if(InitializeEffect(ALContext, ALContext->DefaultSlot, &DefaultEffect) == AL_NO_ERROR)
3755 UpdateEffectSlotProps(ALContext->DefaultSlot, ALContext);
3756 else
3757 ERR("Failed to initialize the default effect\n");
3760 ALCdevice_DecRef(device);
3762 TRACE("Created context %p\n", ALContext);
3763 return ALContext;
3766 /* alcDestroyContext
3768 * Remove a context from its device
3770 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3772 ALCdevice *Device;
3774 LockLists();
3775 if(!VerifyContext(&context))
3777 UnlockLists();
3778 alcSetError(NULL, ALC_INVALID_CONTEXT);
3779 return;
3782 Device = context->Device;
3783 if(Device)
3785 almtx_lock(&Device->BackendLock);
3786 if(!ReleaseContext(context, Device))
3788 V0(Device->Backend,stop)();
3789 Device->Flags &= ~DEVICE_RUNNING;
3791 almtx_unlock(&Device->BackendLock);
3793 UnlockLists();
3795 ALCcontext_DecRef(context);
3799 /* alcGetCurrentContext
3801 * Returns the currently active context on the calling thread
3803 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3805 ALCcontext *Context = altss_get(LocalContext);
3806 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3807 return Context;
3810 /* alcGetThreadContext
3812 * Returns the currently active thread-local context
3814 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3816 return altss_get(LocalContext);
3820 /* alcMakeContextCurrent
3822 * Makes the given context the active process-wide context, and removes the
3823 * thread-local context for the calling thread.
3825 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3827 /* context must be valid or NULL */
3828 if(context && !VerifyContext(&context))
3830 alcSetError(NULL, ALC_INVALID_CONTEXT);
3831 return ALC_FALSE;
3833 /* context's reference count is already incremented */
3834 context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
3835 if(context) ALCcontext_DecRef(context);
3837 if((context=altss_get(LocalContext)) != NULL)
3839 altss_set(LocalContext, NULL);
3840 ALCcontext_DecRef(context);
3843 return ALC_TRUE;
3846 /* alcSetThreadContext
3848 * Makes the given context the active context for the current thread
3850 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3852 ALCcontext *old;
3854 /* context must be valid or NULL */
3855 if(context && !VerifyContext(&context))
3857 alcSetError(NULL, ALC_INVALID_CONTEXT);
3858 return ALC_FALSE;
3860 /* context's reference count is already incremented */
3861 old = altss_get(LocalContext);
3862 altss_set(LocalContext, context);
3863 if(old) ALCcontext_DecRef(old);
3865 return ALC_TRUE;
3869 /* alcGetContextsDevice
3871 * Returns the device that a particular context is attached to
3873 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3875 ALCdevice *Device;
3877 if(!VerifyContext(&Context))
3879 alcSetError(NULL, ALC_INVALID_CONTEXT);
3880 return NULL;
3882 Device = Context->Device;
3883 ALCcontext_DecRef(Context);
3885 return Device;
3889 /* alcOpenDevice
3891 * Opens the named device.
3893 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3895 ALCbackendFactory *factory;
3896 const ALCchar *fmt;
3897 ALCdevice *device;
3898 ALCenum err;
3899 ALCsizei i;
3901 DO_INITCONFIG();
3903 if(!PlaybackBackend.name)
3905 alcSetError(NULL, ALC_INVALID_VALUE);
3906 return NULL;
3909 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3910 #ifdef _WIN32
3911 /* Some old Windows apps hardcode these expecting OpenAL to use a
3912 * specific audio API, even when they're not enumerated. Creative's
3913 * router effectively ignores them too.
3915 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3916 || strcasecmp(deviceName, "MMSYSTEM") == 0
3917 #endif
3919 deviceName = NULL;
3921 device = al_calloc(16, sizeof(ALCdevice));
3922 if(!device)
3924 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3925 return NULL;
3928 //Validate device
3929 InitRef(&device->ref, 1);
3930 device->Connected = ALC_TRUE;
3931 device->Type = Playback;
3932 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3934 device->Flags = 0;
3935 device->Bs2b = NULL;
3936 device->Uhj_Encoder = NULL;
3937 device->Hrtf = NULL;
3938 device->HrtfHandle = NULL;
3939 VECTOR_INIT(device->HrtfList);
3940 AL_STRING_INIT(device->HrtfName);
3941 device->Render_Mode = NormalRender;
3942 AL_STRING_INIT(device->DeviceName);
3943 device->Dry.Buffer = NULL;
3944 device->Dry.NumChannels = 0;
3945 device->FOAOut.Buffer = NULL;
3946 device->FOAOut.NumChannels = 0;
3947 device->RealOut.Buffer = NULL;
3948 device->RealOut.NumChannels = 0;
3949 device->Limiter = NULL;
3950 device->AvgSpeakerDist = 0.0f;
3952 ATOMIC_INIT(&device->ContextList, NULL);
3954 device->ClockBase = 0;
3955 device->SamplesDone = 0;
3957 device->SourcesMax = 256;
3958 device->AuxiliaryEffectSlotMax = 64;
3959 device->NumAuxSends = DEFAULT_SENDS;
3961 InitUIntMap(&device->BufferMap, INT_MAX);
3962 InitUIntMap(&device->EffectMap, INT_MAX);
3963 InitUIntMap(&device->FilterMap, INT_MAX);
3965 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3967 device->ChannelDelay[i].Gain = 1.0f;
3968 device->ChannelDelay[i].Length = 0;
3969 device->ChannelDelay[i].Buffer = NULL;
3972 //Set output format
3973 device->FmtChans = DevFmtChannelsDefault;
3974 device->FmtType = DevFmtTypeDefault;
3975 device->Frequency = DEFAULT_OUTPUT_RATE;
3976 device->IsHeadphones = AL_FALSE;
3977 device->AmbiLayout = AmbiLayout_Default;
3978 device->AmbiScale = AmbiNorm_Default;
3979 device->NumUpdates = 3;
3980 device->UpdateSize = 1024;
3982 factory = PlaybackBackend.getFactory();
3983 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3984 if(!device->Backend)
3986 al_free(device);
3987 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3988 return NULL;
3992 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3994 static const struct {
3995 const char name[16];
3996 enum DevFmtChannels chans;
3997 ALsizei order;
3998 } chanlist[] = {
3999 { "mono", DevFmtMono, 0 },
4000 { "stereo", DevFmtStereo, 0 },
4001 { "quad", DevFmtQuad, 0 },
4002 { "surround51", DevFmtX51, 0 },
4003 { "surround61", DevFmtX61, 0 },
4004 { "surround71", DevFmtX71, 0 },
4005 { "surround51rear", DevFmtX51Rear, 0 },
4006 { "ambi1", DevFmtAmbi3D, 1 },
4007 { "ambi2", DevFmtAmbi3D, 2 },
4008 { "ambi3", DevFmtAmbi3D, 3 },
4010 size_t i;
4012 for(i = 0;i < COUNTOF(chanlist);i++)
4014 if(strcasecmp(chanlist[i].name, fmt) == 0)
4016 device->FmtChans = chanlist[i].chans;
4017 device->AmbiOrder = chanlist[i].order;
4018 device->Flags |= DEVICE_CHANNELS_REQUEST;
4019 break;
4022 if(i == COUNTOF(chanlist))
4023 ERR("Unsupported channels: %s\n", fmt);
4025 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
4027 static const struct {
4028 const char name[16];
4029 enum DevFmtType type;
4030 } typelist[] = {
4031 { "int8", DevFmtByte },
4032 { "uint8", DevFmtUByte },
4033 { "int16", DevFmtShort },
4034 { "uint16", DevFmtUShort },
4035 { "int32", DevFmtInt },
4036 { "uint32", DevFmtUInt },
4037 { "float32", DevFmtFloat },
4039 size_t i;
4041 for(i = 0;i < COUNTOF(typelist);i++)
4043 if(strcasecmp(typelist[i].name, fmt) == 0)
4045 device->FmtType = typelist[i].type;
4046 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
4047 break;
4050 if(i == COUNTOF(typelist))
4051 ERR("Unsupported sample-type: %s\n", fmt);
4054 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
4056 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4057 if(device->Frequency < MIN_OUTPUT_RATE)
4058 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
4059 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
4062 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
4063 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
4065 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
4066 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
4067 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
4068 device->UpdateSize = (device->UpdateSize+3)&~3;
4070 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
4071 if(device->SourcesMax == 0) device->SourcesMax = 256;
4073 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4074 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4076 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
4077 device->NumAuxSends = clampi(
4078 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4081 device->NumStereoSources = 1;
4082 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4084 // Find a playback device to open
4085 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4087 DELETE_OBJ(device->Backend);
4088 al_free(device);
4089 alcSetError(NULL, err);
4090 return NULL;
4092 almtx_init(&device->BackendLock, almtx_plain);
4094 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
4096 if(strcasecmp(fmt, "fuma") == 0)
4098 device->AmbiLayout = AmbiLayout_FuMa;
4099 device->AmbiScale = AmbiNorm_FuMa;
4101 else if(strcasecmp(fmt, "acn+sn3d") == 0)
4103 device->AmbiLayout = AmbiLayout_ACN;
4104 device->AmbiScale = AmbiNorm_SN3D;
4106 else if(strcasecmp(fmt, "acn+n3d") == 0)
4108 device->AmbiLayout = AmbiLayout_ACN;
4109 device->AmbiScale = AmbiNorm_N3D;
4111 else
4112 ERR("Unsupported ambi-format: %s\n", fmt);
4115 device->Limiter = CreateDeviceLimiter(device);
4118 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4119 do {
4120 device->next = head;
4121 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4124 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4125 return device;
4128 /* alcCloseDevice
4130 * Closes the given device.
4132 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
4134 ALCdevice *iter, *origdev;
4135 ALCcontext *ctx;
4137 LockLists();
4138 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4139 do {
4140 if(iter == device)
4141 break;
4142 } while((iter=iter->next) != NULL);
4143 if(!iter || iter->Type == Capture)
4145 alcSetError(iter, ALC_INVALID_DEVICE);
4146 UnlockLists();
4147 return ALC_FALSE;
4149 almtx_lock(&device->BackendLock);
4151 origdev = device;
4152 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4154 ALCdevice *volatile*list = &origdev->next;
4155 while(*list)
4157 if(*list == device)
4159 *list = (*list)->next;
4160 break;
4162 list = &(*list)->next;
4165 UnlockLists();
4167 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
4168 while(ctx != NULL)
4170 ALCcontext *next = ctx->next;
4171 WARN("Releasing context %p\n", ctx);
4172 ReleaseContext(ctx, device);
4173 ctx = next;
4175 if((device->Flags&DEVICE_RUNNING))
4176 V0(device->Backend,stop)();
4177 device->Flags &= ~DEVICE_RUNNING;
4178 almtx_unlock(&device->BackendLock);
4180 ALCdevice_DecRef(device);
4182 return ALC_TRUE;
4186 /************************************************
4187 * ALC capture functions
4188 ************************************************/
4189 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4191 ALCbackendFactory *factory;
4192 ALCdevice *device = NULL;
4193 ALCenum err;
4194 ALCsizei i;
4196 DO_INITCONFIG();
4198 if(!CaptureBackend.name)
4200 alcSetError(NULL, ALC_INVALID_VALUE);
4201 return NULL;
4204 if(samples <= 0)
4206 alcSetError(NULL, ALC_INVALID_VALUE);
4207 return NULL;
4210 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4211 deviceName = NULL;
4213 device = al_calloc(16, sizeof(ALCdevice));
4214 if(!device)
4216 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4217 return NULL;
4220 //Validate device
4221 InitRef(&device->ref, 1);
4222 device->Connected = ALC_TRUE;
4223 device->Type = Capture;
4225 device->Hrtf = NULL;
4226 device->HrtfHandle = NULL;
4227 VECTOR_INIT(device->HrtfList);
4228 AL_STRING_INIT(device->HrtfName);
4230 AL_STRING_INIT(device->DeviceName);
4231 device->Dry.Buffer = NULL;
4232 device->Dry.NumChannels = 0;
4233 device->FOAOut.Buffer = NULL;
4234 device->FOAOut.NumChannels = 0;
4235 device->RealOut.Buffer = NULL;
4236 device->RealOut.NumChannels = 0;
4238 InitUIntMap(&device->BufferMap, INT_MAX);
4239 InitUIntMap(&device->EffectMap, INT_MAX);
4240 InitUIntMap(&device->FilterMap, INT_MAX);
4242 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4244 device->ChannelDelay[i].Gain = 1.0f;
4245 device->ChannelDelay[i].Length = 0;
4246 device->ChannelDelay[i].Buffer = NULL;
4249 factory = CaptureBackend.getFactory();
4250 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4251 if(!device->Backend)
4253 al_free(device);
4254 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4255 return NULL;
4258 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4259 device->Frequency = frequency;
4261 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4262 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4264 al_free(device);
4265 alcSetError(NULL, ALC_INVALID_ENUM);
4266 return NULL;
4268 device->IsHeadphones = AL_FALSE;
4269 device->AmbiOrder = 0;
4270 device->AmbiLayout = AmbiLayout_Default;
4271 device->AmbiScale = AmbiNorm_Default;
4273 device->UpdateSize = samples;
4274 device->NumUpdates = 1;
4276 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4277 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
4278 device->Frequency, device->UpdateSize, device->NumUpdates
4280 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4282 al_free(device);
4283 alcSetError(NULL, err);
4284 return NULL;
4286 almtx_init(&device->BackendLock, almtx_plain);
4289 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4290 do {
4291 device->next = head;
4292 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4295 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4296 return device;
4299 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4301 ALCdevice *iter, *origdev;
4303 LockLists();
4304 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4305 do {
4306 if(iter == device)
4307 break;
4308 } while((iter=iter->next) != NULL);
4309 if(!iter || iter->Type != Capture)
4311 alcSetError(iter, ALC_INVALID_DEVICE);
4312 UnlockLists();
4313 return ALC_FALSE;
4316 origdev = device;
4317 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4319 ALCdevice *volatile*list = &origdev->next;
4320 while(*list)
4322 if(*list == device)
4324 *list = (*list)->next;
4325 break;
4327 list = &(*list)->next;
4330 UnlockLists();
4332 ALCdevice_DecRef(device);
4334 return ALC_TRUE;
4337 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4339 if(!VerifyDevice(&device) || device->Type != Capture)
4340 alcSetError(device, ALC_INVALID_DEVICE);
4341 else
4343 almtx_lock(&device->BackendLock);
4344 if(!device->Connected)
4345 alcSetError(device, ALC_INVALID_DEVICE);
4346 else if(!(device->Flags&DEVICE_RUNNING))
4348 if(V0(device->Backend,start)())
4349 device->Flags |= DEVICE_RUNNING;
4350 else
4352 aluHandleDisconnect(device);
4353 alcSetError(device, ALC_INVALID_DEVICE);
4356 almtx_unlock(&device->BackendLock);
4359 if(device) ALCdevice_DecRef(device);
4362 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4364 if(!VerifyDevice(&device) || device->Type != Capture)
4365 alcSetError(device, ALC_INVALID_DEVICE);
4366 else
4368 almtx_lock(&device->BackendLock);
4369 if((device->Flags&DEVICE_RUNNING))
4370 V0(device->Backend,stop)();
4371 device->Flags &= ~DEVICE_RUNNING;
4372 almtx_unlock(&device->BackendLock);
4375 if(device) ALCdevice_DecRef(device);
4378 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4380 if(!VerifyDevice(&device) || device->Type != Capture)
4381 alcSetError(device, ALC_INVALID_DEVICE);
4382 else
4384 ALCenum err = ALC_INVALID_VALUE;
4386 almtx_lock(&device->BackendLock);
4387 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4388 err = V(device->Backend,captureSamples)(buffer, samples);
4389 almtx_unlock(&device->BackendLock);
4391 if(err != ALC_NO_ERROR)
4392 alcSetError(device, err);
4394 if(device) ALCdevice_DecRef(device);
4398 /************************************************
4399 * ALC loopback functions
4400 ************************************************/
4402 /* alcLoopbackOpenDeviceSOFT
4404 * Open a loopback device, for manual rendering.
4406 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4408 ALCbackendFactory *factory;
4409 ALCdevice *device;
4410 ALCsizei i;
4412 DO_INITCONFIG();
4414 /* Make sure the device name, if specified, is us. */
4415 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4417 alcSetError(NULL, ALC_INVALID_VALUE);
4418 return NULL;
4421 device = al_calloc(16, sizeof(ALCdevice));
4422 if(!device)
4424 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4425 return NULL;
4428 //Validate device
4429 InitRef(&device->ref, 1);
4430 device->Connected = ALC_TRUE;
4431 device->Type = Loopback;
4432 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4434 device->Flags = 0;
4435 device->Hrtf = NULL;
4436 device->HrtfHandle = NULL;
4437 VECTOR_INIT(device->HrtfList);
4438 AL_STRING_INIT(device->HrtfName);
4439 device->Bs2b = NULL;
4440 device->Uhj_Encoder = NULL;
4441 device->Render_Mode = NormalRender;
4442 AL_STRING_INIT(device->DeviceName);
4443 device->Dry.Buffer = NULL;
4444 device->Dry.NumChannels = 0;
4445 device->FOAOut.Buffer = NULL;
4446 device->FOAOut.NumChannels = 0;
4447 device->RealOut.Buffer = NULL;
4448 device->RealOut.NumChannels = 0;
4449 device->Limiter = NULL;
4450 device->AvgSpeakerDist = 0.0f;
4452 ATOMIC_INIT(&device->ContextList, NULL);
4454 device->ClockBase = 0;
4455 device->SamplesDone = 0;
4457 device->SourcesMax = 256;
4458 device->AuxiliaryEffectSlotMax = 64;
4459 device->NumAuxSends = DEFAULT_SENDS;
4461 InitUIntMap(&device->BufferMap, INT_MAX);
4462 InitUIntMap(&device->EffectMap, INT_MAX);
4463 InitUIntMap(&device->FilterMap, INT_MAX);
4465 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4467 device->ChannelDelay[i].Gain = 1.0f;
4468 device->ChannelDelay[i].Length = 0;
4469 device->ChannelDelay[i].Buffer = NULL;
4472 factory = ALCloopbackFactory_getFactory();
4473 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4474 if(!device->Backend)
4476 al_free(device);
4477 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4478 return NULL;
4480 almtx_init(&device->BackendLock, almtx_plain);
4482 //Set output format
4483 device->NumUpdates = 0;
4484 device->UpdateSize = 0;
4486 device->Frequency = DEFAULT_OUTPUT_RATE;
4487 device->FmtChans = DevFmtChannelsDefault;
4488 device->FmtType = DevFmtTypeDefault;
4489 device->IsHeadphones = AL_FALSE;
4490 device->AmbiLayout = AmbiLayout_Default;
4491 device->AmbiScale = AmbiNorm_Default;
4493 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4494 if(device->SourcesMax == 0) device->SourcesMax = 256;
4496 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4497 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4499 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4500 device->NumAuxSends = clampi(
4501 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4504 device->NumStereoSources = 1;
4505 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4507 // Open the "backend"
4508 V(device->Backend,open)("Loopback");
4510 device->Limiter = CreateDeviceLimiter(device);
4513 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4514 do {
4515 device->next = head;
4516 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4519 TRACE("Created device %p\n", device);
4520 return device;
4523 /* alcIsRenderFormatSupportedSOFT
4525 * Determines if the loopback device supports the given format for rendering.
4527 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4529 ALCboolean ret = ALC_FALSE;
4531 if(!VerifyDevice(&device) || device->Type != Loopback)
4532 alcSetError(device, ALC_INVALID_DEVICE);
4533 else if(freq <= 0)
4534 alcSetError(device, ALC_INVALID_VALUE);
4535 else
4537 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4538 ret = ALC_TRUE;
4540 if(device) ALCdevice_DecRef(device);
4542 return ret;
4545 /* alcRenderSamplesSOFT
4547 * Renders some samples into a buffer, using the format last set by the
4548 * attributes given to alcCreateContext.
4550 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4552 if(!VerifyDevice(&device) || device->Type != Loopback)
4553 alcSetError(device, ALC_INVALID_DEVICE);
4554 else if(samples < 0 || (samples > 0 && buffer == NULL))
4555 alcSetError(device, ALC_INVALID_VALUE);
4556 else
4558 V0(device->Backend,lock)();
4559 aluMixData(device, buffer, samples);
4560 V0(device->Backend,unlock)();
4562 if(device) ALCdevice_DecRef(device);
4566 /************************************************
4567 * ALC loopback2 functions
4568 ************************************************/
4570 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4572 ALCboolean ret = ALC_FALSE;
4574 if(!VerifyDevice(&device) || device->Type != Loopback)
4575 alcSetError(device, ALC_INVALID_DEVICE);
4576 else if(order <= 0)
4577 alcSetError(device, ALC_INVALID_VALUE);
4578 else
4580 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4581 ret = ALC_TRUE;
4583 if(device) ALCdevice_DecRef(device);
4585 return ret;
4588 /************************************************
4589 * ALC DSP pause/resume functions
4590 ************************************************/
4592 /* alcDevicePauseSOFT
4594 * Pause the DSP to stop audio processing.
4596 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4598 if(!VerifyDevice(&device) || device->Type != Playback)
4599 alcSetError(device, ALC_INVALID_DEVICE);
4600 else
4602 almtx_lock(&device->BackendLock);
4603 if((device->Flags&DEVICE_RUNNING))
4604 V0(device->Backend,stop)();
4605 device->Flags &= ~DEVICE_RUNNING;
4606 device->Flags |= DEVICE_PAUSED;
4607 almtx_unlock(&device->BackendLock);
4609 if(device) ALCdevice_DecRef(device);
4612 /* alcDeviceResumeSOFT
4614 * Resume the DSP to restart audio processing.
4616 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4618 if(!VerifyDevice(&device) || device->Type != Playback)
4619 alcSetError(device, ALC_INVALID_DEVICE);
4620 else
4622 almtx_lock(&device->BackendLock);
4623 if((device->Flags&DEVICE_PAUSED))
4625 device->Flags &= ~DEVICE_PAUSED;
4626 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4628 if(V0(device->Backend,start)() != ALC_FALSE)
4629 device->Flags |= DEVICE_RUNNING;
4630 else
4632 alcSetError(device, ALC_INVALID_DEVICE);
4633 V0(device->Backend,lock)();
4634 aluHandleDisconnect(device);
4635 V0(device->Backend,unlock)();
4639 almtx_unlock(&device->BackendLock);
4641 if(device) ALCdevice_DecRef(device);
4645 /************************************************
4646 * ALC HRTF functions
4647 ************************************************/
4649 /* alcGetStringiSOFT
4651 * Gets a string parameter at the given index.
4653 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4655 const ALCchar *str = NULL;
4657 if(!VerifyDevice(&device) || device->Type == Capture)
4658 alcSetError(device, ALC_INVALID_DEVICE);
4659 else switch(paramName)
4661 case ALC_HRTF_SPECIFIER_SOFT:
4662 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList))
4663 str = alstr_get_cstr(VECTOR_ELEM(device->HrtfList, index).name);
4664 else
4665 alcSetError(device, ALC_INVALID_VALUE);
4666 break;
4668 default:
4669 alcSetError(device, ALC_INVALID_ENUM);
4670 break;
4672 if(device) ALCdevice_DecRef(device);
4674 return str;
4677 /* alcResetDeviceSOFT
4679 * Resets the given device output, using the specified attribute list.
4681 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4683 ALCenum err;
4685 LockLists();
4686 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4688 UnlockLists();
4689 alcSetError(device, ALC_INVALID_DEVICE);
4690 if(device) ALCdevice_DecRef(device);
4691 return ALC_FALSE;
4693 almtx_lock(&device->BackendLock);
4694 UnlockLists();
4696 err = UpdateDeviceParams(device, attribs);
4697 almtx_unlock(&device->BackendLock);
4699 if(err != ALC_NO_ERROR)
4701 alcSetError(device, err);
4702 if(err == ALC_INVALID_DEVICE)
4704 V0(device->Backend,lock)();
4705 aluHandleDisconnect(device);
4706 V0(device->Backend,unlock)();
4708 ALCdevice_DecRef(device);
4709 return ALC_FALSE;
4711 ALCdevice_DecRef(device);
4713 return ALC_TRUE;