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