Update ChangeLog
[openal-soft.git] / Alc / ALc.c
blob7fcac99dc28f69db1a5b89fda791932752991d2a
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 aluInit();
1005 aluInitMixer();
1007 str = getenv("ALSOFT_TRAP_ERROR");
1008 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1010 TrapALError = AL_TRUE;
1011 TrapALCError = AL_TRUE;
1013 else
1015 str = getenv("ALSOFT_TRAP_AL_ERROR");
1016 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1017 TrapALError = AL_TRUE;
1018 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
1020 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1021 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1022 TrapALCError = ALC_TRUE;
1023 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1026 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1027 ReverbBoost *= powf(10.0f, valf / 20.0f);
1029 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1031 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1032 ConfigValueStr(NULL, NULL, "drivers", &devs))
1034 int n;
1035 size_t len;
1036 const char *next = devs;
1037 int endlist, delitem;
1039 i = 0;
1040 do {
1041 devs = next;
1042 while(isspace(devs[0]))
1043 devs++;
1044 next = strchr(devs, ',');
1046 delitem = (devs[0] == '-');
1047 if(devs[0] == '-') devs++;
1049 if(!devs[0] || devs[0] == ',')
1051 endlist = 0;
1052 continue;
1054 endlist = 1;
1056 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1057 while(len > 0 && isspace(devs[len-1]))
1058 len--;
1059 for(n = i;n < BackendListSize;n++)
1061 if(len == strlen(BackendList[n].name) &&
1062 strncmp(BackendList[n].name, devs, len) == 0)
1064 if(delitem)
1066 for(;n+1 < BackendListSize;n++)
1067 BackendList[n] = BackendList[n+1];
1068 BackendListSize--;
1070 else
1072 struct BackendInfo Bkp = BackendList[n];
1073 for(;n > i;n--)
1074 BackendList[n] = BackendList[n-1];
1075 BackendList[n] = Bkp;
1077 i++;
1079 break;
1082 } while(next++);
1084 if(endlist)
1085 BackendListSize = i;
1088 for(i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1090 ALCbackendFactory *factory = BackendList[i].getFactory();
1091 if(!V0(factory,init)())
1093 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1094 continue;
1097 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1098 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1100 PlaybackBackend = BackendList[i];
1101 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1103 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1105 CaptureBackend = BackendList[i];
1106 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1110 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1111 V0(factory,init)();
1114 if(!PlaybackBackend.name)
1115 WARN("No playback backend available!\n");
1116 if(!CaptureBackend.name)
1117 WARN("No capture backend available!\n");
1119 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1121 size_t len;
1122 const char *next = str;
1124 do {
1125 str = next;
1126 next = strchr(str, ',');
1128 if(!str[0] || next == str)
1129 continue;
1131 len = (next ? ((size_t)(next-str)) : strlen(str));
1132 for(n = 0;EffectList[n].name;n++)
1134 if(len == strlen(EffectList[n].name) &&
1135 strncmp(EffectList[n].name, str, len) == 0)
1136 DisabledEffects[EffectList[n].type] = AL_TRUE;
1138 } while(next++);
1141 InitEffectFactoryMap();
1143 InitEffect(&DefaultEffect);
1144 str = getenv("ALSOFT_DEFAULT_REVERB");
1145 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1146 LoadReverbPreset(str, &DefaultEffect);
1148 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1150 #ifdef __ANDROID__
1151 #include <jni.h>
1153 static JavaVM *gJavaVM;
1154 static pthread_key_t gJVMThreadKey;
1156 static void CleanupJNIEnv(void* UNUSED(ptr))
1158 JCALL0(gJavaVM,DetachCurrentThread)();
1161 void *Android_GetJNIEnv(void)
1163 if(!gJavaVM)
1165 WARN("gJavaVM is NULL!\n");
1166 return NULL;
1169 /* http://developer.android.com/guide/practices/jni.html
1171 * All threads are Linux threads, scheduled by the kernel. They're usually
1172 * started from managed code (using Thread.start), but they can also be
1173 * created elsewhere and then attached to the JavaVM. For example, a thread
1174 * started with pthread_create can be attached with the JNI
1175 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1176 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1177 * Attaching a natively-created thread causes a java.lang.Thread object to
1178 * be constructed and added to the "main" ThreadGroup, making it visible to
1179 * the debugger. Calling AttachCurrentThread on an already-attached thread
1180 * is a no-op.
1182 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1183 if(!env)
1185 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1186 if(status < 0)
1188 ERR("Failed to attach current thread\n");
1189 return NULL;
1191 pthread_setspecific(gJVMThreadKey, env);
1193 return env;
1196 /* Automatically called by JNI. */
1197 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1199 void *env;
1200 int err;
1202 gJavaVM = jvm;
1203 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1205 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1206 return JNI_ERR;
1209 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1210 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1212 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1213 ERR("pthread_key_create failed: %d\n", err);
1214 pthread_setspecific(gJVMThreadKey, env);
1215 return JNI_VERSION_1_4;
1217 #endif
1220 /************************************************
1221 * Library deinitialization
1222 ************************************************/
1223 static void alc_cleanup(void)
1225 ALCdevice *dev;
1227 AL_STRING_DEINIT(alcAllDevicesList);
1228 AL_STRING_DEINIT(alcCaptureDeviceList);
1230 free(alcDefaultAllDevicesSpecifier);
1231 alcDefaultAllDevicesSpecifier = NULL;
1232 free(alcCaptureDefaultDeviceSpecifier);
1233 alcCaptureDefaultDeviceSpecifier = NULL;
1235 if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL)
1237 ALCuint num = 0;
1238 do {
1239 num++;
1240 } while((dev=dev->next) != NULL);
1241 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1244 DeinitEffectFactoryMap();
1247 static void alc_deinit_safe(void)
1249 alc_cleanup();
1251 FreeHrtfs();
1252 FreeALConfig();
1254 ThunkExit();
1255 almtx_destroy(&ListLock);
1256 altss_delete(LocalContext);
1258 if(LogFile != stderr)
1259 fclose(LogFile);
1260 LogFile = NULL;
1263 static void alc_deinit(void)
1265 int i;
1267 alc_cleanup();
1269 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1270 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1272 for(i = 0;i < BackendListSize;i++)
1274 ALCbackendFactory *factory = BackendList[i].getFactory();
1275 V0(factory,deinit)();
1278 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1279 V0(factory,deinit)();
1282 alc_deinit_safe();
1286 /************************************************
1287 * Device enumeration
1288 ************************************************/
1289 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1291 ALCbackendFactory *factory;
1293 DO_INITCONFIG();
1295 LockLists();
1296 alstr_clear(list);
1298 factory = backendinfo->getFactory();
1299 V(factory,probe)(type);
1301 UnlockLists();
1303 static void ProbeAllDevicesList(void)
1304 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1305 static void ProbeCaptureDeviceList(void)
1306 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1308 static void AppendDevice(const ALCchar *name, al_string *devnames)
1310 size_t len = strlen(name);
1311 if(len > 0)
1312 alstr_append_range(devnames, name, name+len+1);
1314 void AppendAllDevicesList(const ALCchar *name)
1315 { AppendDevice(name, &alcAllDevicesList); }
1316 void AppendCaptureDeviceList(const ALCchar *name)
1317 { AppendDevice(name, &alcCaptureDeviceList); }
1320 /************************************************
1321 * Device format information
1322 ************************************************/
1323 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1325 switch(type)
1327 case DevFmtByte: return "Signed Byte";
1328 case DevFmtUByte: return "Unsigned Byte";
1329 case DevFmtShort: return "Signed Short";
1330 case DevFmtUShort: return "Unsigned Short";
1331 case DevFmtInt: return "Signed Int";
1332 case DevFmtUInt: return "Unsigned Int";
1333 case DevFmtFloat: return "Float";
1335 return "(unknown type)";
1337 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1339 switch(chans)
1341 case DevFmtMono: return "Mono";
1342 case DevFmtStereo: return "Stereo";
1343 case DevFmtQuad: return "Quadraphonic";
1344 case DevFmtX51: return "5.1 Surround";
1345 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1346 case DevFmtX61: return "6.1 Surround";
1347 case DevFmtX71: return "7.1 Surround";
1348 case DevFmtAmbi3D: return "Ambisonic 3D";
1350 return "(unknown channels)";
1353 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder);
1354 ALsizei BytesFromDevFmt(enum DevFmtType type)
1356 switch(type)
1358 case DevFmtByte: return sizeof(ALbyte);
1359 case DevFmtUByte: return sizeof(ALubyte);
1360 case DevFmtShort: return sizeof(ALshort);
1361 case DevFmtUShort: return sizeof(ALushort);
1362 case DevFmtInt: return sizeof(ALint);
1363 case DevFmtUInt: return sizeof(ALuint);
1364 case DevFmtFloat: return sizeof(ALfloat);
1366 return 0;
1368 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder)
1370 switch(chans)
1372 case DevFmtMono: return 1;
1373 case DevFmtStereo: return 2;
1374 case DevFmtQuad: return 4;
1375 case DevFmtX51: return 6;
1376 case DevFmtX51Rear: return 6;
1377 case DevFmtX61: return 7;
1378 case DevFmtX71: return 8;
1379 case DevFmtAmbi3D: return (ambiorder >= 3) ? 16 :
1380 (ambiorder == 2) ? 9 :
1381 (ambiorder == 1) ? 4 : 1;
1383 return 0;
1386 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1387 enum DevFmtType *type)
1389 static const struct {
1390 ALenum format;
1391 enum DevFmtChannels channels;
1392 enum DevFmtType type;
1393 } list[] = {
1394 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1395 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1396 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1398 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1399 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1400 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1402 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1403 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1404 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1406 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1407 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1408 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1410 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1411 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1412 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1414 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1415 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1416 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1418 ALuint i;
1420 for(i = 0;i < COUNTOF(list);i++)
1422 if(list[i].format == format)
1424 *chans = list[i].channels;
1425 *type = list[i].type;
1426 return AL_TRUE;
1430 return AL_FALSE;
1433 static ALCboolean IsValidALCType(ALCenum type)
1435 switch(type)
1437 case ALC_BYTE_SOFT:
1438 case ALC_UNSIGNED_BYTE_SOFT:
1439 case ALC_SHORT_SOFT:
1440 case ALC_UNSIGNED_SHORT_SOFT:
1441 case ALC_INT_SOFT:
1442 case ALC_UNSIGNED_INT_SOFT:
1443 case ALC_FLOAT_SOFT:
1444 return ALC_TRUE;
1446 return ALC_FALSE;
1449 static ALCboolean IsValidALCChannels(ALCenum channels)
1451 switch(channels)
1453 case ALC_MONO_SOFT:
1454 case ALC_STEREO_SOFT:
1455 case ALC_QUAD_SOFT:
1456 case ALC_5POINT1_SOFT:
1457 case ALC_6POINT1_SOFT:
1458 case ALC_7POINT1_SOFT:
1459 case ALC_BFORMAT3D_SOFT:
1460 return ALC_TRUE;
1462 return ALC_FALSE;
1465 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1467 switch(layout)
1469 case ALC_ACN_SOFT:
1470 case ALC_FUMA_SOFT:
1471 return ALC_TRUE;
1473 return ALC_FALSE;
1476 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1478 switch(scaling)
1480 case ALC_N3D_SOFT:
1481 case ALC_SN3D_SOFT:
1482 case ALC_FUMA_SOFT:
1483 return ALC_TRUE;
1485 return ALC_FALSE;
1488 /************************************************
1489 * Miscellaneous ALC helpers
1490 ************************************************/
1492 void ALCdevice_Lock(ALCdevice *device)
1494 V0(device->Backend,lock)();
1497 void ALCdevice_Unlock(ALCdevice *device)
1499 V0(device->Backend,unlock)();
1503 /* SetDefaultWFXChannelOrder
1505 * Sets the default channel order used by WaveFormatEx.
1507 void SetDefaultWFXChannelOrder(ALCdevice *device)
1509 ALsizei i;
1511 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1512 device->RealOut.ChannelName[i] = InvalidChannel;
1514 switch(device->FmtChans)
1516 case DevFmtMono:
1517 device->RealOut.ChannelName[0] = FrontCenter;
1518 break;
1519 case DevFmtStereo:
1520 device->RealOut.ChannelName[0] = FrontLeft;
1521 device->RealOut.ChannelName[1] = FrontRight;
1522 break;
1523 case DevFmtQuad:
1524 device->RealOut.ChannelName[0] = FrontLeft;
1525 device->RealOut.ChannelName[1] = FrontRight;
1526 device->RealOut.ChannelName[2] = BackLeft;
1527 device->RealOut.ChannelName[3] = BackRight;
1528 break;
1529 case DevFmtX51:
1530 device->RealOut.ChannelName[0] = FrontLeft;
1531 device->RealOut.ChannelName[1] = FrontRight;
1532 device->RealOut.ChannelName[2] = FrontCenter;
1533 device->RealOut.ChannelName[3] = LFE;
1534 device->RealOut.ChannelName[4] = SideLeft;
1535 device->RealOut.ChannelName[5] = SideRight;
1536 break;
1537 case DevFmtX51Rear:
1538 device->RealOut.ChannelName[0] = FrontLeft;
1539 device->RealOut.ChannelName[1] = FrontRight;
1540 device->RealOut.ChannelName[2] = FrontCenter;
1541 device->RealOut.ChannelName[3] = LFE;
1542 device->RealOut.ChannelName[4] = BackLeft;
1543 device->RealOut.ChannelName[5] = BackRight;
1544 break;
1545 case DevFmtX61:
1546 device->RealOut.ChannelName[0] = FrontLeft;
1547 device->RealOut.ChannelName[1] = FrontRight;
1548 device->RealOut.ChannelName[2] = FrontCenter;
1549 device->RealOut.ChannelName[3] = LFE;
1550 device->RealOut.ChannelName[4] = BackCenter;
1551 device->RealOut.ChannelName[5] = SideLeft;
1552 device->RealOut.ChannelName[6] = SideRight;
1553 break;
1554 case DevFmtX71:
1555 device->RealOut.ChannelName[0] = FrontLeft;
1556 device->RealOut.ChannelName[1] = FrontRight;
1557 device->RealOut.ChannelName[2] = FrontCenter;
1558 device->RealOut.ChannelName[3] = LFE;
1559 device->RealOut.ChannelName[4] = BackLeft;
1560 device->RealOut.ChannelName[5] = BackRight;
1561 device->RealOut.ChannelName[6] = SideLeft;
1562 device->RealOut.ChannelName[7] = SideRight;
1563 break;
1564 case DevFmtAmbi3D:
1565 device->RealOut.ChannelName[0] = Aux0;
1566 if(device->AmbiOrder > 0)
1568 device->RealOut.ChannelName[1] = Aux1;
1569 device->RealOut.ChannelName[2] = Aux2;
1570 device->RealOut.ChannelName[3] = Aux3;
1572 if(device->AmbiOrder > 1)
1574 device->RealOut.ChannelName[4] = Aux4;
1575 device->RealOut.ChannelName[5] = Aux5;
1576 device->RealOut.ChannelName[6] = Aux6;
1577 device->RealOut.ChannelName[7] = Aux7;
1578 device->RealOut.ChannelName[8] = Aux8;
1580 if(device->AmbiOrder > 2)
1582 device->RealOut.ChannelName[9] = Aux9;
1583 device->RealOut.ChannelName[10] = Aux10;
1584 device->RealOut.ChannelName[11] = Aux11;
1585 device->RealOut.ChannelName[12] = Aux12;
1586 device->RealOut.ChannelName[13] = Aux13;
1587 device->RealOut.ChannelName[14] = Aux14;
1588 device->RealOut.ChannelName[15] = Aux15;
1590 break;
1594 /* SetDefaultChannelOrder
1596 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1598 void SetDefaultChannelOrder(ALCdevice *device)
1600 ALsizei i;
1602 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1603 device->RealOut.ChannelName[i] = InvalidChannel;
1605 switch(device->FmtChans)
1607 case DevFmtX51Rear:
1608 device->RealOut.ChannelName[0] = FrontLeft;
1609 device->RealOut.ChannelName[1] = FrontRight;
1610 device->RealOut.ChannelName[2] = BackLeft;
1611 device->RealOut.ChannelName[3] = BackRight;
1612 device->RealOut.ChannelName[4] = FrontCenter;
1613 device->RealOut.ChannelName[5] = LFE;
1614 return;
1615 case DevFmtX71:
1616 device->RealOut.ChannelName[0] = FrontLeft;
1617 device->RealOut.ChannelName[1] = FrontRight;
1618 device->RealOut.ChannelName[2] = BackLeft;
1619 device->RealOut.ChannelName[3] = BackRight;
1620 device->RealOut.ChannelName[4] = FrontCenter;
1621 device->RealOut.ChannelName[5] = LFE;
1622 device->RealOut.ChannelName[6] = SideLeft;
1623 device->RealOut.ChannelName[7] = SideRight;
1624 return;
1626 /* Same as WFX order */
1627 case DevFmtMono:
1628 case DevFmtStereo:
1629 case DevFmtQuad:
1630 case DevFmtX51:
1631 case DevFmtX61:
1632 case DevFmtAmbi3D:
1633 SetDefaultWFXChannelOrder(device);
1634 break;
1638 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1641 /* ALCcontext_DeferUpdates
1643 * Defers/suspends updates for the given context's listener and sources. This
1644 * does *NOT* stop mixing, but rather prevents certain property changes from
1645 * taking effect.
1647 void ALCcontext_DeferUpdates(ALCcontext *context)
1649 ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE);
1652 /* ALCcontext_ProcessUpdates
1654 * Resumes update processing after being deferred.
1656 void ALCcontext_ProcessUpdates(ALCcontext *context)
1658 ReadLock(&context->PropLock);
1659 if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE))
1661 /* Tell the mixer to stop applying updates, then wait for any active
1662 * updating to finish, before providing updates.
1664 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1665 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1666 althrd_yield();
1668 UpdateListenerProps(context);
1669 UpdateAllEffectSlotProps(context);
1670 UpdateAllSourceProps(context);
1672 /* Now with all updates declared, let the mixer continue applying them
1673 * so they all happen at once.
1675 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1677 ReadUnlock(&context->PropLock);
1681 /* alcSetError
1683 * Stores the latest ALC device error
1685 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1687 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1688 if(TrapALCError)
1690 #ifdef _WIN32
1691 /* DebugBreak() will cause an exception if there is no debugger */
1692 if(IsDebuggerPresent())
1693 DebugBreak();
1694 #elif defined(SIGTRAP)
1695 raise(SIGTRAP);
1696 #endif
1699 if(device)
1700 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1701 else
1702 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1706 struct Compressor *CreateDeviceLimiter(const ALCdevice *device)
1708 return CompressorInit(0.0f, 0.0f, AL_FALSE, AL_TRUE, 0.0f, 0.0f, 0.5f, 2.0f,
1709 0.0f, -3.0f, 3.0f, device->Frequency);
1712 /* UpdateClockBase
1714 * Updates the device's base clock time with however many samples have been
1715 * done. This is used so frequency changes on the device don't cause the time
1716 * to jump forward or back. Must not be called while the device is running/
1717 * mixing.
1719 static inline void UpdateClockBase(ALCdevice *device)
1721 IncrementRef(&device->MixCount);
1722 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1723 device->SamplesDone = 0;
1724 IncrementRef(&device->MixCount);
1727 /* UpdateDeviceParams
1729 * Updates device parameters according to the attribute list (caller is
1730 * responsible for holding the list lock).
1732 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1734 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1735 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1736 ALCenum gainLimiter = device->Limiter ? ALC_TRUE : ALC_FALSE;
1737 const ALsizei old_sends = device->NumAuxSends;
1738 ALsizei new_sends = device->NumAuxSends;
1739 enum DevFmtChannels oldChans;
1740 enum DevFmtType oldType;
1741 ALboolean update_failed;
1742 ALCsizei hrtf_id = -1;
1743 ALCcontext *context;
1744 ALCuint oldFreq;
1745 size_t size;
1746 ALCsizei i;
1747 int val;
1749 // Check for attributes
1750 if(device->Type == Loopback)
1752 ALCsizei numMono, numStereo, numSends;
1753 ALCenum alayout = AL_NONE;
1754 ALCenum ascale = AL_NONE;
1755 ALCenum schans = AL_NONE;
1756 ALCenum stype = AL_NONE;
1757 ALCsizei attrIdx = 0;
1758 ALCsizei aorder = 0;
1759 ALCuint freq = 0;
1761 if(!attrList)
1763 WARN("Missing attributes for loopback device\n");
1764 return ALC_INVALID_VALUE;
1767 numMono = device->NumMonoSources;
1768 numStereo = device->NumStereoSources;
1769 numSends = old_sends;
1771 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1772 while(attrList[attrIdx])
1774 switch(attrList[attrIdx])
1776 case ALC_FORMAT_CHANNELS_SOFT:
1777 schans = attrList[attrIdx + 1];
1778 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1779 if(!IsValidALCChannels(schans))
1780 return ALC_INVALID_VALUE;
1781 break;
1783 case ALC_FORMAT_TYPE_SOFT:
1784 stype = attrList[attrIdx + 1];
1785 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1786 if(!IsValidALCType(stype))
1787 return ALC_INVALID_VALUE;
1788 break;
1790 case ALC_FREQUENCY:
1791 freq = attrList[attrIdx + 1];
1792 TRACE_ATTR(ALC_FREQUENCY, freq);
1793 if(freq < MIN_OUTPUT_RATE)
1794 return ALC_INVALID_VALUE;
1795 break;
1797 case ALC_AMBISONIC_LAYOUT_SOFT:
1798 alayout = attrList[attrIdx + 1];
1799 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1800 if(!IsValidAmbiLayout(alayout))
1801 return ALC_INVALID_VALUE;
1802 break;
1804 case ALC_AMBISONIC_SCALING_SOFT:
1805 ascale = attrList[attrIdx + 1];
1806 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1807 if(!IsValidAmbiScaling(ascale))
1808 return ALC_INVALID_VALUE;
1809 break;
1811 case ALC_AMBISONIC_ORDER_SOFT:
1812 aorder = attrList[attrIdx + 1];
1813 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1814 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1815 return ALC_INVALID_VALUE;
1816 break;
1818 case ALC_MONO_SOURCES:
1819 numMono = attrList[attrIdx + 1];
1820 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1821 numMono = maxi(numMono, 0);
1822 break;
1824 case ALC_STEREO_SOURCES:
1825 numStereo = attrList[attrIdx + 1];
1826 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1827 numStereo = maxi(numStereo, 0);
1828 break;
1830 case ALC_MAX_AUXILIARY_SENDS:
1831 numSends = attrList[attrIdx + 1];
1832 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1833 numSends = clampi(numSends, 0, MAX_SENDS);
1834 break;
1836 case ALC_HRTF_SOFT:
1837 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1838 if(attrList[attrIdx + 1] == ALC_FALSE)
1839 hrtf_appreq = Hrtf_Disable;
1840 else if(attrList[attrIdx + 1] == ALC_TRUE)
1841 hrtf_appreq = Hrtf_Enable;
1842 else
1843 hrtf_appreq = Hrtf_Default;
1844 break;
1846 case ALC_HRTF_ID_SOFT:
1847 hrtf_id = attrList[attrIdx + 1];
1848 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1849 break;
1851 case ALC_OUTPUT_LIMITER_SOFT:
1852 gainLimiter = attrList[attrIdx + 1];
1853 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1854 break;
1856 default:
1857 TRACE("Loopback 0x%04X = %d (0x%x)\n", attrList[attrIdx],
1858 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1859 break;
1862 attrIdx += 2;
1864 #undef TRACE_ATTR
1866 if(!schans || !stype || !freq)
1868 WARN("Missing format for loopback device\n");
1869 return ALC_INVALID_VALUE;
1871 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1873 WARN("Missing ambisonic info for loopback device\n");
1874 return ALC_INVALID_VALUE;
1877 if((device->Flags&DEVICE_RUNNING))
1878 V0(device->Backend,stop)();
1879 device->Flags &= ~DEVICE_RUNNING;
1881 UpdateClockBase(device);
1883 device->Frequency = freq;
1884 device->FmtChans = schans;
1885 device->FmtType = stype;
1886 if(schans == ALC_BFORMAT3D_SOFT)
1888 device->AmbiOrder = aorder;
1889 device->AmbiLayout = alayout;
1890 device->AmbiScale = ascale;
1893 if(numMono > INT_MAX-numStereo)
1894 numMono = INT_MAX-numStereo;
1895 numMono += numStereo;
1896 if(ConfigValueInt(NULL, NULL, "sources", &numMono))
1898 if(numMono <= 0)
1899 numMono = 256;
1901 else
1902 numMono = maxi(numMono, 256);
1903 numStereo = mini(numStereo, numMono);
1904 numMono -= numStereo;
1905 device->SourcesMax = numMono + numStereo;
1907 device->NumMonoSources = numMono;
1908 device->NumStereoSources = numStereo;
1910 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1911 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1912 else
1913 new_sends = numSends;
1915 else if(attrList && attrList[0])
1917 ALCsizei numMono, numStereo, numSends;
1918 ALCsizei attrIdx = 0;
1919 ALCuint freq;
1921 /* If a context is already running on the device, stop playback so the
1922 * device attributes can be updated. */
1923 if((device->Flags&DEVICE_RUNNING))
1924 V0(device->Backend,stop)();
1925 device->Flags &= ~DEVICE_RUNNING;
1927 UpdateClockBase(device);
1929 freq = device->Frequency;
1930 numMono = device->NumMonoSources;
1931 numStereo = device->NumStereoSources;
1932 numSends = old_sends;
1934 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1935 while(attrList[attrIdx])
1937 switch(attrList[attrIdx])
1939 case ALC_FREQUENCY:
1940 freq = attrList[attrIdx + 1];
1941 TRACE_ATTR(ALC_FREQUENCY, freq);
1942 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1943 break;
1945 case ALC_MONO_SOURCES:
1946 numMono = attrList[attrIdx + 1];
1947 TRACE_ATTR(ALC_MONO_SOURCES, numMono);
1948 numMono = maxi(numMono, 0);
1949 break;
1951 case ALC_STEREO_SOURCES:
1952 numStereo = attrList[attrIdx + 1];
1953 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1954 numStereo = maxi(numStereo, 0);
1955 break;
1957 case ALC_MAX_AUXILIARY_SENDS:
1958 numSends = attrList[attrIdx + 1];
1959 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1960 numSends = clampi(numSends, 0, MAX_SENDS);
1961 break;
1963 case ALC_HRTF_SOFT:
1964 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1965 if(attrList[attrIdx + 1] == ALC_FALSE)
1966 hrtf_appreq = Hrtf_Disable;
1967 else if(attrList[attrIdx + 1] == ALC_TRUE)
1968 hrtf_appreq = Hrtf_Enable;
1969 else
1970 hrtf_appreq = Hrtf_Default;
1971 break;
1973 case ALC_HRTF_ID_SOFT:
1974 hrtf_id = attrList[attrIdx + 1];
1975 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1976 break;
1978 case ALC_OUTPUT_LIMITER_SOFT:
1979 gainLimiter = attrList[attrIdx + 1];
1980 TRACE_ATTR(ALC_OUTPUT_LIMITER_SOFT, gainLimiter);
1981 break;
1983 default:
1984 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
1985 attrList[attrIdx + 1], attrList[attrIdx + 1]);
1986 break;
1989 attrIdx += 2;
1991 #undef TRACE_ATTR
1993 ConfigValueUInt(alstr_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1994 freq = maxu(freq, MIN_OUTPUT_RATE);
1996 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1997 device->Frequency;
1998 /* SSE and Neon do best with the update size being a multiple of 4 */
1999 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2000 device->UpdateSize = (device->UpdateSize+3)&~3;
2002 device->Frequency = freq;
2004 if(numMono > INT_MAX-numStereo)
2005 numMono = INT_MAX-numStereo;
2006 numMono += numStereo;
2007 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono))
2009 if(numMono <= 0)
2010 numMono = 256;
2012 else
2013 numMono = maxi(numMono, 256);
2014 numStereo = mini(numStereo, numMono);
2015 numMono -= numStereo;
2016 device->SourcesMax = numMono + numStereo;
2018 device->NumMonoSources = numMono;
2019 device->NumStereoSources = numStereo;
2021 if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2022 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2023 else
2024 new_sends = numSends;
2027 if((device->Flags&DEVICE_RUNNING))
2028 return ALC_NO_ERROR;
2030 al_free(device->Uhj_Encoder);
2031 device->Uhj_Encoder = NULL;
2033 al_free(device->Bs2b);
2034 device->Bs2b = NULL;
2036 al_free(device->ChannelDelay[0].Buffer);
2037 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2039 device->ChannelDelay[i].Length = 0;
2040 device->ChannelDelay[i].Buffer = NULL;
2043 al_free(device->Dry.Buffer);
2044 device->Dry.Buffer = NULL;
2045 device->Dry.NumChannels = 0;
2046 device->FOAOut.Buffer = NULL;
2047 device->FOAOut.NumChannels = 0;
2048 device->RealOut.Buffer = NULL;
2049 device->RealOut.NumChannels = 0;
2051 UpdateClockBase(device);
2053 device->DitherSeed = DITHER_RNG_SEED;
2055 /*************************************************************************
2056 * Update device format request if HRTF is requested
2058 device->HrtfStatus = ALC_HRTF_DISABLED_SOFT;
2059 if(device->Type != Loopback)
2061 const char *hrtf;
2062 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2064 if(strcasecmp(hrtf, "true") == 0)
2065 hrtf_userreq = Hrtf_Enable;
2066 else if(strcasecmp(hrtf, "false") == 0)
2067 hrtf_userreq = Hrtf_Disable;
2068 else if(strcasecmp(hrtf, "auto") != 0)
2069 ERR("Unexpected hrtf value: %s\n", hrtf);
2072 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2074 struct Hrtf *hrtf = NULL;
2075 if(VECTOR_SIZE(device->HrtfList) == 0)
2077 VECTOR_DEINIT(device->HrtfList);
2078 device->HrtfList = EnumerateHrtf(device->DeviceName);
2080 if(VECTOR_SIZE(device->HrtfList) > 0)
2082 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
2083 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
2084 else
2085 hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
2088 if(hrtf)
2090 device->FmtChans = DevFmtStereo;
2091 device->Frequency = hrtf->sampleRate;
2092 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2093 if(device->HrtfHandle)
2094 Hrtf_DecRef(device->HrtfHandle);
2095 device->HrtfHandle = hrtf;
2097 else
2099 hrtf_userreq = Hrtf_Default;
2100 hrtf_appreq = Hrtf_Disable;
2101 device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2106 oldFreq = device->Frequency;
2107 oldChans = device->FmtChans;
2108 oldType = device->FmtType;
2110 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2111 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2112 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2113 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2114 device->UpdateSize, device->NumUpdates
2117 if(V0(device->Backend,reset)() == ALC_FALSE)
2118 return ALC_INVALID_DEVICE;
2120 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2122 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2123 DevFmtChannelsString(device->FmtChans));
2124 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2126 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2128 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2129 DevFmtTypeString(device->FmtType));
2130 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2132 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2134 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2135 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2138 if((device->UpdateSize&3) != 0)
2140 if((CPUCapFlags&CPU_CAP_SSE))
2141 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2142 if((CPUCapFlags&CPU_CAP_NEON))
2143 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2146 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2147 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2148 device->Frequency, device->UpdateSize, device->NumUpdates
2151 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2152 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2153 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2155 /* Allocate extra channels for any post-filter output. */
2156 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2157 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2159 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2160 device->Dry.Buffer = al_calloc(16, size);
2161 if(!device->Dry.Buffer)
2163 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2164 return ALC_INVALID_DEVICE;
2167 if(device->RealOut.NumChannels != 0)
2168 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2169 device->FOAOut.NumChannels;
2170 else
2172 device->RealOut.Buffer = device->Dry.Buffer;
2173 device->RealOut.NumChannels = device->Dry.NumChannels;
2176 if(device->FOAOut.NumChannels != 0)
2177 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2178 else
2180 device->FOAOut.Buffer = device->Dry.Buffer;
2181 device->FOAOut.NumChannels = device->Dry.NumChannels;
2184 device->NumAuxSends = new_sends;
2185 TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2186 device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2187 device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2189 device->DitherDepth = 0.0f;
2190 if(GetConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "dither", 1))
2192 ALint depth = 0;
2193 ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "dither-depth", &depth);
2194 if(depth <= 0)
2196 switch(device->FmtType)
2198 case DevFmtByte:
2199 case DevFmtUByte:
2200 depth = 8;
2201 break;
2202 case DevFmtShort:
2203 case DevFmtUShort:
2204 depth = 16;
2205 break;
2206 case DevFmtInt:
2207 case DevFmtUInt:
2208 case DevFmtFloat:
2209 break;
2212 else if(depth > 24)
2213 depth = 24;
2214 device->DitherDepth = (depth > 0) ? powf(2.0f, (ALfloat)(depth-1)) : 0.0f;
2216 if(!(device->DitherDepth > 0.0f))
2217 TRACE("Dithering disabled\n");
2218 else
2219 TRACE("Dithering enabled (%g-bit, %g)\n", log2f(device->DitherDepth)+1.0f,
2220 device->DitherDepth);
2222 if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
2223 gainLimiter = val ? ALC_TRUE : ALC_FALSE;
2224 /* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
2225 * ALC_FALSE. We default to on, so ALC_DONT_CARE_SOFT is the same as
2226 * ALC_TRUE.
2228 if(gainLimiter != ALC_FALSE)
2230 if(!device->Limiter || device->Frequency != GetCompressorSampleRate(device->Limiter))
2232 al_free(device->Limiter);
2233 device->Limiter = CreateDeviceLimiter(device);
2236 else
2238 al_free(device->Limiter);
2239 device->Limiter = NULL;
2241 TRACE("Output limiter %s\n", device->Limiter ? "enabled" : "disabled");
2243 /* Need to delay returning failure until replacement Send arrays have been
2244 * allocated with the appropriate size.
2246 update_failed = AL_FALSE;
2247 START_MIXER_MODE();
2248 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2249 while(context)
2251 ALsizei pos;
2253 if(context->DefaultSlot)
2255 ALeffectslot *slot = context->DefaultSlot;
2256 ALeffectState *state = slot->Effect.State;
2258 state->OutBuffer = device->Dry.Buffer;
2259 state->OutChannels = device->Dry.NumChannels;
2260 if(V(state,deviceUpdate)(device) == AL_FALSE)
2261 update_failed = AL_TRUE;
2262 else
2263 UpdateEffectSlotProps(slot);
2266 WriteLock(&context->PropLock);
2267 LockUIntMapRead(&context->EffectSlotMap);
2268 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2270 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2271 ALeffectState *state = slot->Effect.State;
2273 state->OutBuffer = device->Dry.Buffer;
2274 state->OutChannels = device->Dry.NumChannels;
2275 if(V(state,deviceUpdate)(device) == AL_FALSE)
2276 update_failed = AL_TRUE;
2277 else
2278 UpdateEffectSlotProps(slot);
2280 UnlockUIntMapRead(&context->EffectSlotMap);
2282 LockUIntMapRead(&context->SourceMap);
2283 RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax);
2284 for(pos = 0;pos < context->SourceMap.size;pos++)
2286 ALsource *source = context->SourceMap.values[pos];
2288 if(old_sends != device->NumAuxSends)
2290 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2291 ALsizei s;
2293 memcpy(sends, source->Send,
2294 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2296 for(s = device->NumAuxSends;s < old_sends;s++)
2298 if(source->Send[s].Slot)
2299 DecrementRef(&source->Send[s].Slot->ref);
2300 source->Send[s].Slot = NULL;
2302 al_free(source->Send);
2303 source->Send = sends;
2304 for(s = old_sends;s < device->NumAuxSends;s++)
2306 source->Send[s].Slot = NULL;
2307 source->Send[s].Gain = 1.0f;
2308 source->Send[s].GainHF = 1.0f;
2309 source->Send[s].HFReference = LOWPASSFREQREF;
2310 source->Send[s].GainLF = 1.0f;
2311 source->Send[s].LFReference = HIGHPASSFREQREF;
2315 ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
2317 AllocateVoices(context, context->MaxVoices, old_sends);
2318 for(pos = 0;pos < context->VoiceCount;pos++)
2320 ALvoice *voice = context->Voices[pos];
2321 struct ALvoiceProps *props;
2323 /* Clear any pre-existing voice property structs, in case the
2324 * number of auxiliary sends changed. Active sources will have
2325 * updates respecified in UpdateAllSourceProps.
2327 props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed);
2328 al_free(props);
2330 props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
2331 while(props)
2333 struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
2334 al_free(props);
2335 props = next;
2338 if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
2339 continue;
2341 if(device->AvgSpeakerDist > 0.0f)
2343 /* Reinitialize the NFC filters for new parameters. */
2344 ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
2345 (device->AvgSpeakerDist * device->Frequency);
2346 for(i = 0;i < voice->NumChannels;i++)
2348 NfcFilterCreate1(&voice->Direct.Params[i].NFCtrlFilter[0], 0.0f, w1);
2349 NfcFilterCreate2(&voice->Direct.Params[i].NFCtrlFilter[1], 0.0f, w1);
2350 NfcFilterCreate3(&voice->Direct.Params[i].NFCtrlFilter[2], 0.0f, w1);
2354 UnlockUIntMapRead(&context->SourceMap);
2356 UpdateListenerProps(context);
2357 UpdateAllSourceProps(context);
2358 WriteUnlock(&context->PropLock);
2360 context = context->next;
2362 END_MIXER_MODE();
2363 if(update_failed)
2364 return ALC_INVALID_DEVICE;
2366 if(!(device->Flags&DEVICE_PAUSED))
2368 if(V0(device->Backend,start)() == ALC_FALSE)
2369 return ALC_INVALID_DEVICE;
2370 device->Flags |= DEVICE_RUNNING;
2373 return ALC_NO_ERROR;
2376 /* FreeDevice
2378 * Frees the device structure, and destroys any objects the app failed to
2379 * delete. Called once there's no more references on the device.
2381 static ALCvoid FreeDevice(ALCdevice *device)
2383 ALsizei i;
2385 TRACE("%p\n", device);
2387 V0(device->Backend,close)();
2388 DELETE_OBJ(device->Backend);
2389 device->Backend = NULL;
2391 almtx_destroy(&device->BackendLock);
2393 if(device->BufferMap.size > 0)
2395 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2396 (device->BufferMap.size==1)?"":"s");
2397 ReleaseALBuffers(device);
2399 ResetUIntMap(&device->BufferMap);
2401 if(device->EffectMap.size > 0)
2403 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2404 (device->EffectMap.size==1)?"":"s");
2405 ReleaseALEffects(device);
2407 ResetUIntMap(&device->EffectMap);
2409 if(device->FilterMap.size > 0)
2411 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2412 (device->FilterMap.size==1)?"":"s");
2413 ReleaseALFilters(device);
2415 ResetUIntMap(&device->FilterMap);
2417 AL_STRING_DEINIT(device->HrtfName);
2418 FreeHrtfList(&device->HrtfList);
2419 if(device->HrtfHandle)
2420 Hrtf_DecRef(device->HrtfHandle);
2421 device->HrtfHandle = NULL;
2422 al_free(device->Hrtf);
2423 device->Hrtf = NULL;
2425 al_free(device->Bs2b);
2426 device->Bs2b = NULL;
2428 al_free(device->Uhj_Encoder);
2429 device->Uhj_Encoder = NULL;
2431 bformatdec_free(device->AmbiDecoder);
2432 device->AmbiDecoder = NULL;
2434 ambiup_free(device->AmbiUp);
2435 device->AmbiUp = NULL;
2437 al_free(device->Stablizer);
2438 device->Stablizer = NULL;
2440 al_free(device->Limiter);
2441 device->Limiter = NULL;
2443 al_free(device->ChannelDelay[0].Buffer);
2444 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2446 device->ChannelDelay[i].Gain = 1.0f;
2447 device->ChannelDelay[i].Length = 0;
2448 device->ChannelDelay[i].Buffer = NULL;
2451 AL_STRING_DEINIT(device->DeviceName);
2453 al_free(device->Dry.Buffer);
2454 device->Dry.Buffer = NULL;
2455 device->Dry.NumChannels = 0;
2456 device->FOAOut.Buffer = NULL;
2457 device->FOAOut.NumChannels = 0;
2458 device->RealOut.Buffer = NULL;
2459 device->RealOut.NumChannels = 0;
2461 al_free(device);
2465 void ALCdevice_IncRef(ALCdevice *device)
2467 uint ref;
2468 ref = IncrementRef(&device->ref);
2469 TRACEREF("%p increasing refcount to %u\n", device, ref);
2472 void ALCdevice_DecRef(ALCdevice *device)
2474 uint ref;
2475 ref = DecrementRef(&device->ref);
2476 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2477 if(ref == 0) FreeDevice(device);
2480 /* VerifyDevice
2482 * Checks if the device handle is valid, and increments its ref count if so.
2484 static ALCboolean VerifyDevice(ALCdevice **device)
2486 ALCdevice *tmpDevice;
2488 LockLists();
2489 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2490 while(tmpDevice)
2492 if(tmpDevice == *device)
2494 ALCdevice_IncRef(tmpDevice);
2495 UnlockLists();
2496 return ALC_TRUE;
2498 tmpDevice = tmpDevice->next;
2500 UnlockLists();
2502 *device = NULL;
2503 return ALC_FALSE;
2507 /* InitContext
2509 * Initializes context fields
2511 static ALvoid InitContext(ALCcontext *Context)
2513 ALlistener *listener = Context->Listener;
2514 struct ALeffectslotArray *auxslots;
2516 //Initialise listener
2517 listener->Gain = 1.0f;
2518 listener->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT;
2519 listener->Position[0] = 0.0f;
2520 listener->Position[1] = 0.0f;
2521 listener->Position[2] = 0.0f;
2522 listener->Velocity[0] = 0.0f;
2523 listener->Velocity[1] = 0.0f;
2524 listener->Velocity[2] = 0.0f;
2525 listener->Forward[0] = 0.0f;
2526 listener->Forward[1] = 0.0f;
2527 listener->Forward[2] = -1.0f;
2528 listener->Up[0] = 0.0f;
2529 listener->Up[1] = 1.0f;
2530 listener->Up[2] = 0.0f;
2532 aluMatrixfSet(&listener->Params.Matrix,
2533 1.0f, 0.0f, 0.0f, 0.0f,
2534 0.0f, 1.0f, 0.0f, 0.0f,
2535 0.0f, 0.0f, 1.0f, 0.0f,
2536 0.0f, 0.0f, 0.0f, 1.0f
2538 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2539 listener->Params.Gain = 1.0f;
2540 listener->Params.MetersPerUnit = listener->MetersPerUnit;
2541 listener->Params.DopplerFactor = 1.0f;
2542 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2544 ATOMIC_INIT(&listener->Update, NULL);
2545 ATOMIC_INIT(&listener->FreeList, NULL);
2547 //Validate Context
2548 InitRef(&Context->UpdateCount, 0);
2549 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2550 Context->GainBoost = 1.0f;
2551 RWLockInit(&Context->PropLock);
2552 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2553 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2554 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2556 if(Context->DefaultSlot)
2558 auxslots = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, 1));
2559 auxslots->count = 1;
2560 auxslots->slot[0] = Context->DefaultSlot;
2562 else
2564 auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray));
2565 auxslots->count = 0;
2567 ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots);
2569 //Set globals
2570 Context->DistanceModel = DefaultDistanceModel;
2571 Context->SourceDistanceModel = AL_FALSE;
2572 Context->DopplerFactor = 1.0f;
2573 Context->DopplerVelocity = 1.0f;
2574 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2575 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2577 Context->ExtensionList = alExtList;
2581 /* FreeContext
2583 * Cleans up the context, and destroys any remaining objects the app failed to
2584 * delete. Called once there's no more references on the context.
2586 static void FreeContext(ALCcontext *context)
2588 ALlistener *listener = context->Listener;
2589 struct ALeffectslotArray *auxslots;
2590 struct ALlistenerProps *lprops;
2591 size_t count;
2592 ALsizei i;
2594 TRACE("%p\n", context);
2596 if(context->DefaultSlot)
2598 DeinitEffectSlot(context->DefaultSlot);
2599 context->DefaultSlot = NULL;
2602 auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed);
2603 al_free(auxslots);
2605 if(context->SourceMap.size > 0)
2607 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2608 (context->SourceMap.size==1)?"":"s");
2609 ReleaseALSources(context);
2611 ResetUIntMap(&context->SourceMap);
2613 if(context->EffectSlotMap.size > 0)
2615 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2616 (context->EffectSlotMap.size==1)?"":"s");
2617 ReleaseALAuxiliaryEffectSlots(context);
2619 ResetUIntMap(&context->EffectSlotMap);
2621 for(i = 0;i < context->VoiceCount;i++)
2622 DeinitVoice(context->Voices[i]);
2623 al_free(context->Voices);
2624 context->Voices = NULL;
2625 context->VoiceCount = 0;
2626 context->MaxVoices = 0;
2628 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2630 TRACE("Freed unapplied listener update %p\n", lprops);
2631 al_free(lprops);
2633 count = 0;
2634 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
2635 while(lprops)
2637 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2638 al_free(lprops);
2639 lprops = next;
2640 ++count;
2642 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2644 ALCdevice_DecRef(context->Device);
2645 context->Device = NULL;
2647 //Invalidate context
2648 memset(context, 0, sizeof(ALCcontext));
2649 al_free(context);
2652 /* ReleaseContext
2654 * Removes the context reference from the given device and removes it from
2655 * being current on the running thread or globally. Returns true if other
2656 * contexts still exist on the device.
2658 static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
2660 ALCcontext *origctx, *newhead;
2661 bool ret = true;
2663 if(altss_get(LocalContext) == context)
2665 WARN("%p released while current on thread\n", context);
2666 altss_set(LocalContext, NULL);
2667 ALCcontext_DecRef(context);
2670 origctx = context;
2671 if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL))
2672 ALCcontext_DecRef(context);
2674 ALCdevice_Lock(device);
2675 origctx = context;
2676 newhead = context->next;
2677 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead))
2679 ALCcontext *volatile*list = &origctx->next;
2680 while(*list)
2682 if(*list == context)
2684 *list = (*list)->next;
2685 break;
2687 list = &(*list)->next;
2690 else
2691 ret = !!newhead;
2692 ALCdevice_Unlock(device);
2694 ALCcontext_DecRef(context);
2695 return ret;
2698 void ALCcontext_IncRef(ALCcontext *context)
2700 uint ref = IncrementRef(&context->ref);
2701 TRACEREF("%p increasing refcount to %u\n", context, ref);
2704 void ALCcontext_DecRef(ALCcontext *context)
2706 uint ref = DecrementRef(&context->ref);
2707 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2708 if(ref == 0) FreeContext(context);
2711 static void ReleaseThreadCtx(void *ptr)
2713 ALCcontext *context = ptr;
2714 uint ref = DecrementRef(&context->ref);
2715 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2716 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2719 /* VerifyContext
2721 * Checks that the given context is valid, and increments its reference count.
2723 static ALCboolean VerifyContext(ALCcontext **context)
2725 ALCdevice *dev;
2727 LockLists();
2728 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2729 while(dev)
2731 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2732 while(ctx)
2734 if(ctx == *context)
2736 ALCcontext_IncRef(ctx);
2737 UnlockLists();
2738 return ALC_TRUE;
2740 ctx = ctx->next;
2742 dev = dev->next;
2744 UnlockLists();
2746 *context = NULL;
2747 return ALC_FALSE;
2751 /* GetContextRef
2753 * Returns the currently active context for this thread, and adds a reference
2754 * without locking it.
2756 ALCcontext *GetContextRef(void)
2758 ALCcontext *context;
2760 context = altss_get(LocalContext);
2761 if(context)
2762 ALCcontext_IncRef(context);
2763 else
2765 LockLists();
2766 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2767 if(context)
2768 ALCcontext_IncRef(context);
2769 UnlockLists();
2772 return context;
2776 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2778 ALCdevice *device = context->Device;
2779 ALsizei num_sends = device->NumAuxSends;
2780 struct ALvoiceProps *props;
2781 size_t sizeof_props;
2782 size_t sizeof_voice;
2783 ALvoice **voices;
2784 ALvoice *voice;
2785 ALsizei v = 0;
2786 size_t size;
2788 if(num_voices == context->MaxVoices && num_sends == old_sends)
2789 return;
2791 /* Allocate the voice pointers, voices, and the voices' stored source
2792 * property set (including the dynamically-sized Send[] array) in one
2793 * chunk.
2795 sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
2796 sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
2797 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2799 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2800 /* The voice and property objects are stored interleaved since they're
2801 * paired together.
2803 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2804 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2806 if(context->Voices)
2808 const ALsizei v_count = mini(context->VoiceCount, num_voices);
2809 const ALsizei s_count = mini(old_sends, num_sends);
2811 for(;v < v_count;v++)
2813 ALvoice *old_voice = context->Voices[v];
2814 ALsizei i;
2816 /* Copy the old voice data and source property set to the new
2817 * storage.
2819 *voice = *old_voice;
2820 for(i = 0;i < s_count;i++)
2821 voice->Send[i] = old_voice->Send[i];
2822 *props = *(old_voice->Props);
2823 for(i = 0;i < s_count;i++)
2824 props->Send[i] = old_voice->Props->Send[i];
2826 /* Set this voice's property set pointer and voice reference. */
2827 voice->Props = props;
2828 voices[v] = voice;
2830 /* Increment pointers to the next storage space. */
2831 voice = (ALvoice*)((char*)props + sizeof_props);
2832 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2834 /* Deinit any left over voices that weren't copied over to the new
2835 * array. NOTE: If this does anything, v equals num_voices and
2836 * num_voices is less than VoiceCount, so the following loop won't do
2837 * anything.
2839 for(;v < context->VoiceCount;v++)
2840 DeinitVoice(context->Voices[v]);
2842 /* Finish setting the voices' property set pointers and references. */
2843 for(;v < num_voices;v++)
2845 ATOMIC_INIT(&voice->Update, NULL);
2846 ATOMIC_INIT(&voice->FreeList, NULL);
2848 voice->Props = props;
2849 voices[v] = voice;
2851 voice = (ALvoice*)((char*)props + sizeof_props);
2852 props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
2855 al_free(context->Voices);
2856 context->Voices = voices;
2857 context->MaxVoices = num_voices;
2858 context->VoiceCount = mini(context->VoiceCount, num_voices);
2862 /************************************************
2863 * Standard ALC functions
2864 ************************************************/
2866 /* alcGetError
2868 * Return last ALC generated error code for the given device
2870 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2872 ALCenum errorCode;
2874 if(VerifyDevice(&device))
2876 errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR);
2877 ALCdevice_DecRef(device);
2879 else
2880 errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR);
2882 return errorCode;
2886 /* alcSuspendContext
2888 * Suspends updates for the given context
2890 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2892 if(!SuspendDefers)
2893 return;
2895 if(!VerifyContext(&context))
2896 alcSetError(NULL, ALC_INVALID_CONTEXT);
2897 else
2899 ALCcontext_DeferUpdates(context);
2900 ALCcontext_DecRef(context);
2904 /* alcProcessContext
2906 * Resumes processing updates for the given context
2908 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2910 if(!SuspendDefers)
2911 return;
2913 if(!VerifyContext(&context))
2914 alcSetError(NULL, ALC_INVALID_CONTEXT);
2915 else
2917 ALCcontext_ProcessUpdates(context);
2918 ALCcontext_DecRef(context);
2923 /* alcGetString
2925 * Returns information about the device, and error strings
2927 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2929 const ALCchar *value = NULL;
2931 switch(param)
2933 case ALC_NO_ERROR:
2934 value = alcNoError;
2935 break;
2937 case ALC_INVALID_ENUM:
2938 value = alcErrInvalidEnum;
2939 break;
2941 case ALC_INVALID_VALUE:
2942 value = alcErrInvalidValue;
2943 break;
2945 case ALC_INVALID_DEVICE:
2946 value = alcErrInvalidDevice;
2947 break;
2949 case ALC_INVALID_CONTEXT:
2950 value = alcErrInvalidContext;
2951 break;
2953 case ALC_OUT_OF_MEMORY:
2954 value = alcErrOutOfMemory;
2955 break;
2957 case ALC_DEVICE_SPECIFIER:
2958 value = alcDefaultName;
2959 break;
2961 case ALC_ALL_DEVICES_SPECIFIER:
2962 if(VerifyDevice(&Device))
2964 value = alstr_get_cstr(Device->DeviceName);
2965 ALCdevice_DecRef(Device);
2967 else
2969 ProbeAllDevicesList();
2970 value = alstr_get_cstr(alcAllDevicesList);
2972 break;
2974 case ALC_CAPTURE_DEVICE_SPECIFIER:
2975 if(VerifyDevice(&Device))
2977 value = alstr_get_cstr(Device->DeviceName);
2978 ALCdevice_DecRef(Device);
2980 else
2982 ProbeCaptureDeviceList();
2983 value = alstr_get_cstr(alcCaptureDeviceList);
2985 break;
2987 /* Default devices are always first in the list */
2988 case ALC_DEFAULT_DEVICE_SPECIFIER:
2989 value = alcDefaultName;
2990 break;
2992 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2993 if(alstr_empty(alcAllDevicesList))
2994 ProbeAllDevicesList();
2996 VerifyDevice(&Device);
2998 free(alcDefaultAllDevicesSpecifier);
2999 alcDefaultAllDevicesSpecifier = strdup(alstr_get_cstr(alcAllDevicesList));
3000 if(!alcDefaultAllDevicesSpecifier)
3001 alcSetError(Device, ALC_OUT_OF_MEMORY);
3003 value = alcDefaultAllDevicesSpecifier;
3004 if(Device) ALCdevice_DecRef(Device);
3005 break;
3007 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
3008 if(alstr_empty(alcCaptureDeviceList))
3009 ProbeCaptureDeviceList();
3011 VerifyDevice(&Device);
3013 free(alcCaptureDefaultDeviceSpecifier);
3014 alcCaptureDefaultDeviceSpecifier = strdup(alstr_get_cstr(alcCaptureDeviceList));
3015 if(!alcCaptureDefaultDeviceSpecifier)
3016 alcSetError(Device, ALC_OUT_OF_MEMORY);
3018 value = alcCaptureDefaultDeviceSpecifier;
3019 if(Device) ALCdevice_DecRef(Device);
3020 break;
3022 case ALC_EXTENSIONS:
3023 if(!VerifyDevice(&Device))
3024 value = alcNoDeviceExtList;
3025 else
3027 value = alcExtensionList;
3028 ALCdevice_DecRef(Device);
3030 break;
3032 case ALC_HRTF_SPECIFIER_SOFT:
3033 if(!VerifyDevice(&Device))
3034 alcSetError(NULL, ALC_INVALID_DEVICE);
3035 else
3037 almtx_lock(&Device->BackendLock);
3038 value = (Device->HrtfHandle ? alstr_get_cstr(Device->HrtfName) : "");
3039 almtx_unlock(&Device->BackendLock);
3040 ALCdevice_DecRef(Device);
3042 break;
3044 default:
3045 VerifyDevice(&Device);
3046 alcSetError(Device, ALC_INVALID_ENUM);
3047 if(Device) ALCdevice_DecRef(Device);
3048 break;
3051 return value;
3055 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
3057 if(device->Type == Loopback && device->FmtChans == DevFmtAmbi3D)
3058 return 25;
3059 return 19;
3062 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3064 ALCsizei i;
3066 if(size <= 0 || values == NULL)
3068 alcSetError(device, ALC_INVALID_VALUE);
3069 return 0;
3072 if(!device)
3074 switch(param)
3076 case ALC_MAJOR_VERSION:
3077 values[0] = alcMajorVersion;
3078 return 1;
3079 case ALC_MINOR_VERSION:
3080 values[0] = alcMinorVersion;
3081 return 1;
3083 case ALC_ATTRIBUTES_SIZE:
3084 case ALC_ALL_ATTRIBUTES:
3085 case ALC_FREQUENCY:
3086 case ALC_REFRESH:
3087 case ALC_SYNC:
3088 case ALC_MONO_SOURCES:
3089 case ALC_STEREO_SOURCES:
3090 case ALC_CAPTURE_SAMPLES:
3091 case ALC_FORMAT_CHANNELS_SOFT:
3092 case ALC_FORMAT_TYPE_SOFT:
3093 case ALC_AMBISONIC_LAYOUT_SOFT:
3094 case ALC_AMBISONIC_SCALING_SOFT:
3095 case ALC_AMBISONIC_ORDER_SOFT:
3096 alcSetError(NULL, ALC_INVALID_DEVICE);
3097 return 0;
3099 default:
3100 alcSetError(NULL, ALC_INVALID_ENUM);
3101 return 0;
3103 return 0;
3106 if(device->Type == Capture)
3108 switch(param)
3110 case ALC_CAPTURE_SAMPLES:
3111 almtx_lock(&device->BackendLock);
3112 values[0] = V0(device->Backend,availableSamples)();
3113 almtx_unlock(&device->BackendLock);
3114 return 1;
3116 case ALC_CONNECTED:
3117 values[0] = device->Connected;
3118 return 1;
3120 default:
3121 alcSetError(device, ALC_INVALID_ENUM);
3122 return 0;
3124 return 0;
3127 /* render device */
3128 switch(param)
3130 case ALC_MAJOR_VERSION:
3131 values[0] = alcMajorVersion;
3132 return 1;
3134 case ALC_MINOR_VERSION:
3135 values[0] = alcMinorVersion;
3136 return 1;
3138 case ALC_EFX_MAJOR_VERSION:
3139 values[0] = alcEFXMajorVersion;
3140 return 1;
3142 case ALC_EFX_MINOR_VERSION:
3143 values[0] = alcEFXMinorVersion;
3144 return 1;
3146 case ALC_ATTRIBUTES_SIZE:
3147 values[0] = NumAttrsForDevice(device);
3148 return 1;
3150 case ALC_ALL_ATTRIBUTES:
3151 if(size < NumAttrsForDevice(device))
3153 alcSetError(device, ALC_INVALID_VALUE);
3154 return 0;
3157 i = 0;
3158 almtx_lock(&device->BackendLock);
3159 values[i++] = ALC_FREQUENCY;
3160 values[i++] = device->Frequency;
3162 if(device->Type != Loopback)
3164 values[i++] = ALC_REFRESH;
3165 values[i++] = device->Frequency / device->UpdateSize;
3167 values[i++] = ALC_SYNC;
3168 values[i++] = ALC_FALSE;
3170 else
3172 if(device->FmtChans == DevFmtAmbi3D)
3174 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3175 values[i++] = device->AmbiLayout;
3177 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3178 values[i++] = device->AmbiScale;
3180 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3181 values[i++] = device->AmbiOrder;
3184 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3185 values[i++] = device->FmtChans;
3187 values[i++] = ALC_FORMAT_TYPE_SOFT;
3188 values[i++] = device->FmtType;
3191 values[i++] = ALC_MONO_SOURCES;
3192 values[i++] = device->NumMonoSources;
3194 values[i++] = ALC_STEREO_SOURCES;
3195 values[i++] = device->NumStereoSources;
3197 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3198 values[i++] = device->NumAuxSends;
3200 values[i++] = ALC_HRTF_SOFT;
3201 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3203 values[i++] = ALC_HRTF_STATUS_SOFT;
3204 values[i++] = device->HrtfStatus;
3206 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3207 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3208 almtx_unlock(&device->BackendLock);
3210 values[i++] = 0;
3211 return i;
3213 case ALC_FREQUENCY:
3214 values[0] = device->Frequency;
3215 return 1;
3217 case ALC_REFRESH:
3218 if(device->Type == Loopback)
3220 alcSetError(device, ALC_INVALID_DEVICE);
3221 return 0;
3223 almtx_lock(&device->BackendLock);
3224 values[0] = device->Frequency / device->UpdateSize;
3225 almtx_unlock(&device->BackendLock);
3226 return 1;
3228 case ALC_SYNC:
3229 if(device->Type == Loopback)
3231 alcSetError(device, ALC_INVALID_DEVICE);
3232 return 0;
3234 values[0] = ALC_FALSE;
3235 return 1;
3237 case ALC_FORMAT_CHANNELS_SOFT:
3238 if(device->Type != Loopback)
3240 alcSetError(device, ALC_INVALID_DEVICE);
3241 return 0;
3243 values[0] = device->FmtChans;
3244 return 1;
3246 case ALC_FORMAT_TYPE_SOFT:
3247 if(device->Type != Loopback)
3249 alcSetError(device, ALC_INVALID_DEVICE);
3250 return 0;
3252 values[0] = device->FmtType;
3253 return 1;
3255 case ALC_AMBISONIC_LAYOUT_SOFT:
3256 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3258 alcSetError(device, ALC_INVALID_DEVICE);
3259 return 0;
3261 values[0] = device->AmbiLayout;
3262 return 1;
3264 case ALC_AMBISONIC_SCALING_SOFT:
3265 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3267 alcSetError(device, ALC_INVALID_DEVICE);
3268 return 0;
3270 values[0] = device->AmbiScale;
3271 return 1;
3273 case ALC_AMBISONIC_ORDER_SOFT:
3274 if(device->Type != Loopback || device->FmtChans != DevFmtAmbi3D)
3276 alcSetError(device, ALC_INVALID_DEVICE);
3277 return 0;
3279 values[0] = device->AmbiOrder;
3280 return 1;
3282 case ALC_MONO_SOURCES:
3283 values[0] = device->NumMonoSources;
3284 return 1;
3286 case ALC_STEREO_SOURCES:
3287 values[0] = device->NumStereoSources;
3288 return 1;
3290 case ALC_MAX_AUXILIARY_SENDS:
3291 values[0] = device->NumAuxSends;
3292 return 1;
3294 case ALC_CONNECTED:
3295 values[0] = device->Connected;
3296 return 1;
3298 case ALC_HRTF_SOFT:
3299 values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3300 return 1;
3302 case ALC_HRTF_STATUS_SOFT:
3303 values[0] = device->HrtfStatus;
3304 return 1;
3306 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3307 almtx_lock(&device->BackendLock);
3308 FreeHrtfList(&device->HrtfList);
3309 device->HrtfList = EnumerateHrtf(device->DeviceName);
3310 values[0] = (ALCint)VECTOR_SIZE(device->HrtfList);
3311 almtx_unlock(&device->BackendLock);
3312 return 1;
3314 case ALC_OUTPUT_LIMITER_SOFT:
3315 values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3316 return 1;
3318 default:
3319 alcSetError(device, ALC_INVALID_ENUM);
3320 return 0;
3322 return 0;
3325 /* alcGetIntegerv
3327 * Returns information about the device and the version of OpenAL
3329 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3331 VerifyDevice(&device);
3332 if(size <= 0 || values == NULL)
3333 alcSetError(device, ALC_INVALID_VALUE);
3334 else
3335 GetIntegerv(device, param, size, values);
3336 if(device) ALCdevice_DecRef(device);
3339 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3341 ALCint *ivals;
3342 ALsizei i;
3344 VerifyDevice(&device);
3345 if(size <= 0 || values == NULL)
3346 alcSetError(device, ALC_INVALID_VALUE);
3347 else if(!device || device->Type == Capture)
3349 ivals = malloc(size * sizeof(ALCint));
3350 size = GetIntegerv(device, pname, size, ivals);
3351 for(i = 0;i < size;i++)
3352 values[i] = ivals[i];
3353 free(ivals);
3355 else /* render device */
3357 ClockLatency clock;
3358 ALuint64 basecount;
3359 ALuint samplecount;
3360 ALuint refcount;
3362 switch(pname)
3364 case ALC_ATTRIBUTES_SIZE:
3365 *values = NumAttrsForDevice(device)+4;
3366 break;
3368 case ALC_ALL_ATTRIBUTES:
3369 if(size < NumAttrsForDevice(device)+4)
3370 alcSetError(device, ALC_INVALID_VALUE);
3371 else
3373 i = 0;
3374 almtx_lock(&device->BackendLock);
3375 values[i++] = ALC_FREQUENCY;
3376 values[i++] = device->Frequency;
3378 if(device->Type != Loopback)
3380 values[i++] = ALC_REFRESH;
3381 values[i++] = device->Frequency / device->UpdateSize;
3383 values[i++] = ALC_SYNC;
3384 values[i++] = ALC_FALSE;
3386 else
3388 if(device->FmtChans == DevFmtAmbi3D)
3390 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3391 values[i++] = device->AmbiLayout;
3393 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3394 values[i++] = device->AmbiScale;
3396 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3397 values[i++] = device->AmbiOrder;
3400 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3401 values[i++] = device->FmtChans;
3403 values[i++] = ALC_FORMAT_TYPE_SOFT;
3404 values[i++] = device->FmtType;
3407 values[i++] = ALC_MONO_SOURCES;
3408 values[i++] = device->NumMonoSources;
3410 values[i++] = ALC_STEREO_SOURCES;
3411 values[i++] = device->NumStereoSources;
3413 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3414 values[i++] = device->NumAuxSends;
3416 values[i++] = ALC_HRTF_SOFT;
3417 values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
3419 values[i++] = ALC_HRTF_STATUS_SOFT;
3420 values[i++] = device->HrtfStatus;
3422 values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3423 values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3425 clock = V0(device->Backend,getClockLatency)();
3426 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3427 values[i++] = clock.ClockTime;
3429 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3430 values[i++] = clock.Latency;
3431 almtx_unlock(&device->BackendLock);
3433 values[i++] = 0;
3435 break;
3437 case ALC_DEVICE_CLOCK_SOFT:
3438 almtx_lock(&device->BackendLock);
3439 do {
3440 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3441 althrd_yield();
3442 basecount = device->ClockBase;
3443 samplecount = device->SamplesDone;
3444 } while(refcount != ReadRef(&device->MixCount));
3445 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3446 almtx_unlock(&device->BackendLock);
3447 break;
3449 case ALC_DEVICE_LATENCY_SOFT:
3450 almtx_lock(&device->BackendLock);
3451 clock = V0(device->Backend,getClockLatency)();
3452 almtx_unlock(&device->BackendLock);
3453 *values = clock.Latency;
3454 break;
3456 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3457 if(size < 2)
3458 alcSetError(device, ALC_INVALID_VALUE);
3459 else
3461 almtx_lock(&device->BackendLock);
3462 clock = V0(device->Backend,getClockLatency)();
3463 almtx_unlock(&device->BackendLock);
3464 values[0] = clock.ClockTime;
3465 values[1] = clock.Latency;
3467 break;
3469 default:
3470 ivals = malloc(size * sizeof(ALCint));
3471 size = GetIntegerv(device, pname, size, ivals);
3472 for(i = 0;i < size;i++)
3473 values[i] = ivals[i];
3474 free(ivals);
3475 break;
3478 if(device)
3479 ALCdevice_DecRef(device);
3483 /* alcIsExtensionPresent
3485 * Determines if there is support for a particular extension
3487 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3489 ALCboolean bResult = ALC_FALSE;
3491 VerifyDevice(&device);
3493 if(!extName)
3494 alcSetError(device, ALC_INVALID_VALUE);
3495 else
3497 size_t len = strlen(extName);
3498 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3499 while(ptr && *ptr)
3501 if(strncasecmp(ptr, extName, len) == 0 &&
3502 (ptr[len] == '\0' || isspace(ptr[len])))
3504 bResult = ALC_TRUE;
3505 break;
3507 if((ptr=strchr(ptr, ' ')) != NULL)
3509 do {
3510 ++ptr;
3511 } while(isspace(*ptr));
3515 if(device)
3516 ALCdevice_DecRef(device);
3517 return bResult;
3521 /* alcGetProcAddress
3523 * Retrieves the function address for a particular extension function
3525 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3527 ALCvoid *ptr = NULL;
3529 if(!funcName)
3531 VerifyDevice(&device);
3532 alcSetError(device, ALC_INVALID_VALUE);
3533 if(device) ALCdevice_DecRef(device);
3535 else
3537 size_t i = 0;
3538 for(i = 0;i < COUNTOF(alcFunctions);i++)
3540 if(strcmp(alcFunctions[i].funcName, funcName) == 0)
3542 ptr = alcFunctions[i].address;
3543 break;
3548 return ptr;
3552 /* alcGetEnumValue
3554 * Get the value for a particular ALC enumeration name
3556 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3558 ALCenum val = 0;
3560 if(!enumName)
3562 VerifyDevice(&device);
3563 alcSetError(device, ALC_INVALID_VALUE);
3564 if(device) ALCdevice_DecRef(device);
3566 else
3568 size_t i = 0;
3569 for(i = 0;i < COUNTOF(alcEnumerations);i++)
3571 if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
3573 val = alcEnumerations[i].value;
3574 break;
3579 return val;
3583 /* alcCreateContext
3585 * Create and attach a context to the given device.
3587 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3589 ALCcontext *ALContext;
3590 ALfloat valf;
3591 ALCenum err;
3593 /* Explicitly hold the list lock while taking the BackendLock in case the
3594 * device is asynchronously destropyed, to ensure this new context is
3595 * properly cleaned up after being made.
3597 LockLists();
3598 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3600 UnlockLists();
3601 alcSetError(device, ALC_INVALID_DEVICE);
3602 if(device) ALCdevice_DecRef(device);
3603 return NULL;
3605 almtx_lock(&device->BackendLock);
3606 UnlockLists();
3608 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3610 if(device->Type == Playback && DefaultEffect.type != AL_EFFECT_NULL)
3611 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener)+sizeof(ALeffectslot));
3612 else
3613 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3614 if(!ALContext)
3616 almtx_unlock(&device->BackendLock);
3618 alcSetError(device, ALC_OUT_OF_MEMORY);
3619 ALCdevice_DecRef(device);
3620 return NULL;
3623 InitRef(&ALContext->ref, 1);
3624 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3625 ALContext->DefaultSlot = NULL;
3627 ALContext->Voices = NULL;
3628 ALContext->VoiceCount = 0;
3629 ALContext->MaxVoices = 0;
3630 ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL);
3631 ALContext->Device = device;
3633 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3635 almtx_unlock(&device->BackendLock);
3637 al_free(ALContext);
3638 ALContext = NULL;
3640 alcSetError(device, err);
3641 if(err == ALC_INVALID_DEVICE)
3643 V0(device->Backend,lock)();
3644 aluHandleDisconnect(device);
3645 V0(device->Backend,unlock)();
3647 ALCdevice_DecRef(device);
3648 return NULL;
3650 AllocateVoices(ALContext, 256, device->NumAuxSends);
3652 if(DefaultEffect.type != AL_EFFECT_NULL && device->Type == Playback)
3654 ALContext->DefaultSlot = (ALeffectslot*)(ALContext->_listener_mem + sizeof(ALlistener));
3655 if(InitEffectSlot(ALContext->DefaultSlot) == AL_NO_ERROR)
3656 aluInitEffectPanning(ALContext->DefaultSlot);
3657 else
3659 ALContext->DefaultSlot = NULL;
3660 ERR("Failed to initialize the default effect slot\n");
3664 ALCdevice_IncRef(ALContext->Device);
3665 InitContext(ALContext);
3667 if(ConfigValueFloat(alstr_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3669 if(!isfinite(valf))
3670 ERR("volume-adjust must be finite: %f\n", valf);
3671 else
3673 ALfloat db = clampf(valf, -24.0f, 24.0f);
3674 if(db != valf)
3675 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3676 ALContext->GainBoost = powf(10.0f, db/20.0f);
3677 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3680 UpdateListenerProps(ALContext);
3683 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3684 do {
3685 ALContext->next = head;
3686 } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head,
3687 ALContext) == 0);
3689 almtx_unlock(&device->BackendLock);
3691 if(ALContext->DefaultSlot)
3693 if(InitializeEffect(device, ALContext->DefaultSlot, &DefaultEffect) == AL_NO_ERROR)
3694 UpdateEffectSlotProps(ALContext->DefaultSlot);
3695 else
3696 ERR("Failed to initialize the default effect\n");
3699 ALCdevice_DecRef(device);
3701 TRACE("Created context %p\n", ALContext);
3702 return ALContext;
3705 /* alcDestroyContext
3707 * Remove a context from its device
3709 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3711 ALCdevice *Device;
3713 LockLists();
3714 if(!VerifyContext(&context))
3716 UnlockLists();
3717 alcSetError(NULL, ALC_INVALID_CONTEXT);
3718 return;
3721 Device = context->Device;
3722 if(Device)
3724 almtx_lock(&Device->BackendLock);
3725 if(!ReleaseContext(context, Device))
3727 V0(Device->Backend,stop)();
3728 Device->Flags &= ~DEVICE_RUNNING;
3730 almtx_unlock(&Device->BackendLock);
3732 UnlockLists();
3734 ALCcontext_DecRef(context);
3738 /* alcGetCurrentContext
3740 * Returns the currently active context on the calling thread
3742 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3744 ALCcontext *Context = altss_get(LocalContext);
3745 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3746 return Context;
3749 /* alcGetThreadContext
3751 * Returns the currently active thread-local context
3753 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3755 return altss_get(LocalContext);
3759 /* alcMakeContextCurrent
3761 * Makes the given context the active process-wide context, and removes the
3762 * thread-local context for the calling thread.
3764 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3766 /* context must be valid or NULL */
3767 if(context && !VerifyContext(&context))
3769 alcSetError(NULL, ALC_INVALID_CONTEXT);
3770 return ALC_FALSE;
3772 /* context's reference count is already incremented */
3773 context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context);
3774 if(context) ALCcontext_DecRef(context);
3776 if((context=altss_get(LocalContext)) != NULL)
3778 altss_set(LocalContext, NULL);
3779 ALCcontext_DecRef(context);
3782 return ALC_TRUE;
3785 /* alcSetThreadContext
3787 * Makes the given context the active context for the current thread
3789 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3791 ALCcontext *old;
3793 /* context must be valid or NULL */
3794 if(context && !VerifyContext(&context))
3796 alcSetError(NULL, ALC_INVALID_CONTEXT);
3797 return ALC_FALSE;
3799 /* context's reference count is already incremented */
3800 old = altss_get(LocalContext);
3801 altss_set(LocalContext, context);
3802 if(old) ALCcontext_DecRef(old);
3804 return ALC_TRUE;
3808 /* alcGetContextsDevice
3810 * Returns the device that a particular context is attached to
3812 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3814 ALCdevice *Device;
3816 if(!VerifyContext(&Context))
3818 alcSetError(NULL, ALC_INVALID_CONTEXT);
3819 return NULL;
3821 Device = Context->Device;
3822 ALCcontext_DecRef(Context);
3824 return Device;
3828 /* alcOpenDevice
3830 * Opens the named device.
3832 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3834 ALCbackendFactory *factory;
3835 const ALCchar *fmt;
3836 ALCdevice *device;
3837 ALCenum err;
3838 ALCsizei i;
3840 DO_INITCONFIG();
3842 if(!PlaybackBackend.name)
3844 alcSetError(NULL, ALC_INVALID_VALUE);
3845 return NULL;
3848 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3849 #ifdef _WIN32
3850 /* Some old Windows apps hardcode these expecting OpenAL to use a
3851 * specific audio API, even when they're not enumerated. Creative's
3852 * router effectively ignores them too.
3854 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3855 || strcasecmp(deviceName, "MMSYSTEM") == 0
3856 #endif
3858 deviceName = NULL;
3860 device = al_calloc(16, sizeof(ALCdevice));
3861 if(!device)
3863 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3864 return NULL;
3867 //Validate device
3868 InitRef(&device->ref, 1);
3869 device->Connected = ALC_TRUE;
3870 device->Type = Playback;
3871 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3873 device->Flags = 0;
3874 device->Bs2b = NULL;
3875 device->Uhj_Encoder = NULL;
3876 device->Hrtf = NULL;
3877 device->HrtfHandle = NULL;
3878 VECTOR_INIT(device->HrtfList);
3879 AL_STRING_INIT(device->HrtfName);
3880 device->Render_Mode = NormalRender;
3881 AL_STRING_INIT(device->DeviceName);
3882 device->Dry.Buffer = NULL;
3883 device->Dry.NumChannels = 0;
3884 device->FOAOut.Buffer = NULL;
3885 device->FOAOut.NumChannels = 0;
3886 device->RealOut.Buffer = NULL;
3887 device->RealOut.NumChannels = 0;
3888 device->Limiter = NULL;
3889 device->AvgSpeakerDist = 0.0f;
3891 ATOMIC_INIT(&device->ContextList, NULL);
3893 device->ClockBase = 0;
3894 device->SamplesDone = 0;
3896 device->SourcesMax = 256;
3897 device->AuxiliaryEffectSlotMax = 64;
3898 device->NumAuxSends = DEFAULT_SENDS;
3900 InitUIntMap(&device->BufferMap, INT_MAX);
3901 InitUIntMap(&device->EffectMap, INT_MAX);
3902 InitUIntMap(&device->FilterMap, INT_MAX);
3904 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3906 device->ChannelDelay[i].Gain = 1.0f;
3907 device->ChannelDelay[i].Length = 0;
3908 device->ChannelDelay[i].Buffer = NULL;
3911 //Set output format
3912 device->FmtChans = DevFmtChannelsDefault;
3913 device->FmtType = DevFmtTypeDefault;
3914 device->Frequency = DEFAULT_OUTPUT_RATE;
3915 device->IsHeadphones = AL_FALSE;
3916 device->AmbiLayout = AmbiLayout_Default;
3917 device->AmbiScale = AmbiNorm_Default;
3918 device->NumUpdates = 3;
3919 device->UpdateSize = 1024;
3921 factory = PlaybackBackend.getFactory();
3922 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3923 if(!device->Backend)
3925 al_free(device);
3926 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3927 return NULL;
3931 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3933 static const struct {
3934 const char name[16];
3935 enum DevFmtChannels chans;
3936 ALsizei order;
3937 } chanlist[] = {
3938 { "mono", DevFmtMono, 0 },
3939 { "stereo", DevFmtStereo, 0 },
3940 { "quad", DevFmtQuad, 0 },
3941 { "surround51", DevFmtX51, 0 },
3942 { "surround61", DevFmtX61, 0 },
3943 { "surround71", DevFmtX71, 0 },
3944 { "surround51rear", DevFmtX51Rear, 0 },
3945 { "ambi1", DevFmtAmbi3D, 1 },
3946 { "ambi2", DevFmtAmbi3D, 2 },
3947 { "ambi3", DevFmtAmbi3D, 3 },
3949 size_t i;
3951 for(i = 0;i < COUNTOF(chanlist);i++)
3953 if(strcasecmp(chanlist[i].name, fmt) == 0)
3955 device->FmtChans = chanlist[i].chans;
3956 device->AmbiOrder = chanlist[i].order;
3957 device->Flags |= DEVICE_CHANNELS_REQUEST;
3958 break;
3961 if(i == COUNTOF(chanlist))
3962 ERR("Unsupported channels: %s\n", fmt);
3964 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3966 static const struct {
3967 const char name[16];
3968 enum DevFmtType type;
3969 } typelist[] = {
3970 { "int8", DevFmtByte },
3971 { "uint8", DevFmtUByte },
3972 { "int16", DevFmtShort },
3973 { "uint16", DevFmtUShort },
3974 { "int32", DevFmtInt },
3975 { "uint32", DevFmtUInt },
3976 { "float32", DevFmtFloat },
3978 size_t i;
3980 for(i = 0;i < COUNTOF(typelist);i++)
3982 if(strcasecmp(typelist[i].name, fmt) == 0)
3984 device->FmtType = typelist[i].type;
3985 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3986 break;
3989 if(i == COUNTOF(typelist))
3990 ERR("Unsupported sample-type: %s\n", fmt);
3993 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3995 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3996 if(device->Frequency < MIN_OUTPUT_RATE)
3997 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3998 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
4001 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
4002 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
4004 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
4005 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
4006 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
4007 device->UpdateSize = (device->UpdateSize+3)&~3;
4009 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
4010 if(device->SourcesMax == 0) device->SourcesMax = 256;
4012 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4013 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4015 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
4016 device->NumAuxSends = clampi(
4017 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4020 device->NumStereoSources = 1;
4021 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4023 // Find a playback device to open
4024 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4026 DELETE_OBJ(device->Backend);
4027 al_free(device);
4028 alcSetError(NULL, err);
4029 return NULL;
4031 almtx_init(&device->BackendLock, almtx_plain);
4033 if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
4035 if(strcasecmp(fmt, "fuma") == 0)
4037 device->AmbiLayout = AmbiLayout_FuMa;
4038 device->AmbiScale = AmbiNorm_FuMa;
4040 else if(strcasecmp(fmt, "acn+sn3d") == 0)
4042 device->AmbiLayout = AmbiLayout_ACN;
4043 device->AmbiScale = AmbiNorm_SN3D;
4045 else if(strcasecmp(fmt, "acn+n3d") == 0)
4047 device->AmbiLayout = AmbiLayout_ACN;
4048 device->AmbiScale = AmbiNorm_N3D;
4050 else
4051 ERR("Unsupported ambi-format: %s\n", fmt);
4054 device->Limiter = CreateDeviceLimiter(device);
4057 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4058 do {
4059 device->next = head;
4060 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4063 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4064 return device;
4067 /* alcCloseDevice
4069 * Closes the given device.
4071 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
4073 ALCdevice *iter, *origdev;
4074 ALCcontext *ctx;
4076 LockLists();
4077 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4078 do {
4079 if(iter == device)
4080 break;
4081 } while((iter=iter->next) != NULL);
4082 if(!iter || iter->Type == Capture)
4084 alcSetError(iter, ALC_INVALID_DEVICE);
4085 UnlockLists();
4086 return ALC_FALSE;
4088 almtx_lock(&device->BackendLock);
4090 origdev = device;
4091 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4093 ALCdevice *volatile*list = &origdev->next;
4094 while(*list)
4096 if(*list == device)
4098 *list = (*list)->next;
4099 break;
4101 list = &(*list)->next;
4104 UnlockLists();
4106 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
4107 while(ctx != NULL)
4109 ALCcontext *next = ctx->next;
4110 WARN("Releasing context %p\n", ctx);
4111 ReleaseContext(ctx, device);
4112 ctx = next;
4114 if((device->Flags&DEVICE_RUNNING))
4115 V0(device->Backend,stop)();
4116 device->Flags &= ~DEVICE_RUNNING;
4117 almtx_unlock(&device->BackendLock);
4119 ALCdevice_DecRef(device);
4121 return ALC_TRUE;
4125 /************************************************
4126 * ALC capture functions
4127 ************************************************/
4128 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4130 ALCbackendFactory *factory;
4131 ALCdevice *device = NULL;
4132 ALCenum err;
4133 ALCsizei i;
4135 DO_INITCONFIG();
4137 if(!CaptureBackend.name)
4139 alcSetError(NULL, ALC_INVALID_VALUE);
4140 return NULL;
4143 if(samples <= 0)
4145 alcSetError(NULL, ALC_INVALID_VALUE);
4146 return NULL;
4149 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4150 deviceName = NULL;
4152 device = al_calloc(16, sizeof(ALCdevice));
4153 if(!device)
4155 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4156 return NULL;
4159 //Validate device
4160 InitRef(&device->ref, 1);
4161 device->Connected = ALC_TRUE;
4162 device->Type = Capture;
4164 device->Hrtf = NULL;
4165 device->HrtfHandle = NULL;
4166 VECTOR_INIT(device->HrtfList);
4167 AL_STRING_INIT(device->HrtfName);
4169 AL_STRING_INIT(device->DeviceName);
4170 device->Dry.Buffer = NULL;
4171 device->Dry.NumChannels = 0;
4172 device->FOAOut.Buffer = NULL;
4173 device->FOAOut.NumChannels = 0;
4174 device->RealOut.Buffer = NULL;
4175 device->RealOut.NumChannels = 0;
4177 InitUIntMap(&device->BufferMap, INT_MAX);
4178 InitUIntMap(&device->EffectMap, INT_MAX);
4179 InitUIntMap(&device->FilterMap, INT_MAX);
4181 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4183 device->ChannelDelay[i].Gain = 1.0f;
4184 device->ChannelDelay[i].Length = 0;
4185 device->ChannelDelay[i].Buffer = NULL;
4188 factory = CaptureBackend.getFactory();
4189 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4190 if(!device->Backend)
4192 al_free(device);
4193 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4194 return NULL;
4197 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4198 device->Frequency = frequency;
4200 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4201 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4203 al_free(device);
4204 alcSetError(NULL, ALC_INVALID_ENUM);
4205 return NULL;
4207 device->IsHeadphones = AL_FALSE;
4208 device->AmbiOrder = 0;
4209 device->AmbiLayout = AmbiLayout_Default;
4210 device->AmbiScale = AmbiNorm_Default;
4212 device->UpdateSize = samples;
4213 device->NumUpdates = 1;
4215 TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
4216 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
4217 device->Frequency, device->UpdateSize, device->NumUpdates
4219 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4221 al_free(device);
4222 alcSetError(NULL, err);
4223 return NULL;
4225 almtx_init(&device->BackendLock, almtx_plain);
4228 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4229 do {
4230 device->next = head;
4231 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4234 TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName));
4235 return device;
4238 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4240 ALCdevice *iter, *origdev;
4242 LockLists();
4243 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4244 do {
4245 if(iter == device)
4246 break;
4247 } while((iter=iter->next) != NULL);
4248 if(!iter || iter->Type != Capture)
4250 alcSetError(iter, ALC_INVALID_DEVICE);
4251 UnlockLists();
4252 return ALC_FALSE;
4255 origdev = device;
4256 if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next))
4258 ALCdevice *volatile*list = &origdev->next;
4259 while(*list)
4261 if(*list == device)
4263 *list = (*list)->next;
4264 break;
4266 list = &(*list)->next;
4269 UnlockLists();
4271 ALCdevice_DecRef(device);
4273 return ALC_TRUE;
4276 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4278 if(!VerifyDevice(&device) || device->Type != Capture)
4279 alcSetError(device, ALC_INVALID_DEVICE);
4280 else
4282 almtx_lock(&device->BackendLock);
4283 if(!device->Connected)
4284 alcSetError(device, ALC_INVALID_DEVICE);
4285 else if(!(device->Flags&DEVICE_RUNNING))
4287 if(V0(device->Backend,start)())
4288 device->Flags |= DEVICE_RUNNING;
4289 else
4291 aluHandleDisconnect(device);
4292 alcSetError(device, ALC_INVALID_DEVICE);
4295 almtx_unlock(&device->BackendLock);
4298 if(device) ALCdevice_DecRef(device);
4301 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4303 if(!VerifyDevice(&device) || device->Type != Capture)
4304 alcSetError(device, ALC_INVALID_DEVICE);
4305 else
4307 almtx_lock(&device->BackendLock);
4308 if((device->Flags&DEVICE_RUNNING))
4309 V0(device->Backend,stop)();
4310 device->Flags &= ~DEVICE_RUNNING;
4311 almtx_unlock(&device->BackendLock);
4314 if(device) ALCdevice_DecRef(device);
4317 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4319 if(!VerifyDevice(&device) || device->Type != Capture)
4320 alcSetError(device, ALC_INVALID_DEVICE);
4321 else
4323 ALCenum err = ALC_INVALID_VALUE;
4325 almtx_lock(&device->BackendLock);
4326 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4327 err = V(device->Backend,captureSamples)(buffer, samples);
4328 almtx_unlock(&device->BackendLock);
4330 if(err != ALC_NO_ERROR)
4331 alcSetError(device, err);
4333 if(device) ALCdevice_DecRef(device);
4337 /************************************************
4338 * ALC loopback functions
4339 ************************************************/
4341 /* alcLoopbackOpenDeviceSOFT
4343 * Open a loopback device, for manual rendering.
4345 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4347 ALCbackendFactory *factory;
4348 ALCdevice *device;
4349 ALCsizei i;
4351 DO_INITCONFIG();
4353 /* Make sure the device name, if specified, is us. */
4354 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4356 alcSetError(NULL, ALC_INVALID_VALUE);
4357 return NULL;
4360 device = al_calloc(16, sizeof(ALCdevice));
4361 if(!device)
4363 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4364 return NULL;
4367 //Validate device
4368 InitRef(&device->ref, 1);
4369 device->Connected = ALC_TRUE;
4370 device->Type = Loopback;
4371 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4373 device->Flags = 0;
4374 device->Hrtf = NULL;
4375 device->HrtfHandle = NULL;
4376 VECTOR_INIT(device->HrtfList);
4377 AL_STRING_INIT(device->HrtfName);
4378 device->Bs2b = NULL;
4379 device->Uhj_Encoder = NULL;
4380 device->Render_Mode = NormalRender;
4381 AL_STRING_INIT(device->DeviceName);
4382 device->Dry.Buffer = NULL;
4383 device->Dry.NumChannels = 0;
4384 device->FOAOut.Buffer = NULL;
4385 device->FOAOut.NumChannels = 0;
4386 device->RealOut.Buffer = NULL;
4387 device->RealOut.NumChannels = 0;
4388 device->Limiter = NULL;
4389 device->AvgSpeakerDist = 0.0f;
4391 ATOMIC_INIT(&device->ContextList, NULL);
4393 device->ClockBase = 0;
4394 device->SamplesDone = 0;
4396 device->SourcesMax = 256;
4397 device->AuxiliaryEffectSlotMax = 64;
4398 device->NumAuxSends = DEFAULT_SENDS;
4400 InitUIntMap(&device->BufferMap, INT_MAX);
4401 InitUIntMap(&device->EffectMap, INT_MAX);
4402 InitUIntMap(&device->FilterMap, INT_MAX);
4404 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4406 device->ChannelDelay[i].Gain = 1.0f;
4407 device->ChannelDelay[i].Length = 0;
4408 device->ChannelDelay[i].Buffer = NULL;
4411 factory = ALCloopbackFactory_getFactory();
4412 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4413 if(!device->Backend)
4415 al_free(device);
4416 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4417 return NULL;
4419 almtx_init(&device->BackendLock, almtx_plain);
4421 //Set output format
4422 device->NumUpdates = 0;
4423 device->UpdateSize = 0;
4425 device->Frequency = DEFAULT_OUTPUT_RATE;
4426 device->FmtChans = DevFmtChannelsDefault;
4427 device->FmtType = DevFmtTypeDefault;
4428 device->IsHeadphones = AL_FALSE;
4429 device->AmbiLayout = AmbiLayout_Default;
4430 device->AmbiScale = AmbiNorm_Default;
4432 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4433 if(device->SourcesMax == 0) device->SourcesMax = 256;
4435 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4436 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4438 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4439 device->NumAuxSends = clampi(
4440 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4443 device->NumStereoSources = 1;
4444 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4446 // Open the "backend"
4447 V(device->Backend,open)("Loopback");
4449 device->Limiter = CreateDeviceLimiter(device);
4452 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4453 do {
4454 device->next = head;
4455 } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device));
4458 TRACE("Created device %p\n", device);
4459 return device;
4462 /* alcIsRenderFormatSupportedSOFT
4464 * Determines if the loopback device supports the given format for rendering.
4466 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4468 ALCboolean ret = ALC_FALSE;
4470 if(!VerifyDevice(&device) || device->Type != Loopback)
4471 alcSetError(device, ALC_INVALID_DEVICE);
4472 else if(freq <= 0)
4473 alcSetError(device, ALC_INVALID_VALUE);
4474 else
4476 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4477 ret = ALC_TRUE;
4479 if(device) ALCdevice_DecRef(device);
4481 return ret;
4484 /* alcRenderSamplesSOFT
4486 * Renders some samples into a buffer, using the format last set by the
4487 * attributes given to alcCreateContext.
4489 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4491 if(!VerifyDevice(&device) || device->Type != Loopback)
4492 alcSetError(device, ALC_INVALID_DEVICE);
4493 else if(samples < 0 || (samples > 0 && buffer == NULL))
4494 alcSetError(device, ALC_INVALID_VALUE);
4495 else
4497 V0(device->Backend,lock)();
4498 aluMixData(device, buffer, samples);
4499 V0(device->Backend,unlock)();
4501 if(device) ALCdevice_DecRef(device);
4505 /************************************************
4506 * ALC loopback2 functions
4507 ************************************************/
4509 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4511 ALCboolean ret = ALC_FALSE;
4513 if(!VerifyDevice(&device) || device->Type != Loopback)
4514 alcSetError(device, ALC_INVALID_DEVICE);
4515 else if(order <= 0)
4516 alcSetError(device, ALC_INVALID_VALUE);
4517 else
4519 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4520 ret = ALC_TRUE;
4522 if(device) ALCdevice_DecRef(device);
4524 return ret;
4527 /************************************************
4528 * ALC DSP pause/resume functions
4529 ************************************************/
4531 /* alcDevicePauseSOFT
4533 * Pause the DSP to stop audio processing.
4535 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4537 if(!VerifyDevice(&device) || device->Type != Playback)
4538 alcSetError(device, ALC_INVALID_DEVICE);
4539 else
4541 almtx_lock(&device->BackendLock);
4542 if((device->Flags&DEVICE_RUNNING))
4543 V0(device->Backend,stop)();
4544 device->Flags &= ~DEVICE_RUNNING;
4545 device->Flags |= DEVICE_PAUSED;
4546 almtx_unlock(&device->BackendLock);
4548 if(device) ALCdevice_DecRef(device);
4551 /* alcDeviceResumeSOFT
4553 * Resume the DSP to restart audio processing.
4555 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4557 if(!VerifyDevice(&device) || device->Type != Playback)
4558 alcSetError(device, ALC_INVALID_DEVICE);
4559 else
4561 almtx_lock(&device->BackendLock);
4562 if((device->Flags&DEVICE_PAUSED))
4564 device->Flags &= ~DEVICE_PAUSED;
4565 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4567 if(V0(device->Backend,start)() != ALC_FALSE)
4568 device->Flags |= DEVICE_RUNNING;
4569 else
4571 alcSetError(device, ALC_INVALID_DEVICE);
4572 V0(device->Backend,lock)();
4573 aluHandleDisconnect(device);
4574 V0(device->Backend,unlock)();
4578 almtx_unlock(&device->BackendLock);
4580 if(device) ALCdevice_DecRef(device);
4584 /************************************************
4585 * ALC HRTF functions
4586 ************************************************/
4588 /* alcGetStringiSOFT
4590 * Gets a string parameter at the given index.
4592 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4594 const ALCchar *str = NULL;
4596 if(!VerifyDevice(&device) || device->Type == Capture)
4597 alcSetError(device, ALC_INVALID_DEVICE);
4598 else switch(paramName)
4600 case ALC_HRTF_SPECIFIER_SOFT:
4601 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList))
4602 str = alstr_get_cstr(VECTOR_ELEM(device->HrtfList, index).name);
4603 else
4604 alcSetError(device, ALC_INVALID_VALUE);
4605 break;
4607 default:
4608 alcSetError(device, ALC_INVALID_ENUM);
4609 break;
4611 if(device) ALCdevice_DecRef(device);
4613 return str;
4616 /* alcResetDeviceSOFT
4618 * Resets the given device output, using the specified attribute list.
4620 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4622 ALCenum err;
4624 LockLists();
4625 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4627 UnlockLists();
4628 alcSetError(device, ALC_INVALID_DEVICE);
4629 if(device) ALCdevice_DecRef(device);
4630 return ALC_FALSE;
4632 almtx_lock(&device->BackendLock);
4633 UnlockLists();
4635 err = UpdateDeviceParams(device, attribs);
4636 almtx_unlock(&device->BackendLock);
4638 if(err != ALC_NO_ERROR)
4640 alcSetError(device, err);
4641 if(err == ALC_INVALID_DEVICE)
4643 V0(device->Backend,lock)();
4644 aluHandleDisconnect(device);
4645 V0(device->Backend,unlock)();
4647 ALCdevice_DecRef(device);
4648 return ALC_FALSE;
4650 ALCdevice_DecRef(device);
4652 return ALC_TRUE;