Initialize the default effect after device update
[openal-soft.git] / Alc / ALc.c
blobece66273811b7d7ab1c02d16f6acf28eda0cb091
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include "version.h"
25 #include <math.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <memory.h>
29 #include <ctype.h>
30 #include <signal.h>
32 #include "alMain.h"
33 #include "alSource.h"
34 #include "alListener.h"
35 #include "alThunk.h"
36 #include "alSource.h"
37 #include "alBuffer.h"
38 #include "alAuxEffectSlot.h"
39 #include "alError.h"
40 #include "bformatdec.h"
41 #include "alu.h"
43 #include "compat.h"
44 #include "threads.h"
45 #include "alstring.h"
46 #include "almalloc.h"
48 #include "backends/base.h"
51 /************************************************
52 * Backends
53 ************************************************/
54 struct BackendInfo {
55 const char *name;
56 ALCbackendFactory* (*getFactory)(void);
59 static struct BackendInfo BackendList[] = {
60 #ifdef HAVE_JACK
61 { "jack", ALCjackBackendFactory_getFactory },
62 #endif
63 #ifdef HAVE_PULSEAUDIO
64 { "pulse", ALCpulseBackendFactory_getFactory },
65 #endif
66 #ifdef HAVE_ALSA
67 { "alsa", ALCalsaBackendFactory_getFactory },
68 #endif
69 #ifdef HAVE_COREAUDIO
70 { "core", ALCcoreAudioBackendFactory_getFactory },
71 #endif
72 #ifdef HAVE_OSS
73 { "oss", ALCossBackendFactory_getFactory },
74 #endif
75 #ifdef HAVE_SOLARIS
76 { "solaris", ALCsolarisBackendFactory_getFactory },
77 #endif
78 #ifdef HAVE_SNDIO
79 { "sndio", ALCsndioBackendFactory_getFactory },
80 #endif
81 #ifdef HAVE_QSA
82 { "qsa", ALCqsaBackendFactory_getFactory },
83 #endif
84 #ifdef HAVE_MMDEVAPI
85 { "mmdevapi", ALCmmdevBackendFactory_getFactory },
86 #endif
87 #ifdef HAVE_DSOUND
88 { "dsound", ALCdsoundBackendFactory_getFactory },
89 #endif
90 #ifdef HAVE_WINMM
91 { "winmm", ALCwinmmBackendFactory_getFactory },
92 #endif
93 #ifdef HAVE_PORTAUDIO
94 { "port", ALCportBackendFactory_getFactory },
95 #endif
96 #ifdef HAVE_OPENSL
97 { "opensl", ALCopenslBackendFactory_getFactory },
98 #endif
100 { "null", ALCnullBackendFactory_getFactory },
101 #ifdef HAVE_WAVE
102 { "wave", ALCwaveBackendFactory_getFactory },
103 #endif
105 static ALsizei BackendListSize = COUNTOF(BackendList);
106 #undef EmptyFuncs
108 static struct BackendInfo PlaybackBackend;
109 static struct BackendInfo CaptureBackend;
112 /************************************************
113 * Functions, enums, and errors
114 ************************************************/
115 #define DECL(x) { #x, (ALCvoid*)(x) }
116 static const struct {
117 const ALCchar *funcName;
118 ALCvoid *address;
119 } alcFunctions[] = {
120 DECL(alcCreateContext),
121 DECL(alcMakeContextCurrent),
122 DECL(alcProcessContext),
123 DECL(alcSuspendContext),
124 DECL(alcDestroyContext),
125 DECL(alcGetCurrentContext),
126 DECL(alcGetContextsDevice),
127 DECL(alcOpenDevice),
128 DECL(alcCloseDevice),
129 DECL(alcGetError),
130 DECL(alcIsExtensionPresent),
131 DECL(alcGetProcAddress),
132 DECL(alcGetEnumValue),
133 DECL(alcGetString),
134 DECL(alcGetIntegerv),
135 DECL(alcCaptureOpenDevice),
136 DECL(alcCaptureCloseDevice),
137 DECL(alcCaptureStart),
138 DECL(alcCaptureStop),
139 DECL(alcCaptureSamples),
141 DECL(alcSetThreadContext),
142 DECL(alcGetThreadContext),
144 DECL(alcLoopbackOpenDeviceSOFT),
145 DECL(alcIsRenderFormatSupportedSOFT),
146 DECL(alcRenderSamplesSOFT),
148 DECL(alcIsAmbisonicFormatSupportedSOFT),
150 DECL(alcDevicePauseSOFT),
151 DECL(alcDeviceResumeSOFT),
153 DECL(alcGetStringiSOFT),
154 DECL(alcResetDeviceSOFT),
156 DECL(alcGetInteger64vSOFT),
158 DECL(alEnable),
159 DECL(alDisable),
160 DECL(alIsEnabled),
161 DECL(alGetString),
162 DECL(alGetBooleanv),
163 DECL(alGetIntegerv),
164 DECL(alGetFloatv),
165 DECL(alGetDoublev),
166 DECL(alGetBoolean),
167 DECL(alGetInteger),
168 DECL(alGetFloat),
169 DECL(alGetDouble),
170 DECL(alGetError),
171 DECL(alIsExtensionPresent),
172 DECL(alGetProcAddress),
173 DECL(alGetEnumValue),
174 DECL(alListenerf),
175 DECL(alListener3f),
176 DECL(alListenerfv),
177 DECL(alListeneri),
178 DECL(alListener3i),
179 DECL(alListeneriv),
180 DECL(alGetListenerf),
181 DECL(alGetListener3f),
182 DECL(alGetListenerfv),
183 DECL(alGetListeneri),
184 DECL(alGetListener3i),
185 DECL(alGetListeneriv),
186 DECL(alGenSources),
187 DECL(alDeleteSources),
188 DECL(alIsSource),
189 DECL(alSourcef),
190 DECL(alSource3f),
191 DECL(alSourcefv),
192 DECL(alSourcei),
193 DECL(alSource3i),
194 DECL(alSourceiv),
195 DECL(alGetSourcef),
196 DECL(alGetSource3f),
197 DECL(alGetSourcefv),
198 DECL(alGetSourcei),
199 DECL(alGetSource3i),
200 DECL(alGetSourceiv),
201 DECL(alSourcePlayv),
202 DECL(alSourceStopv),
203 DECL(alSourceRewindv),
204 DECL(alSourcePausev),
205 DECL(alSourcePlay),
206 DECL(alSourceStop),
207 DECL(alSourceRewind),
208 DECL(alSourcePause),
209 DECL(alSourceQueueBuffers),
210 DECL(alSourceUnqueueBuffers),
211 DECL(alGenBuffers),
212 DECL(alDeleteBuffers),
213 DECL(alIsBuffer),
214 DECL(alBufferData),
215 DECL(alBufferf),
216 DECL(alBuffer3f),
217 DECL(alBufferfv),
218 DECL(alBufferi),
219 DECL(alBuffer3i),
220 DECL(alBufferiv),
221 DECL(alGetBufferf),
222 DECL(alGetBuffer3f),
223 DECL(alGetBufferfv),
224 DECL(alGetBufferi),
225 DECL(alGetBuffer3i),
226 DECL(alGetBufferiv),
227 DECL(alDopplerFactor),
228 DECL(alDopplerVelocity),
229 DECL(alSpeedOfSound),
230 DECL(alDistanceModel),
232 DECL(alGenFilters),
233 DECL(alDeleteFilters),
234 DECL(alIsFilter),
235 DECL(alFilteri),
236 DECL(alFilteriv),
237 DECL(alFilterf),
238 DECL(alFilterfv),
239 DECL(alGetFilteri),
240 DECL(alGetFilteriv),
241 DECL(alGetFilterf),
242 DECL(alGetFilterfv),
243 DECL(alGenEffects),
244 DECL(alDeleteEffects),
245 DECL(alIsEffect),
246 DECL(alEffecti),
247 DECL(alEffectiv),
248 DECL(alEffectf),
249 DECL(alEffectfv),
250 DECL(alGetEffecti),
251 DECL(alGetEffectiv),
252 DECL(alGetEffectf),
253 DECL(alGetEffectfv),
254 DECL(alGenAuxiliaryEffectSlots),
255 DECL(alDeleteAuxiliaryEffectSlots),
256 DECL(alIsAuxiliaryEffectSlot),
257 DECL(alAuxiliaryEffectSloti),
258 DECL(alAuxiliaryEffectSlotiv),
259 DECL(alAuxiliaryEffectSlotf),
260 DECL(alAuxiliaryEffectSlotfv),
261 DECL(alGetAuxiliaryEffectSloti),
262 DECL(alGetAuxiliaryEffectSlotiv),
263 DECL(alGetAuxiliaryEffectSlotf),
264 DECL(alGetAuxiliaryEffectSlotfv),
266 DECL(alDeferUpdatesSOFT),
267 DECL(alProcessUpdatesSOFT),
269 DECL(alSourcedSOFT),
270 DECL(alSource3dSOFT),
271 DECL(alSourcedvSOFT),
272 DECL(alGetSourcedSOFT),
273 DECL(alGetSource3dSOFT),
274 DECL(alGetSourcedvSOFT),
275 DECL(alSourcei64SOFT),
276 DECL(alSource3i64SOFT),
277 DECL(alSourcei64vSOFT),
278 DECL(alGetSourcei64SOFT),
279 DECL(alGetSource3i64SOFT),
280 DECL(alGetSourcei64vSOFT),
282 DECL(alBufferSamplesSOFT),
283 DECL(alGetBufferSamplesSOFT),
284 DECL(alIsBufferFormatSupportedSOFT),
286 DECL(alGetStringiSOFT),
288 #undef DECL
290 #define DECL(x) { #x, (x) }
291 static const struct {
292 const ALCchar *enumName;
293 ALCenum value;
294 } alcEnumerations[] = {
295 DECL(ALC_INVALID),
296 DECL(ALC_FALSE),
297 DECL(ALC_TRUE),
299 DECL(ALC_MAJOR_VERSION),
300 DECL(ALC_MINOR_VERSION),
301 DECL(ALC_ATTRIBUTES_SIZE),
302 DECL(ALC_ALL_ATTRIBUTES),
303 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
304 DECL(ALC_DEVICE_SPECIFIER),
305 DECL(ALC_ALL_DEVICES_SPECIFIER),
306 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
307 DECL(ALC_EXTENSIONS),
308 DECL(ALC_FREQUENCY),
309 DECL(ALC_REFRESH),
310 DECL(ALC_SYNC),
311 DECL(ALC_MONO_SOURCES),
312 DECL(ALC_STEREO_SOURCES),
313 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
314 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
315 DECL(ALC_CAPTURE_SAMPLES),
316 DECL(ALC_CONNECTED),
318 DECL(ALC_EFX_MAJOR_VERSION),
319 DECL(ALC_EFX_MINOR_VERSION),
320 DECL(ALC_MAX_AUXILIARY_SENDS),
322 DECL(ALC_FORMAT_CHANNELS_SOFT),
323 DECL(ALC_FORMAT_TYPE_SOFT),
325 DECL(ALC_MONO_SOFT),
326 DECL(ALC_STEREO_SOFT),
327 DECL(ALC_QUAD_SOFT),
328 DECL(ALC_5POINT1_SOFT),
329 DECL(ALC_6POINT1_SOFT),
330 DECL(ALC_7POINT1_SOFT),
331 DECL(ALC_BFORMAT3D_SOFT),
333 DECL(ALC_BYTE_SOFT),
334 DECL(ALC_UNSIGNED_BYTE_SOFT),
335 DECL(ALC_SHORT_SOFT),
336 DECL(ALC_UNSIGNED_SHORT_SOFT),
337 DECL(ALC_INT_SOFT),
338 DECL(ALC_UNSIGNED_INT_SOFT),
339 DECL(ALC_FLOAT_SOFT),
341 DECL(ALC_HRTF_SOFT),
342 DECL(ALC_DONT_CARE_SOFT),
343 DECL(ALC_HRTF_STATUS_SOFT),
344 DECL(ALC_HRTF_DISABLED_SOFT),
345 DECL(ALC_HRTF_ENABLED_SOFT),
346 DECL(ALC_HRTF_DENIED_SOFT),
347 DECL(ALC_HRTF_REQUIRED_SOFT),
348 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
349 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
350 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
351 DECL(ALC_HRTF_SPECIFIER_SOFT),
352 DECL(ALC_HRTF_ID_SOFT),
354 DECL(ALC_AMBISONIC_LAYOUT_SOFT),
355 DECL(ALC_AMBISONIC_SCALING_SOFT),
356 DECL(ALC_AMBISONIC_ORDER_SOFT),
357 DECL(ALC_ACN_SOFT),
358 DECL(ALC_FUMA_SOFT),
359 DECL(ALC_N3D_SOFT),
360 DECL(ALC_SN3D_SOFT),
362 DECL(ALC_OUTPUT_LIMITER_SOFT),
364 DECL(ALC_NO_ERROR),
365 DECL(ALC_INVALID_DEVICE),
366 DECL(ALC_INVALID_CONTEXT),
367 DECL(ALC_INVALID_ENUM),
368 DECL(ALC_INVALID_VALUE),
369 DECL(ALC_OUT_OF_MEMORY),
372 DECL(AL_INVALID),
373 DECL(AL_NONE),
374 DECL(AL_FALSE),
375 DECL(AL_TRUE),
377 DECL(AL_SOURCE_RELATIVE),
378 DECL(AL_CONE_INNER_ANGLE),
379 DECL(AL_CONE_OUTER_ANGLE),
380 DECL(AL_PITCH),
381 DECL(AL_POSITION),
382 DECL(AL_DIRECTION),
383 DECL(AL_VELOCITY),
384 DECL(AL_LOOPING),
385 DECL(AL_BUFFER),
386 DECL(AL_GAIN),
387 DECL(AL_MIN_GAIN),
388 DECL(AL_MAX_GAIN),
389 DECL(AL_ORIENTATION),
390 DECL(AL_REFERENCE_DISTANCE),
391 DECL(AL_ROLLOFF_FACTOR),
392 DECL(AL_CONE_OUTER_GAIN),
393 DECL(AL_MAX_DISTANCE),
394 DECL(AL_SEC_OFFSET),
395 DECL(AL_SAMPLE_OFFSET),
396 DECL(AL_BYTE_OFFSET),
397 DECL(AL_SOURCE_TYPE),
398 DECL(AL_STATIC),
399 DECL(AL_STREAMING),
400 DECL(AL_UNDETERMINED),
401 DECL(AL_METERS_PER_UNIT),
402 DECL(AL_LOOP_POINTS_SOFT),
403 DECL(AL_DIRECT_CHANNELS_SOFT),
405 DECL(AL_DIRECT_FILTER),
406 DECL(AL_AUXILIARY_SEND_FILTER),
407 DECL(AL_AIR_ABSORPTION_FACTOR),
408 DECL(AL_ROOM_ROLLOFF_FACTOR),
409 DECL(AL_CONE_OUTER_GAINHF),
410 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
411 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
412 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
414 DECL(AL_SOURCE_STATE),
415 DECL(AL_INITIAL),
416 DECL(AL_PLAYING),
417 DECL(AL_PAUSED),
418 DECL(AL_STOPPED),
420 DECL(AL_BUFFERS_QUEUED),
421 DECL(AL_BUFFERS_PROCESSED),
423 DECL(AL_FORMAT_MONO8),
424 DECL(AL_FORMAT_MONO16),
425 DECL(AL_FORMAT_MONO_FLOAT32),
426 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
427 DECL(AL_FORMAT_STEREO8),
428 DECL(AL_FORMAT_STEREO16),
429 DECL(AL_FORMAT_STEREO_FLOAT32),
430 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
431 DECL(AL_FORMAT_MONO_IMA4),
432 DECL(AL_FORMAT_STEREO_IMA4),
433 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
434 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
435 DECL(AL_FORMAT_QUAD8_LOKI),
436 DECL(AL_FORMAT_QUAD16_LOKI),
437 DECL(AL_FORMAT_QUAD8),
438 DECL(AL_FORMAT_QUAD16),
439 DECL(AL_FORMAT_QUAD32),
440 DECL(AL_FORMAT_51CHN8),
441 DECL(AL_FORMAT_51CHN16),
442 DECL(AL_FORMAT_51CHN32),
443 DECL(AL_FORMAT_61CHN8),
444 DECL(AL_FORMAT_61CHN16),
445 DECL(AL_FORMAT_61CHN32),
446 DECL(AL_FORMAT_71CHN8),
447 DECL(AL_FORMAT_71CHN16),
448 DECL(AL_FORMAT_71CHN32),
449 DECL(AL_FORMAT_REAR8),
450 DECL(AL_FORMAT_REAR16),
451 DECL(AL_FORMAT_REAR32),
452 DECL(AL_FORMAT_MONO_MULAW),
453 DECL(AL_FORMAT_MONO_MULAW_EXT),
454 DECL(AL_FORMAT_STEREO_MULAW),
455 DECL(AL_FORMAT_STEREO_MULAW_EXT),
456 DECL(AL_FORMAT_QUAD_MULAW),
457 DECL(AL_FORMAT_51CHN_MULAW),
458 DECL(AL_FORMAT_61CHN_MULAW),
459 DECL(AL_FORMAT_71CHN_MULAW),
460 DECL(AL_FORMAT_REAR_MULAW),
461 DECL(AL_FORMAT_MONO_ALAW_EXT),
462 DECL(AL_FORMAT_STEREO_ALAW_EXT),
464 DECL(AL_FORMAT_BFORMAT2D_8),
465 DECL(AL_FORMAT_BFORMAT2D_16),
466 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
467 DECL(AL_FORMAT_BFORMAT2D_MULAW),
468 DECL(AL_FORMAT_BFORMAT3D_8),
469 DECL(AL_FORMAT_BFORMAT3D_16),
470 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
471 DECL(AL_FORMAT_BFORMAT3D_MULAW),
473 DECL(AL_MONO8_SOFT),
474 DECL(AL_MONO16_SOFT),
475 DECL(AL_MONO32F_SOFT),
476 DECL(AL_STEREO8_SOFT),
477 DECL(AL_STEREO16_SOFT),
478 DECL(AL_STEREO32F_SOFT),
479 DECL(AL_QUAD8_SOFT),
480 DECL(AL_QUAD16_SOFT),
481 DECL(AL_QUAD32F_SOFT),
482 DECL(AL_REAR8_SOFT),
483 DECL(AL_REAR16_SOFT),
484 DECL(AL_REAR32F_SOFT),
485 DECL(AL_5POINT1_8_SOFT),
486 DECL(AL_5POINT1_16_SOFT),
487 DECL(AL_5POINT1_32F_SOFT),
488 DECL(AL_6POINT1_8_SOFT),
489 DECL(AL_6POINT1_16_SOFT),
490 DECL(AL_6POINT1_32F_SOFT),
491 DECL(AL_7POINT1_8_SOFT),
492 DECL(AL_7POINT1_16_SOFT),
493 DECL(AL_7POINT1_32F_SOFT),
494 DECL(AL_BFORMAT2D_8_SOFT),
495 DECL(AL_BFORMAT2D_16_SOFT),
496 DECL(AL_BFORMAT2D_32F_SOFT),
497 DECL(AL_BFORMAT3D_8_SOFT),
498 DECL(AL_BFORMAT3D_16_SOFT),
499 DECL(AL_BFORMAT3D_32F_SOFT),
501 DECL(AL_MONO_SOFT),
502 DECL(AL_STEREO_SOFT),
503 DECL(AL_QUAD_SOFT),
504 DECL(AL_REAR_SOFT),
505 DECL(AL_5POINT1_SOFT),
506 DECL(AL_6POINT1_SOFT),
507 DECL(AL_7POINT1_SOFT),
508 DECL(AL_BFORMAT2D_SOFT),
509 DECL(AL_BFORMAT3D_SOFT),
511 DECL(AL_BYTE_SOFT),
512 DECL(AL_UNSIGNED_BYTE_SOFT),
513 DECL(AL_SHORT_SOFT),
514 DECL(AL_UNSIGNED_SHORT_SOFT),
515 DECL(AL_INT_SOFT),
516 DECL(AL_UNSIGNED_INT_SOFT),
517 DECL(AL_FLOAT_SOFT),
518 DECL(AL_DOUBLE_SOFT),
519 DECL(AL_BYTE3_SOFT),
520 DECL(AL_UNSIGNED_BYTE3_SOFT),
521 DECL(AL_MULAW_SOFT),
523 DECL(AL_FREQUENCY),
524 DECL(AL_BITS),
525 DECL(AL_CHANNELS),
526 DECL(AL_SIZE),
527 DECL(AL_INTERNAL_FORMAT_SOFT),
528 DECL(AL_BYTE_LENGTH_SOFT),
529 DECL(AL_SAMPLE_LENGTH_SOFT),
530 DECL(AL_SEC_LENGTH_SOFT),
531 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
532 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
534 DECL(AL_SOURCE_RADIUS),
536 DECL(AL_STEREO_ANGLES),
538 DECL(AL_UNUSED),
539 DECL(AL_PENDING),
540 DECL(AL_PROCESSED),
542 DECL(AL_NO_ERROR),
543 DECL(AL_INVALID_NAME),
544 DECL(AL_INVALID_ENUM),
545 DECL(AL_INVALID_VALUE),
546 DECL(AL_INVALID_OPERATION),
547 DECL(AL_OUT_OF_MEMORY),
549 DECL(AL_VENDOR),
550 DECL(AL_VERSION),
551 DECL(AL_RENDERER),
552 DECL(AL_EXTENSIONS),
554 DECL(AL_DOPPLER_FACTOR),
555 DECL(AL_DOPPLER_VELOCITY),
556 DECL(AL_DISTANCE_MODEL),
557 DECL(AL_SPEED_OF_SOUND),
558 DECL(AL_SOURCE_DISTANCE_MODEL),
559 DECL(AL_DEFERRED_UPDATES_SOFT),
560 DECL(AL_GAIN_LIMIT_SOFT),
562 DECL(AL_INVERSE_DISTANCE),
563 DECL(AL_INVERSE_DISTANCE_CLAMPED),
564 DECL(AL_LINEAR_DISTANCE),
565 DECL(AL_LINEAR_DISTANCE_CLAMPED),
566 DECL(AL_EXPONENT_DISTANCE),
567 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
569 DECL(AL_FILTER_TYPE),
570 DECL(AL_FILTER_NULL),
571 DECL(AL_FILTER_LOWPASS),
572 DECL(AL_FILTER_HIGHPASS),
573 DECL(AL_FILTER_BANDPASS),
575 DECL(AL_LOWPASS_GAIN),
576 DECL(AL_LOWPASS_GAINHF),
578 DECL(AL_HIGHPASS_GAIN),
579 DECL(AL_HIGHPASS_GAINLF),
581 DECL(AL_BANDPASS_GAIN),
582 DECL(AL_BANDPASS_GAINHF),
583 DECL(AL_BANDPASS_GAINLF),
585 DECL(AL_EFFECT_TYPE),
586 DECL(AL_EFFECT_NULL),
587 DECL(AL_EFFECT_REVERB),
588 DECL(AL_EFFECT_EAXREVERB),
589 DECL(AL_EFFECT_CHORUS),
590 DECL(AL_EFFECT_DISTORTION),
591 DECL(AL_EFFECT_ECHO),
592 DECL(AL_EFFECT_FLANGER),
593 #if 0
594 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
595 DECL(AL_EFFECT_VOCAL_MORPHER),
596 DECL(AL_EFFECT_PITCH_SHIFTER),
597 #endif
598 DECL(AL_EFFECT_RING_MODULATOR),
599 #if 0
600 DECL(AL_EFFECT_AUTOWAH),
601 #endif
602 DECL(AL_EFFECT_COMPRESSOR),
603 DECL(AL_EFFECT_EQUALIZER),
604 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
605 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
607 DECL(AL_EFFECTSLOT_EFFECT),
608 DECL(AL_EFFECTSLOT_GAIN),
609 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
610 DECL(AL_EFFECTSLOT_NULL),
612 DECL(AL_EAXREVERB_DENSITY),
613 DECL(AL_EAXREVERB_DIFFUSION),
614 DECL(AL_EAXREVERB_GAIN),
615 DECL(AL_EAXREVERB_GAINHF),
616 DECL(AL_EAXREVERB_GAINLF),
617 DECL(AL_EAXREVERB_DECAY_TIME),
618 DECL(AL_EAXREVERB_DECAY_HFRATIO),
619 DECL(AL_EAXREVERB_DECAY_LFRATIO),
620 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
621 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
622 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
623 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
624 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
625 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
626 DECL(AL_EAXREVERB_ECHO_TIME),
627 DECL(AL_EAXREVERB_ECHO_DEPTH),
628 DECL(AL_EAXREVERB_MODULATION_TIME),
629 DECL(AL_EAXREVERB_MODULATION_DEPTH),
630 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
631 DECL(AL_EAXREVERB_HFREFERENCE),
632 DECL(AL_EAXREVERB_LFREFERENCE),
633 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
634 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
636 DECL(AL_REVERB_DENSITY),
637 DECL(AL_REVERB_DIFFUSION),
638 DECL(AL_REVERB_GAIN),
639 DECL(AL_REVERB_GAINHF),
640 DECL(AL_REVERB_DECAY_TIME),
641 DECL(AL_REVERB_DECAY_HFRATIO),
642 DECL(AL_REVERB_REFLECTIONS_GAIN),
643 DECL(AL_REVERB_REFLECTIONS_DELAY),
644 DECL(AL_REVERB_LATE_REVERB_GAIN),
645 DECL(AL_REVERB_LATE_REVERB_DELAY),
646 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
647 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
648 DECL(AL_REVERB_DECAY_HFLIMIT),
650 DECL(AL_CHORUS_WAVEFORM),
651 DECL(AL_CHORUS_PHASE),
652 DECL(AL_CHORUS_RATE),
653 DECL(AL_CHORUS_DEPTH),
654 DECL(AL_CHORUS_FEEDBACK),
655 DECL(AL_CHORUS_DELAY),
657 DECL(AL_DISTORTION_EDGE),
658 DECL(AL_DISTORTION_GAIN),
659 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
660 DECL(AL_DISTORTION_EQCENTER),
661 DECL(AL_DISTORTION_EQBANDWIDTH),
663 DECL(AL_ECHO_DELAY),
664 DECL(AL_ECHO_LRDELAY),
665 DECL(AL_ECHO_DAMPING),
666 DECL(AL_ECHO_FEEDBACK),
667 DECL(AL_ECHO_SPREAD),
669 DECL(AL_FLANGER_WAVEFORM),
670 DECL(AL_FLANGER_PHASE),
671 DECL(AL_FLANGER_RATE),
672 DECL(AL_FLANGER_DEPTH),
673 DECL(AL_FLANGER_FEEDBACK),
674 DECL(AL_FLANGER_DELAY),
676 DECL(AL_RING_MODULATOR_FREQUENCY),
677 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
678 DECL(AL_RING_MODULATOR_WAVEFORM),
680 DECL(AL_COMPRESSOR_ONOFF),
682 DECL(AL_EQUALIZER_LOW_GAIN),
683 DECL(AL_EQUALIZER_LOW_CUTOFF),
684 DECL(AL_EQUALIZER_MID1_GAIN),
685 DECL(AL_EQUALIZER_MID1_CENTER),
686 DECL(AL_EQUALIZER_MID1_WIDTH),
687 DECL(AL_EQUALIZER_MID2_GAIN),
688 DECL(AL_EQUALIZER_MID2_CENTER),
689 DECL(AL_EQUALIZER_MID2_WIDTH),
690 DECL(AL_EQUALIZER_HIGH_GAIN),
691 DECL(AL_EQUALIZER_HIGH_CUTOFF),
693 DECL(AL_DEDICATED_GAIN),
695 DECL(AL_NUM_RESAMPLERS_SOFT),
696 DECL(AL_DEFAULT_RESAMPLER_SOFT),
697 DECL(AL_SOURCE_RESAMPLER_SOFT),
698 DECL(AL_RESAMPLER_NAME_SOFT),
700 DECL(AL_SOURCE_SPATIALIZE_SOFT),
701 DECL(AL_AUTO_SOFT),
703 #undef DECL
705 static const ALCchar alcNoError[] = "No Error";
706 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
707 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
708 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
709 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
710 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
713 /************************************************
714 * Global variables
715 ************************************************/
717 /* Enumerated device names */
718 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
720 static al_string alcAllDevicesList;
721 static al_string alcCaptureDeviceList;
723 /* Default is always the first in the list */
724 static ALCchar *alcDefaultAllDevicesSpecifier;
725 static ALCchar *alcCaptureDefaultDeviceSpecifier;
727 /* Default context extensions */
728 static const ALchar alExtList[] =
729 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
730 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
731 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
732 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
733 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
734 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
735 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length "
736 "AL_SOFT_source_resampler AL_SOFT_source_spatialize";
738 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
740 /* Thread-local current context */
741 static altss_t LocalContext;
742 /* Process-wide current context */
743 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
745 /* Mixing thread piority level */
746 ALint RTPrioLevel;
748 FILE *LogFile;
749 #ifdef _DEBUG
750 enum LogLevel LogLevel = LogWarning;
751 #else
752 enum LogLevel LogLevel = LogError;
753 #endif
755 /* Flag to trap ALC device errors */
756 static ALCboolean TrapALCError = ALC_FALSE;
758 /* One-time configuration init control */
759 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
761 /* Default effect that applies to sources that don't have an effect on send 0 */
762 static ALeffect DefaultEffect;
764 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
765 * updates.
767 static ALCboolean SuspendDefers = ALC_TRUE;
770 /************************************************
771 * ALC information
772 ************************************************/
773 static const ALCchar alcNoDeviceExtList[] =
774 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
775 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
776 static const ALCchar alcExtensionList[] =
777 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
778 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
779 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
780 "ALC_SOFT_loopback ALC_SOFT_output_limiter ALC_SOFT_pause_device";
781 static const ALCint alcMajorVersion = 1;
782 static const ALCint alcMinorVersion = 1;
784 static const ALCint alcEFXMajorVersion = 1;
785 static const ALCint alcEFXMinorVersion = 0;
788 /************************************************
789 * Device lists
790 ************************************************/
791 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
793 static almtx_t ListLock;
794 static inline void LockLists(void)
796 int ret = almtx_lock(&ListLock);
797 assert(ret == althrd_success);
799 static inline void UnlockLists(void)
801 int ret = almtx_unlock(&ListLock);
802 assert(ret == althrd_success);
805 /************************************************
806 * Library initialization
807 ************************************************/
808 #if defined(_WIN32)
809 static void alc_init(void);
810 static void alc_deinit(void);
811 static void alc_deinit_safe(void);
813 #ifndef AL_LIBTYPE_STATIC
814 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
816 switch(reason)
818 case DLL_PROCESS_ATTACH:
819 /* Pin the DLL so we won't get unloaded until the process terminates */
820 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
821 (WCHAR*)hModule, &hModule);
822 alc_init();
823 break;
825 case DLL_THREAD_DETACH:
826 break;
828 case DLL_PROCESS_DETACH:
829 if(!lpReserved)
830 alc_deinit();
831 else
832 alc_deinit_safe();
833 break;
835 return TRUE;
837 #elif defined(_MSC_VER)
838 #pragma section(".CRT$XCU",read)
839 static void alc_constructor(void);
840 static void alc_destructor(void);
841 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
843 static void alc_constructor(void)
845 atexit(alc_destructor);
846 alc_init();
849 static void alc_destructor(void)
851 alc_deinit();
853 #elif defined(HAVE_GCC_DESTRUCTOR)
854 static void alc_init(void) __attribute__((constructor));
855 static void alc_deinit(void) __attribute__((destructor));
856 #else
857 #error "No static initialization available on this platform!"
858 #endif
860 #elif defined(HAVE_GCC_DESTRUCTOR)
862 static void alc_init(void) __attribute__((constructor));
863 static void alc_deinit(void) __attribute__((destructor));
865 #else
866 #error "No global initialization available on this platform!"
867 #endif
869 static void ReleaseThreadCtx(void *ptr);
870 static void alc_init(void)
872 const char *str;
873 int ret;
875 LogFile = stderr;
877 AL_STRING_INIT(alcAllDevicesList);
878 AL_STRING_INIT(alcCaptureDeviceList);
880 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
881 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
882 ConeScale *= 0.5f;
884 str = getenv("__ALSOFT_REVERSE_Z");
885 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
886 ZScale *= -1.0f;
888 ret = altss_create(&LocalContext, ReleaseThreadCtx);
889 assert(ret == althrd_success);
891 ret = almtx_init(&ListLock, almtx_recursive);
892 assert(ret == althrd_success);
894 ThunkInit();
897 static void alc_initconfig(void)
899 const char *devs, *str;
900 ALuint capfilter;
901 float valf;
902 int i, n;
904 str = getenv("ALSOFT_LOGLEVEL");
905 if(str)
907 long lvl = strtol(str, NULL, 0);
908 if(lvl >= NoLog && lvl <= LogRef)
909 LogLevel = lvl;
912 str = getenv("ALSOFT_LOGFILE");
913 if(str && str[0])
915 FILE *logfile = al_fopen(str, "wt");
916 if(logfile) LogFile = logfile;
917 else ERR("Failed to open log file '%s'\n", str);
920 TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION,
921 ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
923 char buf[1024] = "";
924 int len = 0;
926 if(BackendListSize > 0)
927 len += snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
928 for(i = 1;i < BackendListSize;i++)
929 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
930 TRACE("Supported backends: %s\n", buf);
932 ReadALConfig();
934 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
935 if(str && *str)
937 if(strcasecmp(str, "ignore") == 0)
939 SuspendDefers = ALC_FALSE;
940 TRACE("Selected context suspend behavior, \"ignore\"\n");
942 else
943 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
946 capfilter = 0;
947 #if defined(HAVE_SSE4_1)
948 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
949 #elif defined(HAVE_SSE3)
950 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
951 #elif defined(HAVE_SSE2)
952 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
953 #elif defined(HAVE_SSE)
954 capfilter |= CPU_CAP_SSE;
955 #endif
956 #ifdef HAVE_NEON
957 capfilter |= CPU_CAP_NEON;
958 #endif
959 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
961 if(strcasecmp(str, "all") == 0)
962 capfilter = 0;
963 else
965 size_t len;
966 const char *next = str;
968 do {
969 str = next;
970 while(isspace(str[0]))
971 str++;
972 next = strchr(str, ',');
974 if(!str[0] || str[0] == ',')
975 continue;
977 len = (next ? ((size_t)(next-str)) : strlen(str));
978 while(len > 0 && isspace(str[len-1]))
979 len--;
980 if(len == 3 && strncasecmp(str, "sse", len) == 0)
981 capfilter &= ~CPU_CAP_SSE;
982 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
983 capfilter &= ~CPU_CAP_SSE2;
984 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
985 capfilter &= ~CPU_CAP_SSE3;
986 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
987 capfilter &= ~CPU_CAP_SSE4_1;
988 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
989 capfilter &= ~CPU_CAP_NEON;
990 else
991 WARN("Invalid CPU extension \"%s\"\n", str);
992 } while(next++);
995 FillCPUCaps(capfilter);
997 #ifdef _WIN32
998 RTPrioLevel = 1;
999 #else
1000 RTPrioLevel = 0;
1001 #endif
1002 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
1004 aluInitMixer();
1006 str = getenv("ALSOFT_TRAP_ERROR");
1007 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1009 TrapALError = AL_TRUE;
1010 TrapALCError = AL_TRUE;
1012 else
1014 str = getenv("ALSOFT_TRAP_AL_ERROR");
1015 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1016 TrapALError = AL_TRUE;
1017 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1019 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1020 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1021 TrapALCError = ALC_TRUE;
1022 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1025 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1026 ReverbBoost *= powf(10.0f, valf / 20.0f);
1028 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1030 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1031 ConfigValueStr(NULL, NULL, "drivers", &devs))
1033 int n;
1034 size_t len;
1035 const char *next = devs;
1036 int endlist, delitem;
1038 i = 0;
1039 do {
1040 devs = next;
1041 while(isspace(devs[0]))
1042 devs++;
1043 next = strchr(devs, ',');
1045 delitem = (devs[0] == '-');
1046 if(devs[0] == '-') devs++;
1048 if(!devs[0] || devs[0] == ',')
1050 endlist = 0;
1051 continue;
1053 endlist = 1;
1055 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1056 while(len > 0 && isspace(devs[len-1]))
1057 len--;
1058 for(n = i;n < BackendListSize;n++)
1060 if(len == strlen(BackendList[n].name) &&
1061 strncmp(BackendList[n].name, devs, len) == 0)
1063 if(delitem)
1065 for(;n+1 < BackendListSize;n++)
1066 BackendList[n] = BackendList[n+1];
1067 BackendListSize--;
1069 else
1071 struct BackendInfo Bkp = BackendList[n];
1072 for(;n > i;n--)
1073 BackendList[n] = BackendList[n-1];
1074 BackendList[n] = Bkp;
1076 i++;
1078 break;
1081 } while(next++);
1083 if(endlist)
1084 BackendListSize = i;
1087 for(i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1089 ALCbackendFactory *factory = BackendList[i].getFactory();
1090 if(!V0(factory,init)())
1092 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1093 continue;
1096 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1097 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1099 PlaybackBackend = BackendList[i];
1100 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1102 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1104 CaptureBackend = BackendList[i];
1105 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1109 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1110 V0(factory,init)();
1113 if(!PlaybackBackend.name)
1114 WARN("No playback backend available!\n");
1115 if(!CaptureBackend.name)
1116 WARN("No capture backend available!\n");
1118 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1120 size_t len;
1121 const char *next = str;
1123 do {
1124 str = next;
1125 next = strchr(str, ',');
1127 if(!str[0] || next == str)
1128 continue;
1130 len = (next ? ((size_t)(next-str)) : strlen(str));
1131 for(n = 0;EffectList[n].name;n++)
1133 if(len == strlen(EffectList[n].name) &&
1134 strncmp(EffectList[n].name, str, len) == 0)
1135 DisabledEffects[EffectList[n].type] = AL_TRUE;
1137 } while(next++);
1140 InitEffectFactoryMap();
1142 InitEffect(&DefaultEffect);
1143 str = getenv("ALSOFT_DEFAULT_REVERB");
1144 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1145 LoadReverbPreset(str, &DefaultEffect);
1147 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1149 #ifdef __ANDROID__
1150 #include <jni.h>
1152 static JavaVM *gJavaVM;
1153 static pthread_key_t gJVMThreadKey;
1155 static void CleanupJNIEnv(void* UNUSED(ptr))
1157 JCALL0(gJavaVM,DetachCurrentThread)();
1160 void *Android_GetJNIEnv(void)
1162 if(!gJavaVM)
1164 WARN("gJavaVM is NULL!\n");
1165 return NULL;
1168 /* http://developer.android.com/guide/practices/jni.html
1170 * All threads are Linux threads, scheduled by the kernel. They're usually
1171 * started from managed code (using Thread.start), but they can also be
1172 * created elsewhere and then attached to the JavaVM. For example, a thread
1173 * started with pthread_create can be attached with the JNI
1174 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1175 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1176 * Attaching a natively-created thread causes a java.lang.Thread object to
1177 * be constructed and added to the "main" ThreadGroup, making it visible to
1178 * the debugger. Calling AttachCurrentThread on an already-attached thread
1179 * is a no-op.
1181 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1182 if(!env)
1184 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1185 if(status < 0)
1187 ERR("Failed to attach current thread\n");
1188 return NULL;
1190 pthread_setspecific(gJVMThreadKey, env);
1192 return env;
1195 /* Automatically called by JNI. */
1196 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1198 void *env;
1199 int err;
1201 gJavaVM = jvm;
1202 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1204 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1205 return JNI_ERR;
1208 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1209 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1211 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1212 ERR("pthread_key_create failed: %d\n", err);
1213 pthread_setspecific(gJVMThreadKey, env);
1214 return JNI_VERSION_1_4;
1216 #endif
1219 /************************************************
1220 * Library deinitialization
1221 ************************************************/
1222 static void alc_cleanup(void)
1224 ALCdevice *dev;
1226 AL_STRING_DEINIT(alcAllDevicesList);
1227 AL_STRING_DEINIT(alcCaptureDeviceList);
1229 free(alcDefaultAllDevicesSpecifier);
1230 alcDefaultAllDevicesSpecifier = NULL;
1231 free(alcCaptureDefaultDeviceSpecifier);
1232 alcCaptureDefaultDeviceSpecifier = NULL;
1234 if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL)
1236 ALCuint num = 0;
1237 do {
1238 num++;
1239 } while((dev=dev->next) != NULL);
1240 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1243 DeinitEffectFactoryMap();
1246 static void alc_deinit_safe(void)
1248 alc_cleanup();
1250 FreeHrtfs();
1251 FreeALConfig();
1253 ThunkExit();
1254 almtx_destroy(&ListLock);
1255 altss_delete(LocalContext);
1257 if(LogFile != stderr)
1258 fclose(LogFile);
1259 LogFile = NULL;
1262 static void alc_deinit(void)
1264 int i;
1266 alc_cleanup();
1268 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1269 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1271 for(i = 0;i < BackendListSize;i++)
1273 ALCbackendFactory *factory = BackendList[i].getFactory();
1274 V0(factory,deinit)();
1277 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1278 V0(factory,deinit)();
1281 alc_deinit_safe();
1285 /************************************************
1286 * Device enumeration
1287 ************************************************/
1288 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1290 ALCbackendFactory *factory;
1292 DO_INITCONFIG();
1294 LockLists();
1295 alstr_clear(list);
1297 factory = backendinfo->getFactory();
1298 V(factory,probe)(type);
1300 UnlockLists();
1302 static void ProbeAllDevicesList(void)
1303 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1304 static void ProbeCaptureDeviceList(void)
1305 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1307 static void AppendDevice(const ALCchar *name, al_string *devnames)
1309 size_t len = strlen(name);
1310 if(len > 0)
1311 alstr_append_range(devnames, name, name+len+1);
1313 void AppendAllDevicesList(const ALCchar *name)
1314 { AppendDevice(name, &alcAllDevicesList); }
1315 void AppendCaptureDeviceList(const ALCchar *name)
1316 { AppendDevice(name, &alcCaptureDeviceList); }
1319 /************************************************
1320 * Device format information
1321 ************************************************/
1322 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1324 switch(type)
1326 case DevFmtByte: return "Signed Byte";
1327 case DevFmtUByte: return "Unsigned Byte";
1328 case DevFmtShort: return "Signed Short";
1329 case DevFmtUShort: return "Unsigned Short";
1330 case DevFmtInt: return "Signed Int";
1331 case DevFmtUInt: return "Unsigned Int";
1332 case DevFmtFloat: return "Float";
1334 return "(unknown type)";
1336 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1338 switch(chans)
1340 case DevFmtMono: return "Mono";
1341 case DevFmtStereo: return "Stereo";
1342 case DevFmtQuad: return "Quadraphonic";
1343 case DevFmtX51: return "5.1 Surround";
1344 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1345 case DevFmtX61: return "6.1 Surround";
1346 case DevFmtX71: return "7.1 Surround";
1347 case DevFmtAmbi3D: return "Ambisonic 3D";
1349 return "(unknown channels)";
1352 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder);
1353 ALsizei BytesFromDevFmt(enum DevFmtType type)
1355 switch(type)
1357 case DevFmtByte: return sizeof(ALbyte);
1358 case DevFmtUByte: return sizeof(ALubyte);
1359 case DevFmtShort: return sizeof(ALshort);
1360 case DevFmtUShort: return sizeof(ALushort);
1361 case DevFmtInt: return sizeof(ALint);
1362 case DevFmtUInt: return sizeof(ALuint);
1363 case DevFmtFloat: return sizeof(ALfloat);
1365 return 0;
1367 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder)
1369 switch(chans)
1371 case DevFmtMono: return 1;
1372 case DevFmtStereo: return 2;
1373 case DevFmtQuad: return 4;
1374 case DevFmtX51: return 6;
1375 case DevFmtX51Rear: return 6;
1376 case DevFmtX61: return 7;
1377 case DevFmtX71: return 8;
1378 case DevFmtAmbi3D: return (ambiorder >= 3) ? 16 :
1379 (ambiorder == 2) ? 9 :
1380 (ambiorder == 1) ? 4 : 1;
1382 return 0;
1385 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1386 enum DevFmtType *type)
1388 static const struct {
1389 ALenum format;
1390 enum DevFmtChannels channels;
1391 enum DevFmtType type;
1392 } list[] = {
1393 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1394 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1395 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1397 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1398 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1399 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1401 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1402 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1403 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1405 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1406 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1407 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1409 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1410 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1411 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1413 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1414 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1415 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1417 ALuint i;
1419 for(i = 0;i < COUNTOF(list);i++)
1421 if(list[i].format == format)
1423 *chans = list[i].channels;
1424 *type = list[i].type;
1425 return AL_TRUE;
1429 return AL_FALSE;
1432 static ALCboolean IsValidALCType(ALCenum type)
1434 switch(type)
1436 case ALC_BYTE_SOFT:
1437 case ALC_UNSIGNED_BYTE_SOFT:
1438 case ALC_SHORT_SOFT:
1439 case ALC_UNSIGNED_SHORT_SOFT:
1440 case ALC_INT_SOFT:
1441 case ALC_UNSIGNED_INT_SOFT:
1442 case ALC_FLOAT_SOFT:
1443 return ALC_TRUE;
1445 return ALC_FALSE;
1448 static ALCboolean IsValidALCChannels(ALCenum channels)
1450 switch(channels)
1452 case ALC_MONO_SOFT:
1453 case ALC_STEREO_SOFT:
1454 case ALC_QUAD_SOFT:
1455 case ALC_5POINT1_SOFT:
1456 case ALC_6POINT1_SOFT:
1457 case ALC_7POINT1_SOFT:
1458 case ALC_BFORMAT3D_SOFT:
1459 return ALC_TRUE;
1461 return ALC_FALSE;
1464 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1466 switch(layout)
1468 case ALC_ACN_SOFT:
1469 case ALC_FUMA_SOFT:
1470 return ALC_TRUE;
1472 return ALC_FALSE;
1475 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1477 switch(scaling)
1479 case ALC_N3D_SOFT:
1480 case ALC_SN3D_SOFT:
1481 case ALC_FUMA_SOFT:
1482 return ALC_TRUE;
1484 return ALC_FALSE;
1487 /************************************************
1488 * Miscellaneous ALC helpers
1489 ************************************************/
1491 void ALCdevice_Lock(ALCdevice *device)
1493 V0(device->Backend,lock)();
1496 void ALCdevice_Unlock(ALCdevice *device)
1498 V0(device->Backend,unlock)();
1502 /* SetDefaultWFXChannelOrder
1504 * Sets the default channel order used by WaveFormatEx.
1506 void SetDefaultWFXChannelOrder(ALCdevice *device)
1508 ALsizei i;
1510 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1511 device->RealOut.ChannelName[i] = InvalidChannel;
1513 switch(device->FmtChans)
1515 case DevFmtMono:
1516 device->RealOut.ChannelName[0] = FrontCenter;
1517 break;
1518 case DevFmtStereo:
1519 device->RealOut.ChannelName[0] = FrontLeft;
1520 device->RealOut.ChannelName[1] = FrontRight;
1521 break;
1522 case DevFmtQuad:
1523 device->RealOut.ChannelName[0] = FrontLeft;
1524 device->RealOut.ChannelName[1] = FrontRight;
1525 device->RealOut.ChannelName[2] = BackLeft;
1526 device->RealOut.ChannelName[3] = BackRight;
1527 break;
1528 case DevFmtX51:
1529 device->RealOut.ChannelName[0] = FrontLeft;
1530 device->RealOut.ChannelName[1] = FrontRight;
1531 device->RealOut.ChannelName[2] = FrontCenter;
1532 device->RealOut.ChannelName[3] = LFE;
1533 device->RealOut.ChannelName[4] = SideLeft;
1534 device->RealOut.ChannelName[5] = SideRight;
1535 break;
1536 case DevFmtX51Rear:
1537 device->RealOut.ChannelName[0] = FrontLeft;
1538 device->RealOut.ChannelName[1] = FrontRight;
1539 device->RealOut.ChannelName[2] = FrontCenter;
1540 device->RealOut.ChannelName[3] = LFE;
1541 device->RealOut.ChannelName[4] = BackLeft;
1542 device->RealOut.ChannelName[5] = BackRight;
1543 break;
1544 case DevFmtX61:
1545 device->RealOut.ChannelName[0] = FrontLeft;
1546 device->RealOut.ChannelName[1] = FrontRight;
1547 device->RealOut.ChannelName[2] = FrontCenter;
1548 device->RealOut.ChannelName[3] = LFE;
1549 device->RealOut.ChannelName[4] = BackCenter;
1550 device->RealOut.ChannelName[5] = SideLeft;
1551 device->RealOut.ChannelName[6] = SideRight;
1552 break;
1553 case DevFmtX71:
1554 device->RealOut.ChannelName[0] = FrontLeft;
1555 device->RealOut.ChannelName[1] = FrontRight;
1556 device->RealOut.ChannelName[2] = FrontCenter;
1557 device->RealOut.ChannelName[3] = LFE;
1558 device->RealOut.ChannelName[4] = BackLeft;
1559 device->RealOut.ChannelName[5] = BackRight;
1560 device->RealOut.ChannelName[6] = SideLeft;
1561 device->RealOut.ChannelName[7] = SideRight;
1562 break;
1563 case DevFmtAmbi3D:
1564 device->RealOut.ChannelName[0] = Aux0;
1565 if(device->AmbiOrder > 0)
1567 device->RealOut.ChannelName[1] = Aux1;
1568 device->RealOut.ChannelName[2] = Aux2;
1569 device->RealOut.ChannelName[3] = Aux3;
1571 if(device->AmbiOrder > 1)
1573 device->RealOut.ChannelName[4] = Aux4;
1574 device->RealOut.ChannelName[5] = Aux5;
1575 device->RealOut.ChannelName[6] = Aux6;
1576 device->RealOut.ChannelName[7] = Aux7;
1577 device->RealOut.ChannelName[8] = Aux8;
1579 if(device->AmbiOrder > 2)
1581 device->RealOut.ChannelName[9] = Aux9;
1582 device->RealOut.ChannelName[10] = Aux10;
1583 device->RealOut.ChannelName[11] = Aux11;
1584 device->RealOut.ChannelName[12] = Aux12;
1585 device->RealOut.ChannelName[13] = Aux13;
1586 device->RealOut.ChannelName[14] = Aux14;
1587 device->RealOut.ChannelName[15] = Aux15;
1589 break;
1593 /* SetDefaultChannelOrder
1595 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1597 void SetDefaultChannelOrder(ALCdevice *device)
1599 ALsizei i;
1601 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1602 device->RealOut.ChannelName[i] = InvalidChannel;
1604 switch(device->FmtChans)
1606 case DevFmtX51Rear:
1607 device->RealOut.ChannelName[0] = FrontLeft;
1608 device->RealOut.ChannelName[1] = FrontRight;
1609 device->RealOut.ChannelName[2] = BackLeft;
1610 device->RealOut.ChannelName[3] = BackRight;
1611 device->RealOut.ChannelName[4] = FrontCenter;
1612 device->RealOut.ChannelName[5] = LFE;
1613 return;
1614 case DevFmtX71:
1615 device->RealOut.ChannelName[0] = FrontLeft;
1616 device->RealOut.ChannelName[1] = FrontRight;
1617 device->RealOut.ChannelName[2] = BackLeft;
1618 device->RealOut.ChannelName[3] = BackRight;
1619 device->RealOut.ChannelName[4] = FrontCenter;
1620 device->RealOut.ChannelName[5] = LFE;
1621 device->RealOut.ChannelName[6] = SideLeft;
1622 device->RealOut.ChannelName[7] = SideRight;
1623 return;
1625 /* Same as WFX order */
1626 case DevFmtMono:
1627 case DevFmtStereo:
1628 case DevFmtQuad:
1629 case DevFmtX51:
1630 case DevFmtX61:
1631 case DevFmtAmbi3D:
1632 SetDefaultWFXChannelOrder(device);
1633 break;
1637 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1640 /* ALCcontext_DeferUpdates
1642 * Defers/suspends updates for the given context's listener and sources. This
1643 * does *NOT* stop mixing, but rather prevents certain property changes from
1644 * taking effect.
1646 void ALCcontext_DeferUpdates(ALCcontext *context)
1648 ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE);
1651 /* ALCcontext_ProcessUpdates
1653 * Resumes update processing after being deferred.
1655 void ALCcontext_ProcessUpdates(ALCcontext *context)
1657 ReadLock(&context->PropLock);
1658 if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
1660 /* Tell the mixer to stop applying updates, then wait for any active
1661 * updating to finish, before providing updates.
1663 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1664 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1665 althrd_yield();
1667 UpdateListenerProps(context);
1668 UpdateAllEffectSlotProps(context);
1669 UpdateAllSourceProps(context);
1671 /* Now with all updates declared, let the mixer continue applying them
1672 * so they all happen at once.
1674 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1676 ReadUnlock(&context->PropLock);
1680 /* alcSetError
1682 * Stores the latest ALC device error
1684 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1686 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1687 if(TrapALCError)
1689 #ifdef _WIN32
1690 /* DebugBreak() will cause an exception if there is no debugger */
1691 if(IsDebuggerPresent())
1692 DebugBreak();
1693 #elif defined(SIGTRAP)
1694 raise(SIGTRAP);
1695 #endif
1698 if(device)
1699 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1700 else
1701 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1705 struct Compressor *CreateDeviceLimiter(const ALCdevice *device)
1707 return CompressorInit(0.0f, 0.0f, AL_FALSE, AL_TRUE, 0.0f, 0.0f, 0.5f, 2.0f,
1708 0.0f, -3.0f, 3.0f, device->Frequency);
1711 /* UpdateClockBase
1713 * Updates the device's base clock time with however many samples have been
1714 * done. This is used so frequency changes on the device don't cause the time
1715 * to jump forward or back. Must not be called while the device is running/
1716 * mixing.
1718 static inline void UpdateClockBase(ALCdevice *device)
1720 IncrementRef(&device->MixCount);
1721 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1722 device->SamplesDone = 0;
1723 IncrementRef(&device->MixCount);
1726 /* UpdateDeviceParams
1728 * Updates device parameters according to the attribute list (caller is
1729 * responsible for holding the list lock).
1731 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1733 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1734 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1735 ALCenum gainLimiter = device->Limiter ? ALC_TRUE : ALC_FALSE;
1736 const ALsizei old_sends = device->NumAuxSends;
1737 ALsizei new_sends = device->NumAuxSends;
1738 enum DevFmtChannels oldChans;
1739 enum DevFmtType oldType;
1740 ALboolean update_failed;
1741 ALCsizei hrtf_id = -1;
1742 ALCcontext *context;
1743 ALCuint oldFreq;
1744 size_t size;
1745 ALCsizei i;
1746 int val;
1748 // Check for attributes
1749 if(device->Type == Loopback)
1751 ALCsizei numMono, numStereo, numSends;
1752 ALCenum alayout = AL_NONE;
1753 ALCenum ascale = AL_NONE;
1754 ALCenum schans = AL_NONE;
1755 ALCenum stype = AL_NONE;
1756 ALCsizei attrIdx = 0;
1757 ALCsizei aorder = 0;
1758 ALCuint freq = 0;
1760 if(!attrList)
1762 WARN("Missing attributes for loopback device\n");
1763 return ALC_INVALID_VALUE;
1766 numMono = device->NumMonoSources;
1767 numStereo = device->NumStereoSources;
1768 numSends = old_sends;
1770 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1771 while(attrList[attrIdx])
1773 switch(attrList[attrIdx])
1775 case ALC_FORMAT_CHANNELS_SOFT:
1776 schans = attrList[attrIdx + 1];
1777 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1778 if(!IsValidALCChannels(schans))
1779 return ALC_INVALID_VALUE;
1780 break;
1782 case ALC_FORMAT_TYPE_SOFT:
1783 stype = attrList[attrIdx + 1];
1784 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1785 if(!IsValidALCType(stype))
1786 return ALC_INVALID_VALUE;
1787 break;
1789 case ALC_FREQUENCY:
1790 freq = attrList[attrIdx + 1];
1791 TRACE_ATTR(ALC_FREQUENCY, freq);
1792 if(freq < MIN_OUTPUT_RATE)
1793 return ALC_INVALID_VALUE;
1794 break;
1796 case ALC_AMBISONIC_LAYOUT_SOFT:
1797 alayout = attrList[attrIdx + 1];
1798 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1799 if(!IsValidAmbiLayout(alayout))
1800 return ALC_INVALID_VALUE;
1801 break;
1803 case ALC_AMBISONIC_SCALING_SOFT:
1804 ascale = attrList[attrIdx + 1];
1805 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1806 if(!IsValidAmbiScaling(ascale))
1807 return ALC_INVALID_VALUE;
1808 break;
1810 case ALC_AMBISONIC_ORDER_SOFT:
1811 aorder = attrList[attrIdx + 1];
1812 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1813 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1814 return ALC_INVALID_VALUE;
1815 break;
1817 case ALC_MONO_SOURCES:
1818 numMono = attrList[attrIdx + 1];
1819 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1820 numMono = maxi(numMono, 0);
1821 break;
1823 case ALC_STEREO_SOURCES:
1824 numStereo = attrList[attrIdx + 1];
1825 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1826 numStereo = maxi(numStereo, 0);
1827 break;
1829 case ALC_MAX_AUXILIARY_SENDS:
1830 numSends = attrList[attrIdx + 1];
1831 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1832 numSends = clampi(numSends, 0, MAX_SENDS);
1833 break;
1835 case ALC_HRTF_SOFT:
1836 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1837 if(attrList[attrIdx + 1] == ALC_FALSE)
1838 hrtf_appreq = Hrtf_Disable;
1839 else if(attrList[attrIdx + 1] == ALC_TRUE)
1840 hrtf_appreq = Hrtf_Enable;
1841 else
1842 hrtf_appreq = Hrtf_Default;
1843 break;
1845 case ALC_HRTF_ID_SOFT:
1846 hrtf_id = attrList[attrIdx + 1];
1847 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1848 break;
1850 case ALC_OUTPUT_LIMITER_SOFT:
1851 gainLimiter = attrList[attrIdx + 1];
1852 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1853 break;
1855 default:
1856 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList[attrIdx],
1857 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1858 break;
1861 attrIdx += 2;
1863 #undef TRACE_ATTR
1865 if(!schans || !stype || !freq)
1867 WARN("Missing format for loopback device\n");
1868 return ALC_INVALID_VALUE;
1870 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1872 WARN("Missing ambisonic info for loopback device\n");
1873 return ALC_INVALID_VALUE;
1876 if((device->Flags&DEVICE_RUNNING))
1877 V0(device->Backend,stop)();
1878 device->Flags &= ~DEVICE_RUNNING;
1880 UpdateClockBase(device);
1882 device->Frequency = freq;
1883 device->FmtChans = schans;
1884 device->FmtType = stype;
1885 if(schans == ALC_BFORMAT3D_SOFT)
1887 device->AmbiOrder = aorder;
1888 device->AmbiLayout = alayout;
1889 device->AmbiScale = ascale;
1892 if(numMono > INT_MAX-numStereo)
1893 numMono = INT_MAX-numStereo;
1894 numMono += numStereo;
1895 if(ConfigValueInt(NULL, NULL, "sources", &numMono))
1897 if(numMono <= 0)
1898 numMono = 256;
1900 else
1901 numMono = maxi(numMono, 256);
1902 numStereo = mini(numStereo, numMono);
1903 numMono -= numStereo;
1904 device->SourcesMax = numMono + numStereo;
1906 device->NumMonoSources = numMono;
1907 device->NumStereoSources = numStereo;
1909 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1910 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1911 else
1912 new_sends = numSends;
1914 else if(attrList && attrList[0])
1916 ALCsizei numMono, numStereo, numSends;
1917 ALCsizei attrIdx = 0;
1918 ALCuint freq;
1920 /* If a context is already running on the device, stop playback so the
1921 * device attributes can be updated. */
1922 if((device->Flags&DEVICE_RUNNING))
1923 V0(device->Backend,stop)();
1924 device->Flags &= ~DEVICE_RUNNING;
1926 UpdateClockBase(device);
1928 freq = device->Frequency;
1929 numMono = device->NumMonoSources;
1930 numStereo = device->NumStereoSources;
1931 numSends = old_sends;
1933 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1934 while(attrList[attrIdx])
1936 switch(attrList[attrIdx])
1938 case ALC_FREQUENCY:
1939 freq = attrList[attrIdx + 1];
1940 TRACE_ATTR(ALC_FREQUENCY, freq);
1941 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1942 break;
1944 case ALC_MONO_SOURCES:
1945 numMono = attrList[attrIdx + 1];
1946 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1947 numMono = maxi(numMono, 0);
1948 break;
1950 case ALC_STEREO_SOURCES:
1951 numStereo = attrList[attrIdx + 1];
1952 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1953 numStereo = maxi(numStereo, 0);
1954 break;
1956 case ALC_MAX_AUXILIARY_SENDS:
1957 numSends = attrList[attrIdx + 1];
1958 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1959 numSends = clampi(numSends, 0, MAX_SENDS);
1960 break;
1962 case ALC_HRTF_SOFT:
1963 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1964 if(attrList[attrIdx + 1] == ALC_FALSE)
1965 hrtf_appreq = Hrtf_Disable;
1966 else if(attrList[attrIdx + 1] == ALC_TRUE)
1967 hrtf_appreq = Hrtf_Enable;
1968 else
1969 hrtf_appreq = Hrtf_Default;
1970 break;
1972 case ALC_HRTF_ID_SOFT:
1973 hrtf_id = attrList[attrIdx + 1];
1974 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1975 break;
1977 case ALC_OUTPUT_LIMITER_SOFT:
1978 gainLimiter = attrList[attrIdx + 1];
1979 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1980 break;
1982 default:
1983 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
1984 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1985 break;
1988 attrIdx += 2;
1990 #undef TRACE_ATTR
1992 ConfigValueUInt(alstr_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1993 freq = maxu(freq, MIN_OUTPUT_RATE);
1995 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1996 device->Frequency;
1997 /* SSE and Neon do best with the update size being a multiple of 4 */
1998 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1999 device->UpdateSize = (device->UpdateSize+3)&~3;
2001 device->Frequency = freq;
2003 if(numMono > INT_MAX-numStereo)
2004 numMono = INT_MAX-numStereo;
2005 numMono += numStereo;
2006 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono))
2008 if(numMono <= 0)
2009 numMono = 256;
2011 else
2012 numMono = maxi(numMono, 256);
2013 numStereo = mini(numStereo, numMono);
2014 numMono -= numStereo;
2015 device->SourcesMax = numMono + numStereo;
2017 device->NumMonoSources = numMono;
2018 device->NumStereoSources = numStereo;
2020 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2021 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2022 else
2023 new_sends = numSends;
2026 if((device->Flags&DEVICE_RUNNING))
2027 return ALC_NO_ERROR;
2029 al_free(device->Uhj_Encoder);
2030 device->Uhj_Encoder = NULL;
2032 al_free(device->Bs2b);
2033 device->Bs2b = NULL;
2035 al_free(device->ChannelDelay[0].Buffer);
2036 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2038 device->ChannelDelay[i].Length = 0;
2039 device->ChannelDelay[i].Buffer = NULL;
2042 al_free(device->Dry.Buffer);
2043 device->Dry.Buffer = NULL;
2044 device->Dry.NumChannels = 0;
2045 device->FOAOut.Buffer = NULL;
2046 device->FOAOut.NumChannels = 0;
2047 device->RealOut.Buffer = NULL;
2048 device->RealOut.NumChannels = 0;
2050 UpdateClockBase(device);
2052 device->DitherSeed = DITHER_RNG_SEED;
2054 /*************************************************************************
2055 * Update device format request if HRTF is requested
2057 device->HrtfStatus = ALC_HRTF_DISABLED_SOFT;
2058 if(device->Type != Loopback)
2060 const char *hrtf;
2061 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2063 if(strcasecmp(hrtf, "true") == 0)
2064 hrtf_userreq = Hrtf_Enable;
2065 else if(strcasecmp(hrtf, "false") == 0)
2066 hrtf_userreq = Hrtf_Disable;
2067 else if(strcasecmp(hrtf, "auto") != 0)
2068 ERR("Unexpected hrtf value: %s\n", hrtf);
2071 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2073 struct Hrtf *hrtf = NULL;
2074 if(VECTOR_SIZE(device->HrtfList) == 0)
2076 VECTOR_DEINIT(device->HrtfList);
2077 device->HrtfList = EnumerateHrtf(device->DeviceName);
2079 if(VECTOR_SIZE(device->HrtfList) > 0)
2081 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
2082 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
2083 else
2084 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
2087 if(hrtf)
2089 device->FmtChans = DevFmtStereo;
2090 device->Frequency = hrtf->sampleRate;
2091 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2092 if(device->HrtfHandle)
2093 Hrtf_DecRef(device->HrtfHandle);
2094 device->HrtfHandle = hrtf;
2096 else
2098 hrtf_userreq = Hrtf_Default;
2099 hrtf_appreq = Hrtf_Disable;
2100 device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2105 oldFreq = device->Frequency;
2106 oldChans = device->FmtChans;
2107 oldType = device->FmtType;
2109 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2110 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2111 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2112 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2113 device->UpdateSize, device->NumUpdates
2116 if(V0(device->Backend,reset)() == ALC_FALSE)
2117 return ALC_INVALID_DEVICE;
2119 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2121 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2122 DevFmtChannelsString(device->FmtChans));
2123 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2125 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2127 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2128 DevFmtTypeString(device->FmtType));
2129 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2131 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2133 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2134 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2137 if((device->UpdateSize&3) != 0)
2139 if((CPUCapFlags&CPU_CAP_SSE))
2140 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2141 if((CPUCapFlags&CPU_CAP_NEON))
2142 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2145 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2146 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2147 device->Frequency, device->UpdateSize, device->NumUpdates
2150 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2151 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2152 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2154 /* Allocate extra channels for any post-filter output. */
2155 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2156 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2158 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2159 device->Dry.Buffer = al_calloc(16, size);
2160 if(!device->Dry.Buffer)
2162 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2163 return ALC_INVALID_DEVICE;
2166 if(device->RealOut.NumChannels != 0)
2167 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2168 device->FOAOut.NumChannels;
2169 else
2171 device->RealOut.Buffer = device->Dry.Buffer;
2172 device->RealOut.NumChannels = device->Dry.NumChannels;
2175 if(device->FOAOut.NumChannels != 0)
2176 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2177 else
2179 device->FOAOut.Buffer = device->Dry.Buffer;
2180 device->FOAOut.NumChannels = device->Dry.NumChannels;
2183 device->NumAuxSends = new_sends;
2184 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2185 device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2186 device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2188 device->DitherDepth = 0.0f;
2189 if(GetConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "dither", 1))
2191 ALint depth = 0;
2192 ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "dither-depth", &depth);
2193 if(depth <= 0)
2195 switch(device->FmtType)
2197 case DevFmtByte:
2198 case DevFmtUByte:
2199 depth = 8;
2200 break;
2201 case DevFmtShort:
2202 case DevFmtUShort:
2203 depth = 16;
2204 break;
2205 case DevFmtInt:
2206 case DevFmtUInt:
2207 case DevFmtFloat:
2208 break;
2211 else if(depth > 24)
2212 depth = 24;
2213 device->DitherDepth = (depth > 0) ? powf(2.0f, (ALfloat)(depth-1)) : 0.0f;
2215 if(!(device->DitherDepth > 0.0f))
2216 TRACE("Dithering disabled\n");
2217 else
2218 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device->DitherDepth)+1.0f,
2219 device->DitherDepth);
2221 if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
2222 gainLimiter = val ? ALC_TRUE : ALC_FALSE;
2223 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2224 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2225 * ALC_TRUE.
2227 if(gainLimiter != ALC_FALSE)
2229 if(!device->Limiter || device->Frequency != GetCompressorSampleRate(device->Limiter))
2231 al_free(device->Limiter);
2232 device->Limiter = CreateDeviceLimiter(device);
2235 else
2237 al_free(device->Limiter);
2238 device->Limiter = NULL;
2240 TRACE("Output limiter %s\n", device->Limiter ? "enabled" : "disabled");
2242 /* Need to delay returning failure until replacement Send arrays have been
2243 * allocated with the appropriate size.
2245 update_failed = AL_FALSE;
2246 START_MIXER_MODE();
2247 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2248 while(context)
2250 ALsizei pos;
2252 if(context->DefaultSlot)
2254 ALeffectslot *slot = context->DefaultSlot;
2255 ALeffectState *state = slot->Effect.State;
2257 state->OutBuffer = device->Dry.Buffer;
2258 state->OutChannels = device->Dry.NumChannels;
2259 if(V(state,deviceUpdate)(device) == AL_FALSE)
2260 update_failed = AL_TRUE;
2261 else
2262 UpdateEffectSlotProps(slot);
2265 WriteLock(&context->PropLock);
2266 LockUIntMapRead(&context->EffectSlotMap);
2267 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2269 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2270 ALeffectState *state = slot->Effect.State;
2272 state->OutBuffer = device->Dry.Buffer;
2273 state->OutChannels = device->Dry.NumChannels;
2274 if(V(state,deviceUpdate)(device) == AL_FALSE)
2275 update_failed = AL_TRUE;
2276 else
2277 UpdateEffectSlotProps(slot);
2279 UnlockUIntMapRead(&context->EffectSlotMap);
2281 LockUIntMapRead(&context->SourceMap);
2282 RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax);
2283 for(pos = 0;pos < context->SourceMap.size;pos++)
2285 ALsource *source = context->SourceMap.values[pos];
2287 if(old_sends != device->NumAuxSends)
2289 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2290 ALsizei s;
2292 memcpy(sends, source->Send,
2293 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2295 for(s = device->NumAuxSends;s < old_sends;s++)
2297 if(source->Send[s].Slot)
2298 DecrementRef(&source->Send[s].Slot->ref);
2299 source->Send[s].Slot = NULL;
2301 al_free(source->Send);
2302 source->Send = sends;
2303 for(s = old_sends;s < device->NumAuxSends;s++)
2305 source->Send[s].Slot = NULL;
2306 source->Send[s].Gain = 1.0f;
2307 source->Send[s].GainHF = 1.0f;
2308 source->Send[s].HFReference = LOWPASSFREQREF;
2309 source->Send[s].GainLF = 1.0f;
2310 source->Send[s].LFReference = HIGHPASSFREQREF;
2314 ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
2316 AllocateVoices(context, context->MaxVoices, old_sends);
2317 for(pos = 0;pos < context->VoiceCount;pos++)
2319 ALvoice *voice = context->Voices[pos];
2320 struct ALvoiceProps *props;
2322 /* Clear any pre-existing voice property structs, in case the
2323 * number of auxiliary sends changed. Active sources will have
2324 * updates respecified in UpdateAllSourceProps.
2326 props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed);
2327 al_free(props);
2329 props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
2330 while(props)
2332 struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
2333 al_free(props);
2334 props = next;
2337 if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
2338 continue;
2340 if(device->AvgSpeakerDist > 0.0f)
2342 /* Reinitialize the NFC filters for new parameters. */
2343 ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
2344 (device->AvgSpeakerDist * device->Frequency);
2345 for(i = 0;i < voice->NumChannels;i++)
2347 NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1);
2348 NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1);
2349 NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1);
2353 UnlockUIntMapRead(&context->SourceMap);
2355 UpdateListenerProps(context);
2356 UpdateAllSourceProps(context);
2357 WriteUnlock(&context->PropLock);
2359 context = context->next;
2361 END_MIXER_MODE();
2362 if(update_failed)
2363 return ALC_INVALID_DEVICE;
2365 if(!(device->Flags&DEVICE_PAUSED))
2367 if(V0(device->Backend,start)() == ALC_FALSE)
2368 return ALC_INVALID_DEVICE;
2369 device->Flags |= DEVICE_RUNNING;
2372 return ALC_NO_ERROR;
2375 /* FreeDevice
2377 * Frees the device structure, and destroys any objects the app failed to
2378 * delete. Called once there's no more references on the device.
2380 static ALCvoid FreeDevice(ALCdevice *device)
2382 ALsizei i;
2384 TRACE("%p\n", device);
2386 V0(device->Backend,close)();
2387 DELETE_OBJ(device->Backend);
2388 device->Backend = NULL;
2390 almtx_destroy(&device->BackendLock);
2392 if(device->BufferMap.size > 0)
2394 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2395 (device->BufferMap.size==1)?"":"s");
2396 ReleaseALBuffers(device);
2398 ResetUIntMap(&device->BufferMap);
2400 if(device->EffectMap.size > 0)
2402 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2403 (device->EffectMap.size==1)?"":"s");
2404 ReleaseALEffects(device);
2406 ResetUIntMap(&device->EffectMap);
2408 if(device->FilterMap.size > 0)
2410 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2411 (device->FilterMap.size==1)?"":"s");
2412 ReleaseALFilters(device);
2414 ResetUIntMap(&device->FilterMap);
2416 AL_STRING_DEINIT(device->HrtfName);
2417 FreeHrtfList(&device->HrtfList);
2418 if(device->HrtfHandle)
2419 Hrtf_DecRef(device->HrtfHandle);
2420 device->HrtfHandle = NULL;
2421 al_free(device->Hrtf);
2422 device->Hrtf = NULL;
2424 al_free(device->Bs2b);
2425 device->Bs2b = NULL;
2427 al_free(device->Uhj_Encoder);
2428 device->Uhj_Encoder = NULL;
2430 bformatdec_free(device->AmbiDecoder);
2431 device->AmbiDecoder = NULL;
2433 ambiup_free(device->AmbiUp);
2434 device->AmbiUp = NULL;
2436 al_free(device->Limiter);
2437 device->Limiter = NULL;
2439 al_free(device->ChannelDelay[0].Buffer);
2440 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2442 device->ChannelDelay[i].Gain = 1.0f;
2443 device->ChannelDelay[i].Length = 0;
2444 device->ChannelDelay[i].Buffer = NULL;
2447 AL_STRING_DEINIT(device->DeviceName);
2449 al_free(device->Dry.Buffer);
2450 device->Dry.Buffer = NULL;
2451 device->Dry.NumChannels = 0;
2452 device->FOAOut.Buffer = NULL;
2453 device->FOAOut.NumChannels = 0;
2454 device->RealOut.Buffer = NULL;
2455 device->RealOut.NumChannels = 0;
2457 al_free(device);
2461 void ALCdevice_IncRef(ALCdevice *device)
2463 uint ref;
2464 ref = IncrementRef(&device->ref);
2465 TRACEREF("%p increasing refcount to %u\n", device, ref);
2468 void ALCdevice_DecRef(ALCdevice *device)
2470 uint ref;
2471 ref = DecrementRef(&device->ref);
2472 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2473 if(ref == 0) FreeDevice(device);
2476 /* VerifyDevice
2478 * Checks if the device handle is valid, and increments its ref count if so.
2480 static ALCboolean VerifyDevice(ALCdevice **device)
2482 ALCdevice *tmpDevice;
2484 LockLists();
2485 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2486 while(tmpDevice)
2488 if(tmpDevice == *device)
2490 ALCdevice_IncRef(tmpDevice);
2491 UnlockLists();
2492 return ALC_TRUE;
2494 tmpDevice = tmpDevice->next;
2496 UnlockLists();
2498 *device = NULL;
2499 return ALC_FALSE;
2503 /* InitContext
2505 * Initializes context fields
2507 static ALvoid InitContext(ALCcontext *Context)
2509 ALlistener *listener = Context->Listener;
2510 struct ALeffectslotArray *auxslots;
2512 //Initialise listener
2513 listener->Gain = 1.0f;
2514 listener->MetersPerUnit = 1.0f;
2515 listener->Position[0] = 0.0f;
2516 listener->Position[1] = 0.0f;
2517 listener->Position[2] = 0.0f;
2518 listener->Velocity[0] = 0.0f;
2519 listener->Velocity[1] = 0.0f;
2520 listener->Velocity[2] = 0.0f;
2521 listener->Forward[0] = 0.0f;
2522 listener->Forward[1] = 0.0f;
2523 listener->Forward[2] = -1.0f;
2524 listener->Up[0] = 0.0f;
2525 listener->Up[1] = 1.0f;
2526 listener->Up[2] = 0.0f;
2528 aluMatrixfSet(&listener->Params.Matrix,
2529 1.0f, 0.0f, 0.0f, 0.0f,
2530 0.0f, 1.0f, 0.0f, 0.0f,
2531 0.0f, 0.0f, 1.0f, 0.0f,
2532 0.0f, 0.0f, 0.0f, 1.0f
2534 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2535 listener->Params.Gain = 1.0f;
2536 listener->Params.MetersPerUnit = 1.0f;
2537 listener->Params.DopplerFactor = 1.0f;
2538 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2540 ATOMIC_INIT(&listener->Update, NULL);
2541 ATOMIC_INIT(&listener->FreeList, NULL);
2543 //Validate Context
2544 InitRef(&Context->UpdateCount, 0);
2545 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2546 Context->GainBoost = 1.0f;
2547 RWLockInit(&Context->PropLock);
2548 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2549 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2550 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2552 auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray));
2553 auxslots->count = 0;
2554 ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots);
2556 //Set globals
2557 Context->DistanceModel = DefaultDistanceModel;
2558 Context->SourceDistanceModel = AL_FALSE;
2559 Context->DopplerFactor = 1.0f;
2560 Context->DopplerVelocity = 1.0f;
2561 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2562 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2564 Context->ExtensionList = alExtList;
2568 /* FreeContext
2570 * Cleans up the context, and destroys any remaining objects the app failed to
2571 * delete. Called once there's no more references on the context.
2573 static void FreeContext(ALCcontext *context)
2575 ALlistener *listener = context->Listener;
2576 struct ALeffectslotArray *auxslots;
2577 struct ALlistenerProps *lprops;
2578 size_t count;
2579 ALsizei i;
2581 TRACE("%p\n", context);
2583 if(context->DefaultSlot)
2585 DeinitEffectSlot(context->DefaultSlot);
2586 context->DefaultSlot = NULL;
2589 auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
2590 al_free(auxslots);
2592 if(context->SourceMap.size > 0)
2594 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2595 (context->SourceMap.size==1)?"":"s");
2596 ReleaseALSources(context);
2598 ResetUIntMap(&context->SourceMap);
2600 if(context->EffectSlotMap.size > 0)
2602 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2603 (context->EffectSlotMap.size==1)?"":"s");
2604 ReleaseALAuxiliaryEffectSlots(context);
2606 ResetUIntMap(&context->EffectSlotMap);
2608 for(i = 0;i < context->VoiceCount;i++)
2609 DeinitVoice(context->Voices[i]);
2610 al_free(context->Voices);
2611 context->Voices = NULL;
2612 context->VoiceCount = 0;
2613 context->MaxVoices = 0;
2615 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2617 TRACE("Freed unapplied listener update %p\n", lprops);
2618 al_free(lprops);
2620 count = 0;
2621 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
2622 while(lprops)
2624 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2625 al_free(lprops);
2626 lprops = next;
2627 ++count;
2629 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2631 ALCdevice_DecRef(context->Device);
2632 context->Device = NULL;
2634 //Invalidate context
2635 memset(context, 0, sizeof(ALCcontext));
2636 al_free(context);
2639 /* ReleaseContext
2641 * Removes the context reference from the given device and removes it from
2642 * being current on the running thread or globally. Returns true if other
2643 * contexts still exist on the device.
2645 static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
2647 ALCcontext *origctx, *newhead;
2648 bool ret = true;
2650 if(altss_get(LocalContext) == context)
2652 WARN("%p released while current on thread\n", context);
2653 altss_set(LocalContext, NULL);
2654 ALCcontext_DecRef(context);
2657 origctx = context;
2658 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
2659 ALCcontext_DecRef(context);
2661 ALCdevice_Lock(device);
2662 origctx = context;
2663 newhead = context->next;
2664 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
2666 ALCcontext *volatile*list = &origctx->next;
2667 while(*list)
2669 if(*list == context)
2671 *list = (*list)->next;
2672 break;
2674 list = &(*list)->next;
2677 else
2678 ret = !!newhead;
2679 ALCdevice_Unlock(device);
2681 ALCcontext_DecRef(context);
2682 return ret;
2685 void ALCcontext_IncRef(ALCcontext *context)
2687 uint ref = IncrementRef(&context->ref);
2688 TRACEREF("%p increasing refcount to %u\n", context, ref);
2691 void ALCcontext_DecRef(ALCcontext *context)
2693 uint ref = DecrementRef(&context->ref);
2694 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2695 if(ref == 0) FreeContext(context);
2698 static void ReleaseThreadCtx(void *ptr)
2700 ALCcontext *context = ptr;
2701 uint ref = DecrementRef(&context->ref);
2702 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2703 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2706 /* VerifyContext
2708 * Checks that the given context is valid, and increments its reference count.
2710 static ALCboolean VerifyContext(ALCcontext **context)
2712 ALCdevice *dev;
2714 LockLists();
2715 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2716 while(dev)
2718 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2719 while(ctx)
2721 if(ctx == *context)
2723 ALCcontext_IncRef(ctx);
2724 UnlockLists();
2725 return ALC_TRUE;
2727 ctx = ctx->next;
2729 dev = dev->next;
2731 UnlockLists();
2733 *context = NULL;
2734 return ALC_FALSE;
2738 /* GetContextRef
2740 * Returns the currently active context for this thread, and adds a reference
2741 * without locking it.
2743 ALCcontext *GetContextRef(void)
2745 ALCcontext *context;
2747 context = altss_get(LocalContext);
2748 if(context)
2749 ALCcontext_IncRef(context);
2750 else
2752 LockLists();
2753 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2754 if(context)
2755 ALCcontext_IncRef(context);
2756 UnlockLists();
2759 return context;
2763 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2765 ALCdevice *device = context->Device;
2766 ALsizei num_sends = device->NumAuxSends;
2767 struct ALvoiceProps *props;
2768 size_t sizeof_props;
2769 size_t sizeof_voice;
2770 ALvoice **voices;
2771 ALvoice *voice;
2772 ALsizei v = 0;
2773 size_t size;
2775 if(num_voices == context->MaxVoices && num_sends == old_sends)
2776 return;
2778 /* Allocate the voice pointers, voices, and the voices' stored source
2779 * property set (including the dynamically-sized Send[] array) in one
2780 * chunk.
2782 sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
2783 sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
2784 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2786 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2787 /* The voice and property objects are stored interleaved since they're
2788 * paired together.
2790 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2791 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2793 if(context->Voices)
2795 const ALsizei v_count = mini(context->VoiceCount, num_voices);
2796 const ALsizei s_count = mini(old_sends, num_sends);
2798 for(;v < v_count;v++)
2800 ALvoice *old_voice = context->Voices[v];
2801 ALsizei i;
2803 /* Copy the old voice data and source property set to the new
2804 * storage.
2806 *voice = *old_voice;
2807 for(i = 0;i < s_count;i++)
2808 voice->Send[i] = old_voice->Send[i];
2809 *props = *(old_voice->Props);
2810 for(i = 0;i < s_count;i++)
2811 props->Send[i] = old_voice->Props->Send[i];
2813 /* Set this voice's property set pointer and voice reference. */
2814 voice->Props = props;
2815 voices[v] = voice;
2817 /* Increment pointers to the next storage space. */
2818 voice = (ALvoice*)((char*)props + sizeof_props);
2819 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2821 /* Deinit any left over voices that weren't copied over to the new
2822 * array. NOTE: If this does anything, v equals num_voices and
2823 * num_voices is less than VoiceCount, so the following loop won't do
2824 * anything.
2826 for(;v < context->VoiceCount;v++)
2827 DeinitVoice(context->Voices[v]);
2829 /* Finish setting the voices' property set pointers and references. */
2830 for(;v < num_voices;v++)
2832 ATOMIC_INIT(&voice->Update, NULL);
2833 ATOMIC_INIT(&voice->FreeList, NULL);
2835 voice->Props = props;
2836 voices[v] = voice;
2838 voice = (ALvoice*)((char*)props + sizeof_props);
2839 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2842 al_free(context->Voices);
2843 context->Voices = voices;
2844 context->MaxVoices = num_voices;
2845 context->VoiceCount = mini(context->VoiceCount, num_voices);
2849 /************************************************
2850 * Standard ALC functions
2851 ************************************************/
2853 /* alcGetError
2855 * Return last ALC generated error code for the given device
2857 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2859 ALCenum errorCode;
2861 if(VerifyDevice(&device))
2863 errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
2864 ALCdevice_DecRef(device);
2866 else
2867 errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
2869 return errorCode;
2873 /* alcSuspendContext
2875 * Suspends updates for the given context
2877 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2879 if(!SuspendDefers)
2880 return;
2882 if(!VerifyContext(&context))
2883 alcSetError(NULL, ALC_INVALID_CONTEXT);
2884 else
2886 ALCcontext_DeferUpdates(context);
2887 ALCcontext_DecRef(context);
2891 /* alcProcessContext
2893 * Resumes processing updates for the given context
2895 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2897 if(!SuspendDefers)
2898 return;
2900 if(!VerifyContext(&context))
2901 alcSetError(NULL, ALC_INVALID_CONTEXT);
2902 else
2904 ALCcontext_ProcessUpdates(context);
2905 ALCcontext_DecRef(context);
2910 /* alcGetString
2912 * Returns information about the device, and error strings
2914 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2916 const ALCchar *value = NULL;
2918 switch(param)
2920 case ALC_NO_ERROR:
2921 value = alcNoError;
2922 break;
2924 case ALC_INVALID_ENUM:
2925 value = alcErrInvalidEnum;
2926 break;
2928 case ALC_INVALID_VALUE:
2929 value = alcErrInvalidValue;
2930 break;
2932 case ALC_INVALID_DEVICE:
2933 value = alcErrInvalidDevice;
2934 break;
2936 case ALC_INVALID_CONTEXT:
2937 value = alcErrInvalidContext;
2938 break;
2940 case ALC_OUT_OF_MEMORY:
2941 value = alcErrOutOfMemory;
2942 break;
2944 case ALC_DEVICE_SPECIFIER:
2945 value = alcDefaultName;
2946 break;
2948 case ALC_ALL_DEVICES_SPECIFIER:
2949 if(VerifyDevice(&Device))
2951 value = alstr_get_cstr(Device->DeviceName);
2952 ALCdevice_DecRef(Device);
2954 else
2956 ProbeAllDevicesList();
2957 value = alstr_get_cstr(alcAllDevicesList);
2959 break;
2961 case ALC_CAPTURE_DEVICE_SPECIFIER:
2962 if(VerifyDevice(&Device))
2964 value = alstr_get_cstr(Device->DeviceName);
2965 ALCdevice_DecRef(Device);
2967 else
2969 ProbeCaptureDeviceList();
2970 value = alstr_get_cstr(alcCaptureDeviceList);
2972 break;
2974 /* Default devices are always first in the list */
2975 case ALC_DEFAULT_DEVICE_SPECIFIER:
2976 value = alcDefaultName;
2977 break;
2979 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2980 if(alstr_empty(alcAllDevicesList))
2981 ProbeAllDevicesList();
2983 VerifyDevice(&Device);
2985 free(alcDefaultAllDevicesSpecifier);
2986 alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
2987 if(!alcDefaultAllDevicesSpecifier)
2988 alcSetError(Device, ALC_OUT_OF_MEMORY);
2990 value = alcDefaultAllDevicesSpecifier;
2991 if(Device) ALCdevice_DecRef(Device);
2992 break;
2994 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2995 if(alstr_empty(alcCaptureDeviceList))
2996 ProbeCaptureDeviceList();
2998 VerifyDevice(&Device);
3000 free(alcCaptureDefaultDeviceSpecifier);
3001 alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
3002 if(!alcCaptureDefaultDeviceSpecifier)
3003 alcSetError(Device, ALC_OUT_OF_MEMORY);
3005 value = alcCaptureDefaultDeviceSpecifier;
3006 if(Device) ALCdevice_DecRef(Device);
3007 break;
3009 case ALC_EXTENSIONS:
3010 if(!VerifyDevice(&Device))
3011 value = alcNoDeviceExtList;
3012 else
3014 value = alcExtensionList;
3015 ALCdevice_DecRef(Device);
3017 break;
3019 case ALC_HRTF_SPECIFIER_SOFT:
3020 if(!VerifyDevice(&Device))
3021 alcSetError(NULL, ALC_INVALID_DEVICE);
3022 else
3024 almtx_lock(&Device->BackendLock);
3025 value = (Device->HrtfHandle ? alstr_get_cstr(Device->HrtfName) : "");
3026 almtx_unlock(&Device->BackendLock);
3027 ALCdevice_DecRef(Device);
3029 break;
3031 default:
3032 VerifyDevice(&Device);
3033 alcSetError(Device, ALC_INVALID_ENUM);
3034 if(Device) ALCdevice_DecRef(Device);
3035 break;
3038 return value;
3042 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
3044 if(device->Type == Loopback && device->FmtChans == DevFmtAmbi3D)
3045 return 25;
3046 return 19;
3049 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3051 ALCsizei i;
3053 if(size <= 0 || values == NULL)
3055 alcSetError(device, ALC_INVALID_VALUE);
3056 return 0;
3059 if(!device)
3061 switch(param)
3063 case ALC_MAJOR_VERSION:
3064 values[0] = alcMajorVersion;
3065 return 1;
3066 case ALC_MINOR_VERSION:
3067 values[0] = alcMinorVersion;
3068 return 1;
3070 case ALC_ATTRIBUTES_SIZE:
3071 case ALC_ALL_ATTRIBUTES:
3072 case ALC_FREQUENCY:
3073 case ALC_REFRESH:
3074 case ALC_SYNC:
3075 case ALC_MONO_SOURCES:
3076 case ALC_STEREO_SOURCES:
3077 case ALC_CAPTURE_SAMPLES:
3078 case ALC_FORMAT_CHANNELS_SOFT:
3079 case ALC_FORMAT_TYPE_SOFT:
3080 case ALC_AMBISONIC_LAYOUT_SOFT:
3081 case ALC_AMBISONIC_SCALING_SOFT:
3082 case ALC_AMBISONIC_ORDER_SOFT:
3083 alcSetError(NULL, ALC_INVALID_DEVICE);
3084 return 0;
3086 default:
3087 alcSetError(NULL, ALC_INVALID_ENUM);
3088 return 0;
3090 return 0;
3093 if(device->Type == Capture)
3095 switch(param)
3097 case ALC_CAPTURE_SAMPLES:
3098 almtx_lock(&device->BackendLock);
3099 values[0] = V0(device->Backend,availableSamples)();
3100 almtx_unlock(&device->BackendLock);
3101 return 1;
3103 case ALC_CONNECTED:
3104 values[0] = device->Connected;
3105 return 1;
3107 default:
3108 alcSetError(device, ALC_INVALID_ENUM);
3109 return 0;
3111 return 0;
3114 /* render device */
3115 switch(param)
3117 case ALC_MAJOR_VERSION:
3118 values[0] = alcMajorVersion;
3119 return 1;
3121 case ALC_MINOR_VERSION:
3122 values[0] = alcMinorVersion;
3123 return 1;
3125 case ALC_EFX_MAJOR_VERSION:
3126 values[0] = alcEFXMajorVersion;
3127 return 1;
3129 case ALC_EFX_MINOR_VERSION:
3130 values[0] = alcEFXMinorVersion;
3131 return 1;
3133 case ALC_ATTRIBUTES_SIZE:
3134 values[0] = NumAttrsForDevice(device);
3135 return 1;
3137 case ALC_ALL_ATTRIBUTES:
3138 if(size < NumAttrsForDevice(device))
3140 alcSetError(device, ALC_INVALID_VALUE);
3141 return 0;
3144 i = 0;
3145 almtx_lock(&device->BackendLock);
3146 values[i++] = ALC_FREQUENCY;
3147 values[i++] = device->Frequency;
3149 if(device->Type != Loopback)
3151 values[i++] = ALC_REFRESH;
3152 values[i++] = device->Frequency / device->UpdateSize;
3154 values[i++] = ALC_SYNC;
3155 values[i++] = ALC_FALSE;
3157 else
3159 if(device->FmtChans == DevFmtAmbi3D)
3161 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3162 values[i++] = device->AmbiLayout;
3164 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3165 values[i++] = device->AmbiScale;
3167 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3168 values[i++] = device->AmbiOrder;
3171 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3172 values[i++] = device->FmtChans;
3174 values[i++] = ALC_FORMAT_TYPE_SOFT;
3175 values[i++] = device->FmtType;
3178 values[i++] = ALC_MONO_SOURCES;
3179 values[i++] = device->NumMonoSources;
3181 values[i++] = ALC_STEREO_SOURCES;
3182 values[i++] = device->NumStereoSources;
3184 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3185 values[i++] = device->NumAuxSends;
3187 values[i++] = ALC_HRTF_SOFT;
3188 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3190 values[i++] = ALC_HRTF_STATUS_SOFT;
3191 values[i++] = device->HrtfStatus;
3193 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3194 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3195 almtx_unlock(&device->BackendLock);
3197 values[i++] = 0;
3198 return i;
3200 case ALC_FREQUENCY:
3201 values[0] = device->Frequency;
3202 return 1;
3204 case ALC_REFRESH:
3205 if(device->Type == Loopback)
3207 alcSetError(device, ALC_INVALID_DEVICE);
3208 return 0;
3210 almtx_lock(&device->BackendLock);
3211 values[0] = device->Frequency / device->UpdateSize;
3212 almtx_unlock(&device->BackendLock);
3213 return 1;
3215 case ALC_SYNC:
3216 if(device->Type == Loopback)
3218 alcSetError(device, ALC_INVALID_DEVICE);
3219 return 0;
3221 values[0] = ALC_FALSE;
3222 return 1;
3224 case ALC_FORMAT_CHANNELS_SOFT:
3225 if(device->Type != Loopback)
3227 alcSetError(device, ALC_INVALID_DEVICE);
3228 return 0;
3230 values[0] = device->FmtChans;
3231 return 1;
3233 case ALC_FORMAT_TYPE_SOFT:
3234 if(device->Type != Loopback)
3236 alcSetError(device, ALC_INVALID_DEVICE);
3237 return 0;
3239 values[0] = device->FmtType;
3240 return 1;
3242 case ALC_AMBISONIC_LAYOUT_SOFT:
3243 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3245 alcSetError(device, ALC_INVALID_DEVICE);
3246 return 0;
3248 values[0] = device->AmbiLayout;
3249 return 1;
3251 case ALC_AMBISONIC_SCALING_SOFT:
3252 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3254 alcSetError(device, ALC_INVALID_DEVICE);
3255 return 0;
3257 values[0] = device->AmbiScale;
3258 return 1;
3260 case ALC_AMBISONIC_ORDER_SOFT:
3261 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3263 alcSetError(device, ALC_INVALID_DEVICE);
3264 return 0;
3266 values[0] = device->AmbiOrder;
3267 return 1;
3269 case ALC_MONO_SOURCES:
3270 values[0] = device->NumMonoSources;
3271 return 1;
3273 case ALC_STEREO_SOURCES:
3274 values[0] = device->NumStereoSources;
3275 return 1;
3277 case ALC_MAX_AUXILIARY_SENDS:
3278 values[0] = device->NumAuxSends;
3279 return 1;
3281 case ALC_CONNECTED:
3282 values[0] = device->Connected;
3283 return 1;
3285 case ALC_HRTF_SOFT:
3286 values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3287 return 1;
3289 case ALC_HRTF_STATUS_SOFT:
3290 values[0] = device->HrtfStatus;
3291 return 1;
3293 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3294 almtx_lock(&device->BackendLock);
3295 FreeHrtfList(&device->HrtfList);
3296 device->HrtfList = EnumerateHrtf(device->DeviceName);
3297 values[0] = (ALCint)VECTOR_SIZE(device->HrtfList);
3298 almtx_unlock(&device->BackendLock);
3299 return 1;
3301 case ALC_OUTPUT_LIMITER_SOFT:
3302 values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3303 return 1;
3305 default:
3306 alcSetError(device, ALC_INVALID_ENUM);
3307 return 0;
3309 return 0;
3312 /* alcGetIntegerv
3314 * Returns information about the device and the version of OpenAL
3316 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3318 VerifyDevice(&device);
3319 if(size <= 0 || values == NULL)
3320 alcSetError(device, ALC_INVALID_VALUE);
3321 else
3322 GetIntegerv(device, param, size, values);
3323 if(device) ALCdevice_DecRef(device);
3326 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3328 ALCint *ivals;
3329 ALsizei i;
3331 VerifyDevice(&device);
3332 if(size <= 0 || values == NULL)
3333 alcSetError(device, ALC_INVALID_VALUE);
3334 else if(!device || device->Type == Capture)
3336 ivals = malloc(size * sizeof(ALCint));
3337 size = GetIntegerv(device, pname, size, ivals);
3338 for(i = 0;i < size;i++)
3339 values[i] = ivals[i];
3340 free(ivals);
3342 else /* render device */
3344 ClockLatency clock;
3345 ALuint64 basecount;
3346 ALuint samplecount;
3347 ALuint refcount;
3349 switch(pname)
3351 case ALC_ATTRIBUTES_SIZE:
3352 *values = NumAttrsForDevice(device)+4;
3353 break;
3355 case ALC_ALL_ATTRIBUTES:
3356 if(size < NumAttrsForDevice(device)+4)
3357 alcSetError(device, ALC_INVALID_VALUE);
3358 else
3360 i = 0;
3361 almtx_lock(&device->BackendLock);
3362 values[i++] = ALC_FREQUENCY;
3363 values[i++] = device->Frequency;
3365 if(device->Type != Loopback)
3367 values[i++] = ALC_REFRESH;
3368 values[i++] = device->Frequency / device->UpdateSize;
3370 values[i++] = ALC_SYNC;
3371 values[i++] = ALC_FALSE;
3373 else
3375 if(device->FmtChans == DevFmtAmbi3D)
3377 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3378 values[i++] = device->AmbiLayout;
3380 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3381 values[i++] = device->AmbiScale;
3383 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3384 values[i++] = device->AmbiOrder;
3387 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3388 values[i++] = device->FmtChans;
3390 values[i++] = ALC_FORMAT_TYPE_SOFT;
3391 values[i++] = device->FmtType;
3394 values[i++] = ALC_MONO_SOURCES;
3395 values[i++] = device->NumMonoSources;
3397 values[i++] = ALC_STEREO_SOURCES;
3398 values[i++] = device->NumStereoSources;
3400 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3401 values[i++] = device->NumAuxSends;
3403 values[i++] = ALC_HRTF_SOFT;
3404 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3406 values[i++] = ALC_HRTF_STATUS_SOFT;
3407 values[i++] = device->HrtfStatus;
3409 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3410 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3412 clock = V0(device->Backend,getClockLatency)();
3413 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3414 values[i++] = clock.ClockTime;
3416 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3417 values[i++] = clock.Latency;
3418 almtx_unlock(&device->BackendLock);
3420 values[i++] = 0;
3422 break;
3424 case ALC_DEVICE_CLOCK_SOFT:
3425 almtx_lock(&device->BackendLock);
3426 do {
3427 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3428 althrd_yield();
3429 basecount = device->ClockBase;
3430 samplecount = device->SamplesDone;
3431 } while(refcount != ReadRef(&device->MixCount));
3432 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3433 almtx_unlock(&device->BackendLock);
3434 break;
3436 case ALC_DEVICE_LATENCY_SOFT:
3437 almtx_lock(&device->BackendLock);
3438 clock = V0(device->Backend,getClockLatency)();
3439 almtx_unlock(&device->BackendLock);
3440 *values = clock.Latency;
3441 break;
3443 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3444 if(size < 2)
3445 alcSetError(device, ALC_INVALID_VALUE);
3446 else
3448 almtx_lock(&device->BackendLock);
3449 clock = V0(device->Backend,getClockLatency)();
3450 almtx_unlock(&device->BackendLock);
3451 values[0] = clock.ClockTime;
3452 values[1] = clock.Latency;
3454 break;
3456 default:
3457 ivals = malloc(size * sizeof(ALCint));
3458 size = GetIntegerv(device, pname, size, ivals);
3459 for(i = 0;i < size;i++)
3460 values[i] = ivals[i];
3461 free(ivals);
3462 break;
3465 if(device)
3466 ALCdevice_DecRef(device);
3470 /* alcIsExtensionPresent
3472 * Determines if there is support for a particular extension
3474 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3476 ALCboolean bResult = ALC_FALSE;
3478 VerifyDevice(&device);
3480 if(!extName)
3481 alcSetError(device, ALC_INVALID_VALUE);
3482 else
3484 size_t len = strlen(extName);
3485 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3486 while(ptr && *ptr)
3488 if(strncasecmp(ptr, extName, len) == 0 &&
3489 (ptr[len] == '\0' || isspace(ptr[len])))
3491 bResult = ALC_TRUE;
3492 break;
3494 if((ptr=strchr(ptr, ' ')) != NULL)
3496 do {
3497 ++ptr;
3498 } while(isspace(*ptr));
3502 if(device)
3503 ALCdevice_DecRef(device);
3504 return bResult;
3508 /* alcGetProcAddress
3510 * Retrieves the function address for a particular extension function
3512 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3514 ALCvoid *ptr = NULL;
3516 if(!funcName)
3518 VerifyDevice(&device);
3519 alcSetError(device, ALC_INVALID_VALUE);
3520 if(device) ALCdevice_DecRef(device);
3522 else
3524 size_t i = 0;
3525 for(i = 0;i < COUNTOF(alcFunctions);i++)
3527 if(strcmp(alcFunctions[i].funcName, funcName) == 0)
3529 ptr = alcFunctions[i].address;
3530 break;
3535 return ptr;
3539 /* alcGetEnumValue
3541 * Get the value for a particular ALC enumeration name
3543 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3545 ALCenum val = 0;
3547 if(!enumName)
3549 VerifyDevice(&device);
3550 alcSetError(device, ALC_INVALID_VALUE);
3551 if(device) ALCdevice_DecRef(device);
3553 else
3555 size_t i = 0;
3556 for(i = 0;i < COUNTOF(alcEnumerations);i++)
3558 if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
3560 val = alcEnumerations[i].value;
3561 break;
3566 return val;
3570 /* alcCreateContext
3572 * Create and attach a context to the given device.
3574 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3576 ALCcontext *ALContext;
3577 ALfloat valf;
3578 ALCenum err;
3580 /* Explicitly hold the list lock while taking the BackendLock in case the
3581 * device is asynchronously destropyed, to ensure this new context is
3582 * properly cleaned up after being made.
3584 LockLists();
3585 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3587 UnlockLists();
3588 alcSetError(device, ALC_INVALID_DEVICE);
3589 if(device) ALCdevice_DecRef(device);
3590 return NULL;
3592 almtx_lock(&device->BackendLock);
3593 UnlockLists();
3595 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3597 if(device->Type == Playback && DefaultEffect.type != AL_EFFECT_NULL)
3598 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener)+sizeof(ALeffectslot));
3599 else
3600 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3601 if(!ALContext)
3603 almtx_unlock(&device->BackendLock);
3605 alcSetError(device, ALC_OUT_OF_MEMORY);
3606 ALCdevice_DecRef(device);
3607 return NULL;
3610 InitRef(&ALContext->ref, 1);
3611 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3612 ALContext->DefaultSlot = NULL;
3614 ALContext->Voices = NULL;
3615 ALContext->VoiceCount = 0;
3616 ALContext->MaxVoices = 0;
3617 ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL);
3618 ALContext->Device = device;
3620 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3622 almtx_unlock(&device->BackendLock);
3624 al_free(ALContext);
3625 ALContext = NULL;
3627 alcSetError(device, err);
3628 if(err == ALC_INVALID_DEVICE)
3630 V0(device->Backend,lock)();
3631 aluHandleDisconnect(device);
3632 V0(device->Backend,unlock)();
3634 ALCdevice_DecRef(device);
3635 return NULL;
3637 AllocateVoices(ALContext, 256, device->NumAuxSends);
3639 if(DefaultEffect.type != AL_EFFECT_NULL && device->Type == Playback)
3641 ALContext->DefaultSlot = (ALeffectslot*)(ALContext->_listener_mem + sizeof(ALlistener));
3642 if(InitEffectSlot(ALContext->DefaultSlot) != AL_NO_ERROR)
3644 ALContext->DefaultSlot = NULL;
3645 ERR("Failed to initialize the default effect slot\n");
3647 else
3649 aluInitEffectPanning(ALContext->DefaultSlot);
3650 if(InitializeEffect(device, ALContext->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3652 DeinitEffectSlot(ALContext->DefaultSlot);
3653 ALContext->DefaultSlot = NULL;
3654 ERR("Failed to initialize the default effect\n");
3657 if(ALContext->DefaultSlot)
3659 ALeffectslot *slot = ALContext->DefaultSlot;
3660 ALeffectState *state = slot->Effect.State;
3662 START_MIXER_MODE();
3663 state->OutBuffer = device->Dry.Buffer;
3664 state->OutChannels = device->Dry.NumChannels;
3665 if(V(state,deviceUpdate)(device) != AL_FALSE)
3666 UpdateEffectSlotProps(slot);
3667 else
3669 DeinitEffectSlot(ALContext->DefaultSlot);
3670 ALContext->DefaultSlot = NULL;
3672 END_MIXER_MODE();
3676 ALCdevice_IncRef(ALContext->Device);
3677 InitContext(ALContext);
3679 if(ConfigValueFloat(alstr_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3681 if(!isfinite(valf))
3682 ERR("volume-adjust must be finite: %f\n", valf);
3683 else
3685 ALfloat db = clampf(valf, -24.0f, 24.0f);
3686 if(db != valf)
3687 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3688 ALContext->GainBoost = powf(10.0f, db/20.0f);
3689 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3692 UpdateListenerProps(ALContext);
3695 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3696 do {
3697 ALContext->next = head;
3698 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
3699 ALContext) == 0);
3701 almtx_unlock(&device->BackendLock);
3703 ALCdevice_DecRef(device);
3705 TRACE("Created context %p\n", ALContext);
3706 return ALContext;
3709 /* alcDestroyContext
3711 * Remove a context from its device
3713 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3715 ALCdevice *Device;
3717 LockLists();
3718 if(!VerifyContext(&context))
3720 UnlockLists();
3721 alcSetError(NULL, ALC_INVALID_CONTEXT);
3722 return;
3725 Device = context->Device;
3726 if(Device)
3728 almtx_lock(&Device->BackendLock);
3729 if(!ReleaseContext(context, Device))
3731 V0(Device->Backend,stop)();
3732 Device->Flags &= ~DEVICE_RUNNING;
3734 almtx_unlock(&Device->BackendLock);
3736 UnlockLists();
3738 ALCcontext_DecRef(context);
3742 /* alcGetCurrentContext
3744 * Returns the currently active context on the calling thread
3746 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3748 ALCcontext *Context = altss_get(LocalContext);
3749 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3750 return Context;
3753 /* alcGetThreadContext
3755 * Returns the currently active thread-local context
3757 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3759 return altss_get(LocalContext);
3763 /* alcMakeContextCurrent
3765 * Makes the given context the active process-wide context, and removes the
3766 * thread-local context for the calling thread.
3768 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3770 /* context must be valid or NULL */
3771 if(context && !VerifyContext(&context))
3773 alcSetError(NULL, ALC_INVALID_CONTEXT);
3774 return ALC_FALSE;
3776 /* context's reference count is already incremented */
3777 context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
3778 if(context) ALCcontext_DecRef(context);
3780 if((context=altss_get(LocalContext)) != NULL)
3782 altss_set(LocalContext, NULL);
3783 ALCcontext_DecRef(context);
3786 return ALC_TRUE;
3789 /* alcSetThreadContext
3791 * Makes the given context the active context for the current thread
3793 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3795 ALCcontext *old;
3797 /* context must be valid or NULL */
3798 if(context && !VerifyContext(&context))
3800 alcSetError(NULL, ALC_INVALID_CONTEXT);
3801 return ALC_FALSE;
3803 /* context's reference count is already incremented */
3804 old = altss_get(LocalContext);
3805 altss_set(LocalContext, context);
3806 if(old) ALCcontext_DecRef(old);
3808 return ALC_TRUE;
3812 /* alcGetContextsDevice
3814 * Returns the device that a particular context is attached to
3816 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3818 ALCdevice *Device;
3820 if(!VerifyContext(&Context))
3822 alcSetError(NULL, ALC_INVALID_CONTEXT);
3823 return NULL;
3825 Device = Context->Device;
3826 ALCcontext_DecRef(Context);
3828 return Device;
3832 /* alcOpenDevice
3834 * Opens the named device.
3836 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3838 ALCbackendFactory *factory;
3839 const ALCchar *fmt;
3840 ALCdevice *device;
3841 ALCenum err;
3842 ALCsizei i;
3844 DO_INITCONFIG();
3846 if(!PlaybackBackend.name)
3848 alcSetError(NULL, ALC_INVALID_VALUE);
3849 return NULL;
3852 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3853 #ifdef _WIN32
3854 /* Some old Windows apps hardcode these expecting OpenAL to use a
3855 * specific audio API, even when they're not enumerated. Creative's
3856 * router effectively ignores them too.
3858 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3859 || strcasecmp(deviceName, "MMSYSTEM") == 0
3860 #endif
3862 deviceName = NULL;
3864 device = al_calloc(16, sizeof(ALCdevice));
3865 if(!device)
3867 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3868 return NULL;
3871 //Validate device
3872 InitRef(&device->ref, 1);
3873 device->Connected = ALC_TRUE;
3874 device->Type = Playback;
3875 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3877 device->Flags = 0;
3878 device->Bs2b = NULL;
3879 device->Uhj_Encoder = NULL;
3880 device->Hrtf = NULL;
3881 device->HrtfHandle = NULL;
3882 VECTOR_INIT(device->HrtfList);
3883 AL_STRING_INIT(device->HrtfName);
3884 device->Render_Mode = NormalRender;
3885 AL_STRING_INIT(device->DeviceName);
3886 device->Dry.Buffer = NULL;
3887 device->Dry.NumChannels = 0;
3888 device->FOAOut.Buffer = NULL;
3889 device->FOAOut.NumChannels = 0;
3890 device->RealOut.Buffer = NULL;
3891 device->RealOut.NumChannels = 0;
3892 device->Limiter = NULL;
3893 device->AvgSpeakerDist = 0.0f;
3895 ATOMIC_INIT(&device->ContextList, NULL);
3897 device->ClockBase = 0;
3898 device->SamplesDone = 0;
3900 device->SourcesMax = 256;
3901 device->AuxiliaryEffectSlotMax = 64;
3902 device->NumAuxSends = DEFAULT_SENDS;
3904 InitUIntMap(&device->BufferMap, INT_MAX);
3905 InitUIntMap(&device->EffectMap, INT_MAX);
3906 InitUIntMap(&device->FilterMap, INT_MAX);
3908 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3910 device->ChannelDelay[i].Gain = 1.0f;
3911 device->ChannelDelay[i].Length = 0;
3912 device->ChannelDelay[i].Buffer = NULL;
3915 //Set output format
3916 device->FmtChans = DevFmtChannelsDefault;
3917 device->FmtType = DevFmtTypeDefault;
3918 device->Frequency = DEFAULT_OUTPUT_RATE;
3919 device->IsHeadphones = AL_FALSE;
3920 device->AmbiLayout = AmbiLayout_Default;
3921 device->AmbiScale = AmbiNorm_Default;
3922 device->NumUpdates = 3;
3923 device->UpdateSize = 1024;
3925 factory = PlaybackBackend.getFactory();
3926 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3927 if(!device->Backend)
3929 al_free(device);
3930 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3931 return NULL;
3935 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3937 static const struct {
3938 const char name[16];
3939 enum DevFmtChannels chans;
3940 ALsizei order;
3941 } chanlist[] = {
3942 { "mono", DevFmtMono, 0 },
3943 { "stereo", DevFmtStereo, 0 },
3944 { "quad", DevFmtQuad, 0 },
3945 { "surround51", DevFmtX51, 0 },
3946 { "surround61", DevFmtX61, 0 },
3947 { "surround71", DevFmtX71, 0 },
3948 { "surround51rear", DevFmtX51Rear, 0 },
3949 { "ambi1", DevFmtAmbi3D, 1 },
3950 { "ambi2", DevFmtAmbi3D, 2 },
3951 { "ambi3", DevFmtAmbi3D, 3 },
3953 size_t i;
3955 for(i = 0;i < COUNTOF(chanlist);i++)
3957 if(strcasecmp(chanlist[i].name, fmt) == 0)
3959 device->FmtChans = chanlist[i].chans;
3960 device->AmbiOrder = chanlist[i].order;
3961 device->Flags |= DEVICE_CHANNELS_REQUEST;
3962 break;
3965 if(i == COUNTOF(chanlist))
3966 ERR("Unsupported channels: %s\n", fmt);
3968 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3970 static const struct {
3971 const char name[16];
3972 enum DevFmtType type;
3973 } typelist[] = {
3974 { "int8", DevFmtByte },
3975 { "uint8", DevFmtUByte },
3976 { "int16", DevFmtShort },
3977 { "uint16", DevFmtUShort },
3978 { "int32", DevFmtInt },
3979 { "uint32", DevFmtUInt },
3980 { "float32", DevFmtFloat },
3982 size_t i;
3984 for(i = 0;i < COUNTOF(typelist);i++)
3986 if(strcasecmp(typelist[i].name, fmt) == 0)
3988 device->FmtType = typelist[i].type;
3989 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3990 break;
3993 if(i == COUNTOF(typelist))
3994 ERR("Unsupported sample-type: %s\n", fmt);
3997 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3999 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4000 if(device->Frequency < MIN_OUTPUT_RATE)
4001 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
4002 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
4005 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
4006 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
4008 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
4009 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
4010 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
4011 device->UpdateSize = (device->UpdateSize+3)&~3;
4013 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
4014 if(device->SourcesMax == 0) device->SourcesMax = 256;
4016 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4017 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4019 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
4020 device->NumAuxSends = clampi(
4021 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4024 device->NumStereoSources = 1;
4025 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4027 // Find a playback device to open
4028 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4030 DELETE_OBJ(device->Backend);
4031 al_free(device);
4032 alcSetError(NULL, err);
4033 return NULL;
4035 almtx_init(&device->BackendLock, almtx_plain);
4037 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
4039 if(strcasecmp(fmt, "fuma") == 0)
4041 device->AmbiLayout = AmbiLayout_FuMa;
4042 device->AmbiScale = AmbiNorm_FuMa;
4044 else if(strcasecmp(fmt, "acn+sn3d") == 0)
4046 device->AmbiLayout = AmbiLayout_ACN;
4047 device->AmbiScale = AmbiNorm_SN3D;
4049 else if(strcasecmp(fmt, "acn+n3d") == 0)
4051 device->AmbiLayout = AmbiLayout_ACN;
4052 device->AmbiScale = AmbiNorm_N3D;
4054 else
4055 ERR("Unsupported ambi-format: %s\n", fmt);
4058 device->Limiter = CreateDeviceLimiter(device);
4061 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4062 do {
4063 device->next = head;
4064 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4067 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4068 return device;
4071 /* alcCloseDevice
4073 * Closes the given device.
4075 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
4077 ALCdevice *iter, *origdev;
4078 ALCcontext *ctx;
4080 LockLists();
4081 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4082 do {
4083 if(iter == device)
4084 break;
4085 } while((iter=iter->next) != NULL);
4086 if(!iter || iter->Type == Capture)
4088 alcSetError(iter, ALC_INVALID_DEVICE);
4089 UnlockLists();
4090 return ALC_FALSE;
4092 almtx_lock(&device->BackendLock);
4094 origdev = device;
4095 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4097 ALCdevice *volatile*list = &origdev->next;
4098 while(*list)
4100 if(*list == device)
4102 *list = (*list)->next;
4103 break;
4105 list = &(*list)->next;
4108 UnlockLists();
4110 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
4111 while(ctx != NULL)
4113 ALCcontext *next = ctx->next;
4114 WARN("Releasing context %p\n", ctx);
4115 ReleaseContext(ctx, device);
4116 ctx = next;
4118 if((device->Flags&DEVICE_RUNNING))
4119 V0(device->Backend,stop)();
4120 device->Flags &= ~DEVICE_RUNNING;
4121 almtx_unlock(&device->BackendLock);
4123 ALCdevice_DecRef(device);
4125 return ALC_TRUE;
4129 /************************************************
4130 * ALC capture functions
4131 ************************************************/
4132 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4134 ALCbackendFactory *factory;
4135 ALCdevice *device = NULL;
4136 ALCenum err;
4137 ALCsizei i;
4139 DO_INITCONFIG();
4141 if(!CaptureBackend.name)
4143 alcSetError(NULL, ALC_INVALID_VALUE);
4144 return NULL;
4147 if(samples <= 0)
4149 alcSetError(NULL, ALC_INVALID_VALUE);
4150 return NULL;
4153 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4154 deviceName = NULL;
4156 device = al_calloc(16, sizeof(ALCdevice));
4157 if(!device)
4159 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4160 return NULL;
4163 //Validate device
4164 InitRef(&device->ref, 1);
4165 device->Connected = ALC_TRUE;
4166 device->Type = Capture;
4168 device->Hrtf = NULL;
4169 device->HrtfHandle = NULL;
4170 VECTOR_INIT(device->HrtfList);
4171 AL_STRING_INIT(device->HrtfName);
4173 AL_STRING_INIT(device->DeviceName);
4174 device->Dry.Buffer = NULL;
4175 device->Dry.NumChannels = 0;
4176 device->FOAOut.Buffer = NULL;
4177 device->FOAOut.NumChannels = 0;
4178 device->RealOut.Buffer = NULL;
4179 device->RealOut.NumChannels = 0;
4181 InitUIntMap(&device->BufferMap, INT_MAX);
4182 InitUIntMap(&device->EffectMap, INT_MAX);
4183 InitUIntMap(&device->FilterMap, INT_MAX);
4185 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4187 device->ChannelDelay[i].Gain = 1.0f;
4188 device->ChannelDelay[i].Length = 0;
4189 device->ChannelDelay[i].Buffer = NULL;
4192 factory = CaptureBackend.getFactory();
4193 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4194 if(!device->Backend)
4196 al_free(device);
4197 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4198 return NULL;
4201 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4202 device->Frequency = frequency;
4204 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4205 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4207 al_free(device);
4208 alcSetError(NULL, ALC_INVALID_ENUM);
4209 return NULL;
4211 device->IsHeadphones = AL_FALSE;
4212 device->AmbiOrder = 0;
4213 device->AmbiLayout = AmbiLayout_Default;
4214 device->AmbiScale = AmbiNorm_Default;
4216 device->UpdateSize = samples;
4217 device->NumUpdates = 1;
4219 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4220 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
4221 device->Frequency, device->UpdateSize, device->NumUpdates
4223 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4225 al_free(device);
4226 alcSetError(NULL, err);
4227 return NULL;
4229 almtx_init(&device->BackendLock, almtx_plain);
4232 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4233 do {
4234 device->next = head;
4235 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4238 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4239 return device;
4242 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4244 ALCdevice *iter, *origdev;
4246 LockLists();
4247 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4248 do {
4249 if(iter == device)
4250 break;
4251 } while((iter=iter->next) != NULL);
4252 if(!iter || iter->Type != Capture)
4254 alcSetError(iter, ALC_INVALID_DEVICE);
4255 UnlockLists();
4256 return ALC_FALSE;
4259 origdev = device;
4260 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4262 ALCdevice *volatile*list = &origdev->next;
4263 while(*list)
4265 if(*list == device)
4267 *list = (*list)->next;
4268 break;
4270 list = &(*list)->next;
4273 UnlockLists();
4275 ALCdevice_DecRef(device);
4277 return ALC_TRUE;
4280 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4282 if(!VerifyDevice(&device) || device->Type != Capture)
4283 alcSetError(device, ALC_INVALID_DEVICE);
4284 else
4286 almtx_lock(&device->BackendLock);
4287 if(!device->Connected)
4288 alcSetError(device, ALC_INVALID_DEVICE);
4289 else if(!(device->Flags&DEVICE_RUNNING))
4291 if(V0(device->Backend,start)())
4292 device->Flags |= DEVICE_RUNNING;
4293 else
4295 aluHandleDisconnect(device);
4296 alcSetError(device, ALC_INVALID_DEVICE);
4299 almtx_unlock(&device->BackendLock);
4302 if(device) ALCdevice_DecRef(device);
4305 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4307 if(!VerifyDevice(&device) || device->Type != Capture)
4308 alcSetError(device, ALC_INVALID_DEVICE);
4309 else
4311 almtx_lock(&device->BackendLock);
4312 if((device->Flags&DEVICE_RUNNING))
4313 V0(device->Backend,stop)();
4314 device->Flags &= ~DEVICE_RUNNING;
4315 almtx_unlock(&device->BackendLock);
4318 if(device) ALCdevice_DecRef(device);
4321 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4323 if(!VerifyDevice(&device) || device->Type != Capture)
4324 alcSetError(device, ALC_INVALID_DEVICE);
4325 else
4327 ALCenum err = ALC_INVALID_VALUE;
4329 almtx_lock(&device->BackendLock);
4330 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4331 err = V(device->Backend,captureSamples)(buffer, samples);
4332 almtx_unlock(&device->BackendLock);
4334 if(err != ALC_NO_ERROR)
4335 alcSetError(device, err);
4337 if(device) ALCdevice_DecRef(device);
4341 /************************************************
4342 * ALC loopback functions
4343 ************************************************/
4345 /* alcLoopbackOpenDeviceSOFT
4347 * Open a loopback device, for manual rendering.
4349 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4351 ALCbackendFactory *factory;
4352 ALCdevice *device;
4353 ALCsizei i;
4355 DO_INITCONFIG();
4357 /* Make sure the device name, if specified, is us. */
4358 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4360 alcSetError(NULL, ALC_INVALID_VALUE);
4361 return NULL;
4364 device = al_calloc(16, sizeof(ALCdevice));
4365 if(!device)
4367 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4368 return NULL;
4371 //Validate device
4372 InitRef(&device->ref, 1);
4373 device->Connected = ALC_TRUE;
4374 device->Type = Loopback;
4375 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4377 device->Flags = 0;
4378 device->Hrtf = NULL;
4379 device->HrtfHandle = NULL;
4380 VECTOR_INIT(device->HrtfList);
4381 AL_STRING_INIT(device->HrtfName);
4382 device->Bs2b = NULL;
4383 device->Uhj_Encoder = NULL;
4384 device->Render_Mode = NormalRender;
4385 AL_STRING_INIT(device->DeviceName);
4386 device->Dry.Buffer = NULL;
4387 device->Dry.NumChannels = 0;
4388 device->FOAOut.Buffer = NULL;
4389 device->FOAOut.NumChannels = 0;
4390 device->RealOut.Buffer = NULL;
4391 device->RealOut.NumChannels = 0;
4392 device->Limiter = NULL;
4393 device->AvgSpeakerDist = 0.0f;
4395 ATOMIC_INIT(&device->ContextList, NULL);
4397 device->ClockBase = 0;
4398 device->SamplesDone = 0;
4400 device->SourcesMax = 256;
4401 device->AuxiliaryEffectSlotMax = 64;
4402 device->NumAuxSends = DEFAULT_SENDS;
4404 InitUIntMap(&device->BufferMap, INT_MAX);
4405 InitUIntMap(&device->EffectMap, INT_MAX);
4406 InitUIntMap(&device->FilterMap, INT_MAX);
4408 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4410 device->ChannelDelay[i].Gain = 1.0f;
4411 device->ChannelDelay[i].Length = 0;
4412 device->ChannelDelay[i].Buffer = NULL;
4415 factory = ALCloopbackFactory_getFactory();
4416 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4417 if(!device->Backend)
4419 al_free(device);
4420 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4421 return NULL;
4423 almtx_init(&device->BackendLock, almtx_plain);
4425 //Set output format
4426 device->NumUpdates = 0;
4427 device->UpdateSize = 0;
4429 device->Frequency = DEFAULT_OUTPUT_RATE;
4430 device->FmtChans = DevFmtChannelsDefault;
4431 device->FmtType = DevFmtTypeDefault;
4432 device->IsHeadphones = AL_FALSE;
4433 device->AmbiLayout = AmbiLayout_Default;
4434 device->AmbiScale = AmbiNorm_Default;
4436 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4437 if(device->SourcesMax == 0) device->SourcesMax = 256;
4439 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4440 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4442 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4443 device->NumAuxSends = clampi(
4444 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4447 device->NumStereoSources = 1;
4448 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4450 // Open the "backend"
4451 V(device->Backend,open)("Loopback");
4453 device->Limiter = CreateDeviceLimiter(device);
4456 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4457 do {
4458 device->next = head;
4459 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4462 TRACE("Created device %p\n", device);
4463 return device;
4466 /* alcIsRenderFormatSupportedSOFT
4468 * Determines if the loopback device supports the given format for rendering.
4470 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4472 ALCboolean ret = ALC_FALSE;
4474 if(!VerifyDevice(&device) || device->Type != Loopback)
4475 alcSetError(device, ALC_INVALID_DEVICE);
4476 else if(freq <= 0)
4477 alcSetError(device, ALC_INVALID_VALUE);
4478 else
4480 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4481 ret = ALC_TRUE;
4483 if(device) ALCdevice_DecRef(device);
4485 return ret;
4488 /* alcRenderSamplesSOFT
4490 * Renders some samples into a buffer, using the format last set by the
4491 * attributes given to alcCreateContext.
4493 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4495 if(!VerifyDevice(&device) || device->Type != Loopback)
4496 alcSetError(device, ALC_INVALID_DEVICE);
4497 else if(samples < 0 || (samples > 0 && buffer == NULL))
4498 alcSetError(device, ALC_INVALID_VALUE);
4499 else
4501 V0(device->Backend,lock)();
4502 aluMixData(device, buffer, samples);
4503 V0(device->Backend,unlock)();
4505 if(device) ALCdevice_DecRef(device);
4509 /************************************************
4510 * ALC loopback2 functions
4511 ************************************************/
4513 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4515 ALCboolean ret = ALC_FALSE;
4517 if(!VerifyDevice(&device) || device->Type != Loopback)
4518 alcSetError(device, ALC_INVALID_DEVICE);
4519 else if(order <= 0)
4520 alcSetError(device, ALC_INVALID_VALUE);
4521 else
4523 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4524 ret = ALC_TRUE;
4526 if(device) ALCdevice_DecRef(device);
4528 return ret;
4531 /************************************************
4532 * ALC DSP pause/resume functions
4533 ************************************************/
4535 /* alcDevicePauseSOFT
4537 * Pause the DSP to stop audio processing.
4539 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4541 if(!VerifyDevice(&device) || device->Type != Playback)
4542 alcSetError(device, ALC_INVALID_DEVICE);
4543 else
4545 almtx_lock(&device->BackendLock);
4546 if((device->Flags&DEVICE_RUNNING))
4547 V0(device->Backend,stop)();
4548 device->Flags &= ~DEVICE_RUNNING;
4549 device->Flags |= DEVICE_PAUSED;
4550 almtx_unlock(&device->BackendLock);
4552 if(device) ALCdevice_DecRef(device);
4555 /* alcDeviceResumeSOFT
4557 * Resume the DSP to restart audio processing.
4559 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4561 if(!VerifyDevice(&device) || device->Type != Playback)
4562 alcSetError(device, ALC_INVALID_DEVICE);
4563 else
4565 almtx_lock(&device->BackendLock);
4566 if((device->Flags&DEVICE_PAUSED))
4568 device->Flags &= ~DEVICE_PAUSED;
4569 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4571 if(V0(device->Backend,start)() != ALC_FALSE)
4572 device->Flags |= DEVICE_RUNNING;
4573 else
4575 alcSetError(device, ALC_INVALID_DEVICE);
4576 V0(device->Backend,lock)();
4577 aluHandleDisconnect(device);
4578 V0(device->Backend,unlock)();
4582 almtx_unlock(&device->BackendLock);
4584 if(device) ALCdevice_DecRef(device);
4588 /************************************************
4589 * ALC HRTF functions
4590 ************************************************/
4592 /* alcGetStringiSOFT
4594 * Gets a string parameter at the given index.
4596 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4598 const ALCchar *str = NULL;
4600 if(!VerifyDevice(&device) || device->Type == Capture)
4601 alcSetError(device, ALC_INVALID_DEVICE);
4602 else switch(paramName)
4604 case ALC_HRTF_SPECIFIER_SOFT:
4605 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList))
4606 str = alstr_get_cstr(VECTOR_ELEM(device->HrtfList, index).name);
4607 else
4608 alcSetError(device, ALC_INVALID_VALUE);
4609 break;
4611 default:
4612 alcSetError(device, ALC_INVALID_ENUM);
4613 break;
4615 if(device) ALCdevice_DecRef(device);
4617 return str;
4620 /* alcResetDeviceSOFT
4622 * Resets the given device output, using the specified attribute list.
4624 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4626 ALCenum err;
4628 LockLists();
4629 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4631 UnlockLists();
4632 alcSetError(device, ALC_INVALID_DEVICE);
4633 if(device) ALCdevice_DecRef(device);
4634 return ALC_FALSE;
4636 almtx_lock(&device->BackendLock);
4637 UnlockLists();
4639 err = UpdateDeviceParams(device, attribs);
4640 almtx_unlock(&device->BackendLock);
4642 if(err != ALC_NO_ERROR)
4644 alcSetError(device, err);
4645 if(err == ALC_INVALID_DEVICE)
4647 V0(device->Backend,lock)();
4648 aluHandleDisconnect(device);
4649 V0(device->Backend,unlock)();
4651 ALCdevice_DecRef(device);
4652 return ALC_FALSE;
4654 ALCdevice_DecRef(device);
4656 return ALC_TRUE;