Make the voice's source pointer atomic
[openal-soft.git] / Alc / ALc.c
blob42e1cea004ab113b2a7eba504461d56583c844c6
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include "version.h"
25 #include <math.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <memory.h>
29 #include <ctype.h>
30 #include <signal.h>
32 #include "alMain.h"
33 #include "alSource.h"
34 #include "alListener.h"
35 #include "alThunk.h"
36 #include "alSource.h"
37 #include "alBuffer.h"
38 #include "alAuxEffectSlot.h"
39 #include "alError.h"
40 #include "bformatdec.h"
41 #include "alu.h"
43 #include "compat.h"
44 #include "threads.h"
45 #include "alstring.h"
46 #include "almalloc.h"
48 #include "backends/base.h"
51 /************************************************
52 * Backends
53 ************************************************/
54 struct BackendInfo {
55 const char *name;
56 ALCbackendFactory* (*getFactory)(void);
57 ALCboolean (*Init)(BackendFuncs*);
58 void (*Deinit)(void);
59 void (*Probe)(enum DevProbe);
60 BackendFuncs Funcs;
63 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
64 static struct BackendInfo BackendList[] = {
65 #ifdef HAVE_JACK
66 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
67 #endif
68 #ifdef HAVE_PULSEAUDIO
69 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
70 #endif
71 #ifdef HAVE_ALSA
72 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
73 #endif
74 #ifdef HAVE_COREAUDIO
75 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
76 #endif
77 #ifdef HAVE_OSS
78 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
79 #endif
80 #ifdef HAVE_SOLARIS
81 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
82 #endif
83 #ifdef HAVE_SNDIO
84 { "sndio", ALCsndioBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
85 #endif
86 #ifdef HAVE_QSA
87 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
88 #endif
89 #ifdef HAVE_MMDEVAPI
90 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
91 #endif
92 #ifdef HAVE_DSOUND
93 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
94 #endif
95 #ifdef HAVE_WINMM
96 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
97 #endif
98 #ifdef HAVE_PORTAUDIO
99 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
100 #endif
101 #ifdef HAVE_OPENSL
102 { "opensl", ALCopenslBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
103 #endif
105 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
106 #ifdef HAVE_WAVE
107 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
108 #endif
110 static ALsizei BackendListSize = COUNTOF(BackendList);
111 #undef EmptyFuncs
113 static struct BackendInfo PlaybackBackend;
114 static struct BackendInfo CaptureBackend;
117 /************************************************
118 * Functions, enums, and errors
119 ************************************************/
120 typedef struct ALCfunction {
121 const ALCchar *funcName;
122 ALCvoid *address;
123 } ALCfunction;
125 typedef struct ALCenums {
126 const ALCchar *enumName;
127 ALCenum value;
128 } ALCenums;
130 #define DECL(x) { #x, (ALCvoid*)(x) }
131 static const ALCfunction alcFunctions[] = {
132 DECL(alcCreateContext),
133 DECL(alcMakeContextCurrent),
134 DECL(alcProcessContext),
135 DECL(alcSuspendContext),
136 DECL(alcDestroyContext),
137 DECL(alcGetCurrentContext),
138 DECL(alcGetContextsDevice),
139 DECL(alcOpenDevice),
140 DECL(alcCloseDevice),
141 DECL(alcGetError),
142 DECL(alcIsExtensionPresent),
143 DECL(alcGetProcAddress),
144 DECL(alcGetEnumValue),
145 DECL(alcGetString),
146 DECL(alcGetIntegerv),
147 DECL(alcCaptureOpenDevice),
148 DECL(alcCaptureCloseDevice),
149 DECL(alcCaptureStart),
150 DECL(alcCaptureStop),
151 DECL(alcCaptureSamples),
153 DECL(alcSetThreadContext),
154 DECL(alcGetThreadContext),
156 DECL(alcLoopbackOpenDeviceSOFT),
157 DECL(alcIsRenderFormatSupportedSOFT),
158 DECL(alcRenderSamplesSOFT),
160 DECL(alcIsAmbisonicFormatSupportedSOFT),
162 DECL(alcDevicePauseSOFT),
163 DECL(alcDeviceResumeSOFT),
165 DECL(alcGetStringiSOFT),
166 DECL(alcResetDeviceSOFT),
168 DECL(alcGetInteger64vSOFT),
170 DECL(alEnable),
171 DECL(alDisable),
172 DECL(alIsEnabled),
173 DECL(alGetString),
174 DECL(alGetBooleanv),
175 DECL(alGetIntegerv),
176 DECL(alGetFloatv),
177 DECL(alGetDoublev),
178 DECL(alGetBoolean),
179 DECL(alGetInteger),
180 DECL(alGetFloat),
181 DECL(alGetDouble),
182 DECL(alGetError),
183 DECL(alIsExtensionPresent),
184 DECL(alGetProcAddress),
185 DECL(alGetEnumValue),
186 DECL(alListenerf),
187 DECL(alListener3f),
188 DECL(alListenerfv),
189 DECL(alListeneri),
190 DECL(alListener3i),
191 DECL(alListeneriv),
192 DECL(alGetListenerf),
193 DECL(alGetListener3f),
194 DECL(alGetListenerfv),
195 DECL(alGetListeneri),
196 DECL(alGetListener3i),
197 DECL(alGetListeneriv),
198 DECL(alGenSources),
199 DECL(alDeleteSources),
200 DECL(alIsSource),
201 DECL(alSourcef),
202 DECL(alSource3f),
203 DECL(alSourcefv),
204 DECL(alSourcei),
205 DECL(alSource3i),
206 DECL(alSourceiv),
207 DECL(alGetSourcef),
208 DECL(alGetSource3f),
209 DECL(alGetSourcefv),
210 DECL(alGetSourcei),
211 DECL(alGetSource3i),
212 DECL(alGetSourceiv),
213 DECL(alSourcePlayv),
214 DECL(alSourceStopv),
215 DECL(alSourceRewindv),
216 DECL(alSourcePausev),
217 DECL(alSourcePlay),
218 DECL(alSourceStop),
219 DECL(alSourceRewind),
220 DECL(alSourcePause),
221 DECL(alSourceQueueBuffers),
222 DECL(alSourceUnqueueBuffers),
223 DECL(alGenBuffers),
224 DECL(alDeleteBuffers),
225 DECL(alIsBuffer),
226 DECL(alBufferData),
227 DECL(alBufferf),
228 DECL(alBuffer3f),
229 DECL(alBufferfv),
230 DECL(alBufferi),
231 DECL(alBuffer3i),
232 DECL(alBufferiv),
233 DECL(alGetBufferf),
234 DECL(alGetBuffer3f),
235 DECL(alGetBufferfv),
236 DECL(alGetBufferi),
237 DECL(alGetBuffer3i),
238 DECL(alGetBufferiv),
239 DECL(alDopplerFactor),
240 DECL(alDopplerVelocity),
241 DECL(alSpeedOfSound),
242 DECL(alDistanceModel),
244 DECL(alGenFilters),
245 DECL(alDeleteFilters),
246 DECL(alIsFilter),
247 DECL(alFilteri),
248 DECL(alFilteriv),
249 DECL(alFilterf),
250 DECL(alFilterfv),
251 DECL(alGetFilteri),
252 DECL(alGetFilteriv),
253 DECL(alGetFilterf),
254 DECL(alGetFilterfv),
255 DECL(alGenEffects),
256 DECL(alDeleteEffects),
257 DECL(alIsEffect),
258 DECL(alEffecti),
259 DECL(alEffectiv),
260 DECL(alEffectf),
261 DECL(alEffectfv),
262 DECL(alGetEffecti),
263 DECL(alGetEffectiv),
264 DECL(alGetEffectf),
265 DECL(alGetEffectfv),
266 DECL(alGenAuxiliaryEffectSlots),
267 DECL(alDeleteAuxiliaryEffectSlots),
268 DECL(alIsAuxiliaryEffectSlot),
269 DECL(alAuxiliaryEffectSloti),
270 DECL(alAuxiliaryEffectSlotiv),
271 DECL(alAuxiliaryEffectSlotf),
272 DECL(alAuxiliaryEffectSlotfv),
273 DECL(alGetAuxiliaryEffectSloti),
274 DECL(alGetAuxiliaryEffectSlotiv),
275 DECL(alGetAuxiliaryEffectSlotf),
276 DECL(alGetAuxiliaryEffectSlotfv),
278 DECL(alDeferUpdatesSOFT),
279 DECL(alProcessUpdatesSOFT),
281 DECL(alSourcedSOFT),
282 DECL(alSource3dSOFT),
283 DECL(alSourcedvSOFT),
284 DECL(alGetSourcedSOFT),
285 DECL(alGetSource3dSOFT),
286 DECL(alGetSourcedvSOFT),
287 DECL(alSourcei64SOFT),
288 DECL(alSource3i64SOFT),
289 DECL(alSourcei64vSOFT),
290 DECL(alGetSourcei64SOFT),
291 DECL(alGetSource3i64SOFT),
292 DECL(alGetSourcei64vSOFT),
294 DECL(alBufferSamplesSOFT),
295 DECL(alGetBufferSamplesSOFT),
296 DECL(alIsBufferFormatSupportedSOFT),
298 { NULL, NULL }
300 #undef DECL
302 #define DECL(x) { #x, (x) }
303 static const ALCenums enumeration[] = {
304 DECL(ALC_INVALID),
305 DECL(ALC_FALSE),
306 DECL(ALC_TRUE),
308 DECL(ALC_MAJOR_VERSION),
309 DECL(ALC_MINOR_VERSION),
310 DECL(ALC_ATTRIBUTES_SIZE),
311 DECL(ALC_ALL_ATTRIBUTES),
312 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
313 DECL(ALC_DEVICE_SPECIFIER),
314 DECL(ALC_ALL_DEVICES_SPECIFIER),
315 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
316 DECL(ALC_EXTENSIONS),
317 DECL(ALC_FREQUENCY),
318 DECL(ALC_REFRESH),
319 DECL(ALC_SYNC),
320 DECL(ALC_MONO_SOURCES),
321 DECL(ALC_STEREO_SOURCES),
322 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
323 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
324 DECL(ALC_CAPTURE_SAMPLES),
325 DECL(ALC_CONNECTED),
327 DECL(ALC_EFX_MAJOR_VERSION),
328 DECL(ALC_EFX_MINOR_VERSION),
329 DECL(ALC_MAX_AUXILIARY_SENDS),
331 DECL(ALC_FORMAT_CHANNELS_SOFT),
332 DECL(ALC_FORMAT_TYPE_SOFT),
334 DECL(ALC_MONO_SOFT),
335 DECL(ALC_STEREO_SOFT),
336 DECL(ALC_QUAD_SOFT),
337 DECL(ALC_5POINT1_SOFT),
338 DECL(ALC_6POINT1_SOFT),
339 DECL(ALC_7POINT1_SOFT),
340 DECL(ALC_BFORMAT3D_SOFT),
342 DECL(ALC_BYTE_SOFT),
343 DECL(ALC_UNSIGNED_BYTE_SOFT),
344 DECL(ALC_SHORT_SOFT),
345 DECL(ALC_UNSIGNED_SHORT_SOFT),
346 DECL(ALC_INT_SOFT),
347 DECL(ALC_UNSIGNED_INT_SOFT),
348 DECL(ALC_FLOAT_SOFT),
350 DECL(ALC_HRTF_SOFT),
351 DECL(ALC_DONT_CARE_SOFT),
352 DECL(ALC_HRTF_STATUS_SOFT),
353 DECL(ALC_HRTF_DISABLED_SOFT),
354 DECL(ALC_HRTF_ENABLED_SOFT),
355 DECL(ALC_HRTF_DENIED_SOFT),
356 DECL(ALC_HRTF_REQUIRED_SOFT),
357 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
358 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
359 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
360 DECL(ALC_HRTF_SPECIFIER_SOFT),
361 DECL(ALC_HRTF_ID_SOFT),
363 DECL(ALC_AMBISONIC_LAYOUT_SOFT),
364 DECL(ALC_AMBISONIC_SCALING_SOFT),
365 DECL(ALC_AMBISONIC_ORDER_SOFT),
366 DECL(ALC_ACN_SOFT),
367 DECL(ALC_FUMA_SOFT),
368 DECL(ALC_N3D_SOFT),
369 DECL(ALC_SN3D_SOFT),
371 DECL(ALC_NO_ERROR),
372 DECL(ALC_INVALID_DEVICE),
373 DECL(ALC_INVALID_CONTEXT),
374 DECL(ALC_INVALID_ENUM),
375 DECL(ALC_INVALID_VALUE),
376 DECL(ALC_OUT_OF_MEMORY),
379 DECL(AL_INVALID),
380 DECL(AL_NONE),
381 DECL(AL_FALSE),
382 DECL(AL_TRUE),
384 DECL(AL_SOURCE_RELATIVE),
385 DECL(AL_CONE_INNER_ANGLE),
386 DECL(AL_CONE_OUTER_ANGLE),
387 DECL(AL_PITCH),
388 DECL(AL_POSITION),
389 DECL(AL_DIRECTION),
390 DECL(AL_VELOCITY),
391 DECL(AL_LOOPING),
392 DECL(AL_BUFFER),
393 DECL(AL_GAIN),
394 DECL(AL_MIN_GAIN),
395 DECL(AL_MAX_GAIN),
396 DECL(AL_ORIENTATION),
397 DECL(AL_REFERENCE_DISTANCE),
398 DECL(AL_ROLLOFF_FACTOR),
399 DECL(AL_CONE_OUTER_GAIN),
400 DECL(AL_MAX_DISTANCE),
401 DECL(AL_SEC_OFFSET),
402 DECL(AL_SAMPLE_OFFSET),
403 DECL(AL_BYTE_OFFSET),
404 DECL(AL_SOURCE_TYPE),
405 DECL(AL_STATIC),
406 DECL(AL_STREAMING),
407 DECL(AL_UNDETERMINED),
408 DECL(AL_METERS_PER_UNIT),
409 DECL(AL_LOOP_POINTS_SOFT),
410 DECL(AL_DIRECT_CHANNELS_SOFT),
412 DECL(AL_DIRECT_FILTER),
413 DECL(AL_AUXILIARY_SEND_FILTER),
414 DECL(AL_AIR_ABSORPTION_FACTOR),
415 DECL(AL_ROOM_ROLLOFF_FACTOR),
416 DECL(AL_CONE_OUTER_GAINHF),
417 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
418 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
419 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
421 DECL(AL_SOURCE_STATE),
422 DECL(AL_INITIAL),
423 DECL(AL_PLAYING),
424 DECL(AL_PAUSED),
425 DECL(AL_STOPPED),
427 DECL(AL_BUFFERS_QUEUED),
428 DECL(AL_BUFFERS_PROCESSED),
430 DECL(AL_FORMAT_MONO8),
431 DECL(AL_FORMAT_MONO16),
432 DECL(AL_FORMAT_MONO_FLOAT32),
433 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
434 DECL(AL_FORMAT_STEREO8),
435 DECL(AL_FORMAT_STEREO16),
436 DECL(AL_FORMAT_STEREO_FLOAT32),
437 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
438 DECL(AL_FORMAT_MONO_IMA4),
439 DECL(AL_FORMAT_STEREO_IMA4),
440 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
441 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
442 DECL(AL_FORMAT_QUAD8_LOKI),
443 DECL(AL_FORMAT_QUAD16_LOKI),
444 DECL(AL_FORMAT_QUAD8),
445 DECL(AL_FORMAT_QUAD16),
446 DECL(AL_FORMAT_QUAD32),
447 DECL(AL_FORMAT_51CHN8),
448 DECL(AL_FORMAT_51CHN16),
449 DECL(AL_FORMAT_51CHN32),
450 DECL(AL_FORMAT_61CHN8),
451 DECL(AL_FORMAT_61CHN16),
452 DECL(AL_FORMAT_61CHN32),
453 DECL(AL_FORMAT_71CHN8),
454 DECL(AL_FORMAT_71CHN16),
455 DECL(AL_FORMAT_71CHN32),
456 DECL(AL_FORMAT_REAR8),
457 DECL(AL_FORMAT_REAR16),
458 DECL(AL_FORMAT_REAR32),
459 DECL(AL_FORMAT_MONO_MULAW),
460 DECL(AL_FORMAT_MONO_MULAW_EXT),
461 DECL(AL_FORMAT_STEREO_MULAW),
462 DECL(AL_FORMAT_STEREO_MULAW_EXT),
463 DECL(AL_FORMAT_QUAD_MULAW),
464 DECL(AL_FORMAT_51CHN_MULAW),
465 DECL(AL_FORMAT_61CHN_MULAW),
466 DECL(AL_FORMAT_71CHN_MULAW),
467 DECL(AL_FORMAT_REAR_MULAW),
468 DECL(AL_FORMAT_MONO_ALAW_EXT),
469 DECL(AL_FORMAT_STEREO_ALAW_EXT),
471 DECL(AL_FORMAT_BFORMAT2D_8),
472 DECL(AL_FORMAT_BFORMAT2D_16),
473 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
474 DECL(AL_FORMAT_BFORMAT2D_MULAW),
475 DECL(AL_FORMAT_BFORMAT3D_8),
476 DECL(AL_FORMAT_BFORMAT3D_16),
477 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
478 DECL(AL_FORMAT_BFORMAT3D_MULAW),
480 DECL(AL_MONO8_SOFT),
481 DECL(AL_MONO16_SOFT),
482 DECL(AL_MONO32F_SOFT),
483 DECL(AL_STEREO8_SOFT),
484 DECL(AL_STEREO16_SOFT),
485 DECL(AL_STEREO32F_SOFT),
486 DECL(AL_QUAD8_SOFT),
487 DECL(AL_QUAD16_SOFT),
488 DECL(AL_QUAD32F_SOFT),
489 DECL(AL_REAR8_SOFT),
490 DECL(AL_REAR16_SOFT),
491 DECL(AL_REAR32F_SOFT),
492 DECL(AL_5POINT1_8_SOFT),
493 DECL(AL_5POINT1_16_SOFT),
494 DECL(AL_5POINT1_32F_SOFT),
495 DECL(AL_6POINT1_8_SOFT),
496 DECL(AL_6POINT1_16_SOFT),
497 DECL(AL_6POINT1_32F_SOFT),
498 DECL(AL_7POINT1_8_SOFT),
499 DECL(AL_7POINT1_16_SOFT),
500 DECL(AL_7POINT1_32F_SOFT),
501 DECL(AL_BFORMAT2D_8_SOFT),
502 DECL(AL_BFORMAT2D_16_SOFT),
503 DECL(AL_BFORMAT2D_32F_SOFT),
504 DECL(AL_BFORMAT3D_8_SOFT),
505 DECL(AL_BFORMAT3D_16_SOFT),
506 DECL(AL_BFORMAT3D_32F_SOFT),
508 DECL(AL_MONO_SOFT),
509 DECL(AL_STEREO_SOFT),
510 DECL(AL_QUAD_SOFT),
511 DECL(AL_REAR_SOFT),
512 DECL(AL_5POINT1_SOFT),
513 DECL(AL_6POINT1_SOFT),
514 DECL(AL_7POINT1_SOFT),
515 DECL(AL_BFORMAT2D_SOFT),
516 DECL(AL_BFORMAT3D_SOFT),
518 DECL(AL_BYTE_SOFT),
519 DECL(AL_UNSIGNED_BYTE_SOFT),
520 DECL(AL_SHORT_SOFT),
521 DECL(AL_UNSIGNED_SHORT_SOFT),
522 DECL(AL_INT_SOFT),
523 DECL(AL_UNSIGNED_INT_SOFT),
524 DECL(AL_FLOAT_SOFT),
525 DECL(AL_DOUBLE_SOFT),
526 DECL(AL_BYTE3_SOFT),
527 DECL(AL_UNSIGNED_BYTE3_SOFT),
528 DECL(AL_MULAW_SOFT),
530 DECL(AL_FREQUENCY),
531 DECL(AL_BITS),
532 DECL(AL_CHANNELS),
533 DECL(AL_SIZE),
534 DECL(AL_INTERNAL_FORMAT_SOFT),
535 DECL(AL_BYTE_LENGTH_SOFT),
536 DECL(AL_SAMPLE_LENGTH_SOFT),
537 DECL(AL_SEC_LENGTH_SOFT),
538 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
539 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
541 DECL(AL_SOURCE_RADIUS),
543 DECL(AL_STEREO_ANGLES),
545 DECL(AL_UNUSED),
546 DECL(AL_PENDING),
547 DECL(AL_PROCESSED),
549 DECL(AL_NO_ERROR),
550 DECL(AL_INVALID_NAME),
551 DECL(AL_INVALID_ENUM),
552 DECL(AL_INVALID_VALUE),
553 DECL(AL_INVALID_OPERATION),
554 DECL(AL_OUT_OF_MEMORY),
556 DECL(AL_VENDOR),
557 DECL(AL_VERSION),
558 DECL(AL_RENDERER),
559 DECL(AL_EXTENSIONS),
561 DECL(AL_DOPPLER_FACTOR),
562 DECL(AL_DOPPLER_VELOCITY),
563 DECL(AL_DISTANCE_MODEL),
564 DECL(AL_SPEED_OF_SOUND),
565 DECL(AL_SOURCE_DISTANCE_MODEL),
566 DECL(AL_DEFERRED_UPDATES_SOFT),
567 DECL(AL_GAIN_LIMIT_SOFT),
569 DECL(AL_INVERSE_DISTANCE),
570 DECL(AL_INVERSE_DISTANCE_CLAMPED),
571 DECL(AL_LINEAR_DISTANCE),
572 DECL(AL_LINEAR_DISTANCE_CLAMPED),
573 DECL(AL_EXPONENT_DISTANCE),
574 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
576 DECL(AL_FILTER_TYPE),
577 DECL(AL_FILTER_NULL),
578 DECL(AL_FILTER_LOWPASS),
579 DECL(AL_FILTER_HIGHPASS),
580 DECL(AL_FILTER_BANDPASS),
582 DECL(AL_LOWPASS_GAIN),
583 DECL(AL_LOWPASS_GAINHF),
585 DECL(AL_HIGHPASS_GAIN),
586 DECL(AL_HIGHPASS_GAINLF),
588 DECL(AL_BANDPASS_GAIN),
589 DECL(AL_BANDPASS_GAINHF),
590 DECL(AL_BANDPASS_GAINLF),
592 DECL(AL_EFFECT_TYPE),
593 DECL(AL_EFFECT_NULL),
594 DECL(AL_EFFECT_REVERB),
595 DECL(AL_EFFECT_EAXREVERB),
596 DECL(AL_EFFECT_CHORUS),
597 DECL(AL_EFFECT_DISTORTION),
598 DECL(AL_EFFECT_ECHO),
599 DECL(AL_EFFECT_FLANGER),
600 #if 0
601 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
602 DECL(AL_EFFECT_VOCAL_MORPHER),
603 DECL(AL_EFFECT_PITCH_SHIFTER),
604 #endif
605 DECL(AL_EFFECT_RING_MODULATOR),
606 #if 0
607 DECL(AL_EFFECT_AUTOWAH),
608 #endif
609 DECL(AL_EFFECT_COMPRESSOR),
610 DECL(AL_EFFECT_EQUALIZER),
611 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
612 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
614 DECL(AL_EFFECTSLOT_EFFECT),
615 DECL(AL_EFFECTSLOT_GAIN),
616 DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
617 DECL(AL_EFFECTSLOT_NULL),
619 DECL(AL_EAXREVERB_DENSITY),
620 DECL(AL_EAXREVERB_DIFFUSION),
621 DECL(AL_EAXREVERB_GAIN),
622 DECL(AL_EAXREVERB_GAINHF),
623 DECL(AL_EAXREVERB_GAINLF),
624 DECL(AL_EAXREVERB_DECAY_TIME),
625 DECL(AL_EAXREVERB_DECAY_HFRATIO),
626 DECL(AL_EAXREVERB_DECAY_LFRATIO),
627 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
628 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
629 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
630 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
631 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
632 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
633 DECL(AL_EAXREVERB_ECHO_TIME),
634 DECL(AL_EAXREVERB_ECHO_DEPTH),
635 DECL(AL_EAXREVERB_MODULATION_TIME),
636 DECL(AL_EAXREVERB_MODULATION_DEPTH),
637 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
638 DECL(AL_EAXREVERB_HFREFERENCE),
639 DECL(AL_EAXREVERB_LFREFERENCE),
640 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
641 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
643 DECL(AL_REVERB_DENSITY),
644 DECL(AL_REVERB_DIFFUSION),
645 DECL(AL_REVERB_GAIN),
646 DECL(AL_REVERB_GAINHF),
647 DECL(AL_REVERB_DECAY_TIME),
648 DECL(AL_REVERB_DECAY_HFRATIO),
649 DECL(AL_REVERB_REFLECTIONS_GAIN),
650 DECL(AL_REVERB_REFLECTIONS_DELAY),
651 DECL(AL_REVERB_LATE_REVERB_GAIN),
652 DECL(AL_REVERB_LATE_REVERB_DELAY),
653 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
654 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
655 DECL(AL_REVERB_DECAY_HFLIMIT),
657 DECL(AL_CHORUS_WAVEFORM),
658 DECL(AL_CHORUS_PHASE),
659 DECL(AL_CHORUS_RATE),
660 DECL(AL_CHORUS_DEPTH),
661 DECL(AL_CHORUS_FEEDBACK),
662 DECL(AL_CHORUS_DELAY),
664 DECL(AL_DISTORTION_EDGE),
665 DECL(AL_DISTORTION_GAIN),
666 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
667 DECL(AL_DISTORTION_EQCENTER),
668 DECL(AL_DISTORTION_EQBANDWIDTH),
670 DECL(AL_ECHO_DELAY),
671 DECL(AL_ECHO_LRDELAY),
672 DECL(AL_ECHO_DAMPING),
673 DECL(AL_ECHO_FEEDBACK),
674 DECL(AL_ECHO_SPREAD),
676 DECL(AL_FLANGER_WAVEFORM),
677 DECL(AL_FLANGER_PHASE),
678 DECL(AL_FLANGER_RATE),
679 DECL(AL_FLANGER_DEPTH),
680 DECL(AL_FLANGER_FEEDBACK),
681 DECL(AL_FLANGER_DELAY),
683 DECL(AL_RING_MODULATOR_FREQUENCY),
684 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
685 DECL(AL_RING_MODULATOR_WAVEFORM),
687 DECL(AL_COMPRESSOR_ONOFF),
689 DECL(AL_EQUALIZER_LOW_GAIN),
690 DECL(AL_EQUALIZER_LOW_CUTOFF),
691 DECL(AL_EQUALIZER_MID1_GAIN),
692 DECL(AL_EQUALIZER_MID1_CENTER),
693 DECL(AL_EQUALIZER_MID1_WIDTH),
694 DECL(AL_EQUALIZER_MID2_GAIN),
695 DECL(AL_EQUALIZER_MID2_CENTER),
696 DECL(AL_EQUALIZER_MID2_WIDTH),
697 DECL(AL_EQUALIZER_HIGH_GAIN),
698 DECL(AL_EQUALIZER_HIGH_CUTOFF),
700 DECL(AL_DEDICATED_GAIN),
702 { NULL, (ALCenum)0 }
704 #undef DECL
706 static const ALCchar alcNoError[] = "No Error";
707 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
708 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
709 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
710 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
711 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
714 /************************************************
715 * Global variables
716 ************************************************/
718 /* Enumerated device names */
719 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
721 static al_string alcAllDevicesList;
722 static al_string alcCaptureDeviceList;
724 /* Default is always the first in the list */
725 static ALCchar *alcDefaultAllDevicesSpecifier;
726 static ALCchar *alcCaptureDefaultDeviceSpecifier;
728 /* Default context extensions */
729 static const ALchar alExtList[] =
730 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
731 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
732 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
733 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
734 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
735 "AL_SOFT_direct_channels AL_SOFT_gain_clamp_ex AL_SOFT_loop_points "
736 "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length";
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_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 if(BackendList[i].getFactory)
1091 ALCbackendFactory *factory = BackendList[i].getFactory();
1092 if(!V0(factory,init)())
1094 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1095 continue;
1098 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1099 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1101 PlaybackBackend = BackendList[i];
1102 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1104 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1106 CaptureBackend = BackendList[i];
1107 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1110 continue;
1113 if(!BackendList[i].Init(&BackendList[i].Funcs))
1115 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1116 continue;
1119 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1120 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1122 PlaybackBackend = BackendList[i];
1123 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1125 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1127 CaptureBackend = BackendList[i];
1128 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1132 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1133 V0(factory,init)();
1136 if(!PlaybackBackend.name)
1137 WARN("No playback backend available!\n");
1138 if(!CaptureBackend.name)
1139 WARN("No capture backend available!\n");
1141 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1143 size_t len;
1144 const char *next = str;
1146 do {
1147 str = next;
1148 next = strchr(str, ',');
1150 if(!str[0] || next == str)
1151 continue;
1153 len = (next ? ((size_t)(next-str)) : strlen(str));
1154 for(n = 0;EffectList[n].name;n++)
1156 if(len == strlen(EffectList[n].name) &&
1157 strncmp(EffectList[n].name, str, len) == 0)
1158 DisabledEffects[EffectList[n].type] = AL_TRUE;
1160 } while(next++);
1163 InitEffectFactoryMap();
1165 InitEffect(&DefaultEffect);
1166 str = getenv("ALSOFT_DEFAULT_REVERB");
1167 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1168 LoadReverbPreset(str, &DefaultEffect);
1170 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1172 #ifdef __ANDROID__
1173 #include <jni.h>
1175 static JavaVM *gJavaVM;
1176 static pthread_key_t gJVMThreadKey;
1178 static void CleanupJNIEnv(void* UNUSED(ptr))
1180 JCALL0(gJavaVM,DetachCurrentThread)();
1183 void *Android_GetJNIEnv(void)
1185 if(!gJavaVM)
1187 WARN("gJavaVM is NULL!\n");
1188 return NULL;
1191 /* http://developer.android.com/guide/practices/jni.html
1193 * All threads are Linux threads, scheduled by the kernel. They're usually
1194 * started from managed code (using Thread.start), but they can also be
1195 * created elsewhere and then attached to the JavaVM. For example, a thread
1196 * started with pthread_create can be attached with the JNI
1197 * AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a
1198 * thread is attached, it has no JNIEnv, and cannot make JNI calls.
1199 * Attaching a natively-created thread causes a java.lang.Thread object to
1200 * be constructed and added to the "main" ThreadGroup, making it visible to
1201 * the debugger. Calling AttachCurrentThread on an already-attached thread
1202 * is a no-op.
1204 JNIEnv *env = pthread_getspecific(gJVMThreadKey);
1205 if(!env)
1207 int status = JCALL(gJavaVM,AttachCurrentThread)(&env, NULL);
1208 if(status < 0)
1210 ERR("Failed to attach current thread\n");
1211 return NULL;
1213 pthread_setspecific(gJVMThreadKey, env);
1215 return env;
1218 /* Automatically called by JNI. */
1219 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void* UNUSED(reserved))
1221 void *env;
1222 int err;
1224 gJavaVM = jvm;
1225 if(JCALL(gJavaVM,GetEnv)(&env, JNI_VERSION_1_4) != JNI_OK)
1227 ERR("Failed to get JNIEnv with JNI_VERSION_1_4\n");
1228 return JNI_ERR;
1231 /* Create gJVMThreadKey so we can keep track of the JNIEnv assigned to each
1232 * thread. The JNIEnv *must* be detached before the thread is destroyed.
1234 if((err=pthread_key_create(&gJVMThreadKey, CleanupJNIEnv)) != 0)
1235 ERR("pthread_key_create failed: %d\n", err);
1236 pthread_setspecific(gJVMThreadKey, env);
1237 return JNI_VERSION_1_4;
1240 #endif
1243 /************************************************
1244 * Library deinitialization
1245 ************************************************/
1246 static void alc_cleanup(void)
1248 ALCdevice *dev;
1250 AL_STRING_DEINIT(alcAllDevicesList);
1251 AL_STRING_DEINIT(alcCaptureDeviceList);
1253 free(alcDefaultAllDevicesSpecifier);
1254 alcDefaultAllDevicesSpecifier = NULL;
1255 free(alcCaptureDefaultDeviceSpecifier);
1256 alcCaptureDefaultDeviceSpecifier = NULL;
1258 if((dev=ATOMIC_EXCHANGE_SEQ(ALCdevice*, &DeviceList, NULL)) != NULL)
1260 ALCuint num = 0;
1261 do {
1262 num++;
1263 } while((dev=dev->next) != NULL);
1264 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1267 DeinitEffectFactoryMap();
1270 static void alc_deinit_safe(void)
1272 alc_cleanup();
1274 FreeHrtfs();
1275 FreeALConfig();
1277 ThunkExit();
1278 almtx_destroy(&ListLock);
1279 altss_delete(LocalContext);
1281 if(LogFile != stderr)
1282 fclose(LogFile);
1283 LogFile = NULL;
1286 static void alc_deinit(void)
1288 int i;
1290 alc_cleanup();
1292 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1293 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1295 for(i = 0;i < BackendListSize;i++)
1297 if(!BackendList[i].getFactory)
1298 BackendList[i].Deinit();
1299 else
1301 ALCbackendFactory *factory = BackendList[i].getFactory();
1302 V0(factory,deinit)();
1306 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1307 V0(factory,deinit)();
1310 alc_deinit_safe();
1314 /************************************************
1315 * Device enumeration
1316 ************************************************/
1317 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1319 DO_INITCONFIG();
1321 LockLists();
1322 al_string_clear(list);
1324 if(backendinfo->Probe)
1325 backendinfo->Probe(type);
1326 else if(backendinfo->getFactory)
1328 ALCbackendFactory *factory = backendinfo->getFactory();
1329 V(factory,probe)(type);
1332 UnlockLists();
1334 static void ProbeAllDevicesList(void)
1335 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1336 static void ProbeCaptureDeviceList(void)
1337 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1339 static void AppendDevice(const ALCchar *name, al_string *devnames)
1341 size_t len = strlen(name);
1342 if(len > 0)
1343 al_string_append_range(devnames, name, name+len+1);
1345 void AppendAllDevicesList(const ALCchar *name)
1346 { AppendDevice(name, &alcAllDevicesList); }
1347 void AppendCaptureDeviceList(const ALCchar *name)
1348 { AppendDevice(name, &alcCaptureDeviceList); }
1351 /************************************************
1352 * Device format information
1353 ************************************************/
1354 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1356 switch(type)
1358 case DevFmtByte: return "Signed Byte";
1359 case DevFmtUByte: return "Unsigned Byte";
1360 case DevFmtShort: return "Signed Short";
1361 case DevFmtUShort: return "Unsigned Short";
1362 case DevFmtInt: return "Signed Int";
1363 case DevFmtUInt: return "Unsigned Int";
1364 case DevFmtFloat: return "Float";
1366 return "(unknown type)";
1368 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1370 switch(chans)
1372 case DevFmtMono: return "Mono";
1373 case DevFmtStereo: return "Stereo";
1374 case DevFmtQuad: return "Quadraphonic";
1375 case DevFmtX51: return "5.1 Surround";
1376 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1377 case DevFmtX61: return "6.1 Surround";
1378 case DevFmtX71: return "7.1 Surround";
1379 case DevFmtAmbi1: return "Ambisonic (1st Order)";
1380 case DevFmtAmbi2: return "Ambisonic (2nd Order)";
1381 case DevFmtAmbi3: return "Ambisonic (3rd Order)";
1383 return "(unknown channels)";
1386 extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1387 ALsizei BytesFromDevFmt(enum DevFmtType type)
1389 switch(type)
1391 case DevFmtByte: return sizeof(ALbyte);
1392 case DevFmtUByte: return sizeof(ALubyte);
1393 case DevFmtShort: return sizeof(ALshort);
1394 case DevFmtUShort: return sizeof(ALushort);
1395 case DevFmtInt: return sizeof(ALint);
1396 case DevFmtUInt: return sizeof(ALuint);
1397 case DevFmtFloat: return sizeof(ALfloat);
1399 return 0;
1401 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans)
1403 switch(chans)
1405 case DevFmtMono: return 1;
1406 case DevFmtStereo: return 2;
1407 case DevFmtQuad: return 4;
1408 case DevFmtX51: return 6;
1409 case DevFmtX51Rear: return 6;
1410 case DevFmtX61: return 7;
1411 case DevFmtX71: return 8;
1412 case DevFmtAmbi1: return 4;
1413 case DevFmtAmbi2: return 9;
1414 case DevFmtAmbi3: return 16;
1416 return 0;
1419 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1420 enum DevFmtType *type)
1422 static const struct {
1423 ALenum format;
1424 enum DevFmtChannels channels;
1425 enum DevFmtType type;
1426 } list[] = {
1427 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1428 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1429 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1431 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1432 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1433 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1435 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1436 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1437 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1439 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1440 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1441 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1443 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1444 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1445 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1447 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1448 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1449 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1451 ALuint i;
1453 for(i = 0;i < COUNTOF(list);i++)
1455 if(list[i].format == format)
1457 *chans = list[i].channels;
1458 *type = list[i].type;
1459 return AL_TRUE;
1463 return AL_FALSE;
1466 static ALCboolean IsValidALCType(ALCenum type)
1468 switch(type)
1470 case ALC_BYTE_SOFT:
1471 case ALC_UNSIGNED_BYTE_SOFT:
1472 case ALC_SHORT_SOFT:
1473 case ALC_UNSIGNED_SHORT_SOFT:
1474 case ALC_INT_SOFT:
1475 case ALC_UNSIGNED_INT_SOFT:
1476 case ALC_FLOAT_SOFT:
1477 return ALC_TRUE;
1479 return ALC_FALSE;
1482 static ALCboolean IsValidALCChannels(ALCenum channels)
1484 switch(channels)
1486 case ALC_MONO_SOFT:
1487 case ALC_STEREO_SOFT:
1488 case ALC_QUAD_SOFT:
1489 case ALC_5POINT1_SOFT:
1490 case ALC_6POINT1_SOFT:
1491 case ALC_7POINT1_SOFT:
1492 case ALC_BFORMAT3D_SOFT:
1493 return ALC_TRUE;
1495 return ALC_FALSE;
1498 static ALCboolean IsValidAmbiLayout(ALCenum layout)
1500 switch(layout)
1502 case ALC_ACN_SOFT:
1503 case ALC_FUMA_SOFT:
1504 return ALC_TRUE;
1506 return ALC_FALSE;
1509 static ALCboolean IsValidAmbiScaling(ALCenum scaling)
1511 switch(scaling)
1513 case ALC_N3D_SOFT:
1514 case ALC_SN3D_SOFT:
1515 case ALC_FUMA_SOFT:
1516 return ALC_TRUE;
1518 return ALC_FALSE;
1521 /************************************************
1522 * Miscellaneous ALC helpers
1523 ************************************************/
1525 void ALCdevice_Lock(ALCdevice *device)
1527 V0(device->Backend,lock)();
1530 void ALCdevice_Unlock(ALCdevice *device)
1532 V0(device->Backend,unlock)();
1536 /* SetDefaultWFXChannelOrder
1538 * Sets the default channel order used by WaveFormatEx.
1540 void SetDefaultWFXChannelOrder(ALCdevice *device)
1542 ALuint i;
1544 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1545 device->RealOut.ChannelName[i] = InvalidChannel;
1547 switch(device->FmtChans)
1549 case DevFmtMono:
1550 device->RealOut.ChannelName[0] = FrontCenter;
1551 break;
1552 case DevFmtStereo:
1553 device->RealOut.ChannelName[0] = FrontLeft;
1554 device->RealOut.ChannelName[1] = FrontRight;
1555 break;
1556 case DevFmtQuad:
1557 device->RealOut.ChannelName[0] = FrontLeft;
1558 device->RealOut.ChannelName[1] = FrontRight;
1559 device->RealOut.ChannelName[2] = BackLeft;
1560 device->RealOut.ChannelName[3] = BackRight;
1561 break;
1562 case DevFmtX51:
1563 device->RealOut.ChannelName[0] = FrontLeft;
1564 device->RealOut.ChannelName[1] = FrontRight;
1565 device->RealOut.ChannelName[2] = FrontCenter;
1566 device->RealOut.ChannelName[3] = LFE;
1567 device->RealOut.ChannelName[4] = SideLeft;
1568 device->RealOut.ChannelName[5] = SideRight;
1569 break;
1570 case DevFmtX51Rear:
1571 device->RealOut.ChannelName[0] = FrontLeft;
1572 device->RealOut.ChannelName[1] = FrontRight;
1573 device->RealOut.ChannelName[2] = FrontCenter;
1574 device->RealOut.ChannelName[3] = LFE;
1575 device->RealOut.ChannelName[4] = BackLeft;
1576 device->RealOut.ChannelName[5] = BackRight;
1577 break;
1578 case DevFmtX61:
1579 device->RealOut.ChannelName[0] = FrontLeft;
1580 device->RealOut.ChannelName[1] = FrontRight;
1581 device->RealOut.ChannelName[2] = FrontCenter;
1582 device->RealOut.ChannelName[3] = LFE;
1583 device->RealOut.ChannelName[4] = BackCenter;
1584 device->RealOut.ChannelName[5] = SideLeft;
1585 device->RealOut.ChannelName[6] = SideRight;
1586 break;
1587 case DevFmtX71:
1588 device->RealOut.ChannelName[0] = FrontLeft;
1589 device->RealOut.ChannelName[1] = FrontRight;
1590 device->RealOut.ChannelName[2] = FrontCenter;
1591 device->RealOut.ChannelName[3] = LFE;
1592 device->RealOut.ChannelName[4] = BackLeft;
1593 device->RealOut.ChannelName[5] = BackRight;
1594 device->RealOut.ChannelName[6] = SideLeft;
1595 device->RealOut.ChannelName[7] = SideRight;
1596 break;
1597 case DevFmtAmbi1:
1598 device->RealOut.ChannelName[0] = Aux0;
1599 device->RealOut.ChannelName[1] = Aux1;
1600 device->RealOut.ChannelName[2] = Aux2;
1601 device->RealOut.ChannelName[3] = Aux3;
1602 break;
1603 case DevFmtAmbi2:
1604 device->RealOut.ChannelName[0] = Aux0;
1605 device->RealOut.ChannelName[1] = Aux1;
1606 device->RealOut.ChannelName[2] = Aux2;
1607 device->RealOut.ChannelName[3] = Aux3;
1608 device->RealOut.ChannelName[4] = Aux4;
1609 device->RealOut.ChannelName[5] = Aux5;
1610 device->RealOut.ChannelName[6] = Aux6;
1611 device->RealOut.ChannelName[7] = Aux7;
1612 device->RealOut.ChannelName[8] = Aux8;
1613 break;
1614 case DevFmtAmbi3:
1615 device->RealOut.ChannelName[0] = Aux0;
1616 device->RealOut.ChannelName[1] = Aux1;
1617 device->RealOut.ChannelName[2] = Aux2;
1618 device->RealOut.ChannelName[3] = Aux3;
1619 device->RealOut.ChannelName[4] = Aux4;
1620 device->RealOut.ChannelName[5] = Aux5;
1621 device->RealOut.ChannelName[6] = Aux6;
1622 device->RealOut.ChannelName[7] = Aux7;
1623 device->RealOut.ChannelName[8] = Aux8;
1624 device->RealOut.ChannelName[9] = Aux9;
1625 device->RealOut.ChannelName[10] = Aux10;
1626 device->RealOut.ChannelName[11] = Aux11;
1627 device->RealOut.ChannelName[12] = Aux12;
1628 device->RealOut.ChannelName[13] = Aux13;
1629 device->RealOut.ChannelName[14] = Aux14;
1630 device->RealOut.ChannelName[15] = Aux15;
1631 break;
1635 /* SetDefaultChannelOrder
1637 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1639 void SetDefaultChannelOrder(ALCdevice *device)
1641 ALuint i;
1643 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1644 device->RealOut.ChannelName[i] = InvalidChannel;
1646 switch(device->FmtChans)
1648 case DevFmtX51Rear:
1649 device->RealOut.ChannelName[0] = FrontLeft;
1650 device->RealOut.ChannelName[1] = FrontRight;
1651 device->RealOut.ChannelName[2] = BackLeft;
1652 device->RealOut.ChannelName[3] = BackRight;
1653 device->RealOut.ChannelName[4] = FrontCenter;
1654 device->RealOut.ChannelName[5] = LFE;
1655 return;
1656 case DevFmtX71:
1657 device->RealOut.ChannelName[0] = FrontLeft;
1658 device->RealOut.ChannelName[1] = FrontRight;
1659 device->RealOut.ChannelName[2] = BackLeft;
1660 device->RealOut.ChannelName[3] = BackRight;
1661 device->RealOut.ChannelName[4] = FrontCenter;
1662 device->RealOut.ChannelName[5] = LFE;
1663 device->RealOut.ChannelName[6] = SideLeft;
1664 device->RealOut.ChannelName[7] = SideRight;
1665 return;
1667 /* Same as WFX order */
1668 case DevFmtMono:
1669 case DevFmtStereo:
1670 case DevFmtQuad:
1671 case DevFmtX51:
1672 case DevFmtX61:
1673 case DevFmtAmbi1:
1674 case DevFmtAmbi2:
1675 case DevFmtAmbi3:
1676 SetDefaultWFXChannelOrder(device);
1677 break;
1681 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1684 /* ALCcontext_DeferUpdates
1686 * Defers/suspends updates for the given context's listener and sources. This
1687 * does *NOT* stop mixing, but rather prevents certain property changes from
1688 * taking effect.
1690 void ALCcontext_DeferUpdates(ALCcontext *context, ALenum type)
1692 ATOMIC_STORE_SEQ(&context->DeferUpdates, type);
1695 /* ALCcontext_ProcessUpdates
1697 * Resumes update processing after being deferred.
1699 void ALCcontext_ProcessUpdates(ALCcontext *context)
1701 ALCdevice *device = context->Device;
1703 ReadLock(&context->PropLock);
1704 if(ATOMIC_EXCHANGE_SEQ(ALenum, &context->DeferUpdates, AL_FALSE))
1706 ALsizei pos;
1707 uint updates;
1709 /* Tell the mixer to stop applying updates, then wait for any active
1710 * updating to finish, before providing updates.
1712 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1713 while(((updates=ReadRef(&context->UpdateCount))&1) != 0)
1714 althrd_yield();
1716 UpdateListenerProps(context);
1717 UpdateAllEffectSlotProps(context);
1719 LockUIntMapRead(&context->SourceMap);
1720 V0(device->Backend,lock)();
1721 for(pos = 0;pos < context->VoiceCount;pos++)
1723 ALvoice *voice = context->Voices[pos];
1724 ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire);
1725 if(source && source->OffsetType != AL_NONE)
1727 WriteLock(&source->queue_lock);
1728 ApplyOffset(source, voice);
1729 WriteUnlock(&source->queue_lock);
1732 for(pos = 0;pos < context->SourceMap.size;pos++)
1734 ALsource *source = context->SourceMap.values[pos];
1735 ALenum new_state = source->new_state;
1736 source->new_state = AL_NONE;
1737 if(new_state)
1738 SetSourceState(source, context, new_state);
1740 V0(device->Backend,unlock)();
1741 UnlockUIntMapRead(&context->SourceMap);
1743 UpdateAllSourceProps(context);
1745 /* Now with all updates declared, let the mixer continue applying them
1746 * so they all happen at once.
1748 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1750 ReadUnlock(&context->PropLock);
1754 /* alcSetError
1756 * Stores the latest ALC device error
1758 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1760 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1761 if(TrapALCError)
1763 #ifdef _WIN32
1764 /* DebugBreak() will cause an exception if there is no debugger */
1765 if(IsDebuggerPresent())
1766 DebugBreak();
1767 #elif defined(SIGTRAP)
1768 raise(SIGTRAP);
1769 #endif
1772 if(device)
1773 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1774 else
1775 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1779 /* UpdateClockBase
1781 * Updates the device's base clock time with however many samples have been
1782 * done. This is used so frequency changes on the device don't cause the time
1783 * to jump forward or back. Must not be called while the device is running/
1784 * mixing.
1786 static inline void UpdateClockBase(ALCdevice *device)
1788 IncrementRef(&device->MixCount);
1789 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1790 device->SamplesDone = 0;
1791 IncrementRef(&device->MixCount);
1794 /* UpdateDeviceParams
1796 * Updates device parameters according to the attribute list (caller is
1797 * responsible for holding the list lock).
1799 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1801 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1802 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1803 const ALsizei old_sends = device->NumAuxSends;
1804 ALsizei new_sends = device->NumAuxSends;
1805 enum DevFmtChannels oldChans;
1806 enum DevFmtType oldType;
1807 ALboolean update_failed;
1808 ALCsizei hrtf_id = -1;
1809 ALCcontext *context;
1810 ALCuint oldFreq;
1811 FPUCtl oldMode;
1812 size_t size;
1813 ALCsizei i;
1815 // Check for attributes
1816 if(device->Type == Loopback)
1818 ALCsizei numMono, numStereo, numSends;
1819 ALCenum alayout = AL_NONE;
1820 ALCenum ascale = AL_NONE;
1821 ALCenum schans = AL_NONE;
1822 ALCenum stype = AL_NONE;
1823 ALCsizei attrIdx = 0;
1824 ALCsizei aorder = 0;
1825 ALCuint freq = 0;
1827 if(!attrList)
1829 WARN("Missing attributes for loopback device\n");
1830 return ALC_INVALID_VALUE;
1833 numMono = device->NumMonoSources;
1834 numStereo = device->NumStereoSources;
1835 numSends = old_sends;
1837 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1838 while(attrList[attrIdx])
1840 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1842 schans = attrList[attrIdx + 1];
1843 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1844 if(!IsValidALCChannels(schans))
1845 return ALC_INVALID_VALUE;
1848 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1850 stype = attrList[attrIdx + 1];
1851 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1852 if(!IsValidALCType(stype))
1853 return ALC_INVALID_VALUE;
1856 if(attrList[attrIdx] == ALC_FREQUENCY)
1858 freq = attrList[attrIdx + 1];
1859 TRACE_ATTR(ALC_FREQUENCY, freq);
1860 if(freq < MIN_OUTPUT_RATE)
1861 return ALC_INVALID_VALUE;
1864 if(attrList[attrIdx] == ALC_AMBISONIC_LAYOUT_SOFT)
1866 alayout = attrList[attrIdx + 1];
1867 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1868 if(!IsValidAmbiLayout(alayout))
1869 return ALC_INVALID_VALUE;
1872 if(attrList[attrIdx] == ALC_AMBISONIC_SCALING_SOFT)
1874 ascale = attrList[attrIdx + 1];
1875 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1876 if(!IsValidAmbiScaling(ascale))
1877 return ALC_INVALID_VALUE;
1880 if(attrList[attrIdx] == ALC_AMBISONIC_ORDER_SOFT)
1882 aorder = attrList[attrIdx + 1];
1883 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1884 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1885 return ALC_INVALID_VALUE;
1888 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1890 numStereo = attrList[attrIdx + 1];
1891 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1893 numStereo = clampi(numStereo, 0, device->SourcesMax);
1894 numMono = device->SourcesMax - numStereo;
1897 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1899 numSends = attrList[attrIdx + 1];
1900 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1901 numSends = clampi(numSends, 0, MAX_SENDS);
1904 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1906 ALCint val = attrList[attrIdx + 1];
1907 TRACE_ATTR(ALC_HRTF_SOFT, val);
1908 if(val == ALC_FALSE)
1909 hrtf_appreq = Hrtf_Disable;
1910 else if(val == ALC_TRUE)
1911 hrtf_appreq = Hrtf_Enable;
1912 else
1913 hrtf_appreq = Hrtf_Default;
1916 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1918 hrtf_id = attrList[attrIdx + 1];
1919 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1922 attrIdx += 2;
1924 #undef TRACE_ATTR
1926 if(!schans || !stype || !freq)
1928 WARN("Missing format for loopback device\n");
1929 return ALC_INVALID_VALUE;
1931 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1933 WARN("Missing ambisonic info for loopback device\n");
1934 return ALC_INVALID_VALUE;
1937 if((device->Flags&DEVICE_RUNNING))
1938 V0(device->Backend,stop)();
1939 device->Flags &= ~DEVICE_RUNNING;
1941 UpdateClockBase(device);
1943 if(schans == ALC_BFORMAT3D_SOFT)
1945 device->FmtChans = DevFmtAmbi1 + aorder;
1946 device->AmbiLayout = alayout;
1947 device->AmbiScale = ascale;
1949 else
1950 device->FmtChans = schans;
1951 device->Frequency = freq;
1952 device->FmtType = stype;
1953 device->NumMonoSources = numMono;
1954 device->NumStereoSources = numStereo;
1956 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1957 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1958 else
1959 new_sends = numSends;
1961 else if(attrList && attrList[0])
1963 ALCsizei numMono, numStereo, numSends;
1964 ALCsizei attrIdx = 0;
1965 ALCuint freq;
1967 /* If a context is already running on the device, stop playback so the
1968 * device attributes can be updated. */
1969 if((device->Flags&DEVICE_RUNNING))
1970 V0(device->Backend,stop)();
1971 device->Flags &= ~DEVICE_RUNNING;
1973 UpdateClockBase(device);
1975 freq = device->Frequency;
1976 numMono = device->NumMonoSources;
1977 numStereo = device->NumStereoSources;
1978 numSends = old_sends;
1980 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1981 while(attrList[attrIdx])
1983 if(attrList[attrIdx] == ALC_FREQUENCY)
1985 freq = attrList[attrIdx + 1];
1986 TRACE_ATTR(ALC_FREQUENCY, freq);
1987 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1990 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1992 numStereo = attrList[attrIdx + 1];
1993 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1995 numStereo = clampi(numStereo, 0, device->SourcesMax);
1996 numMono = device->SourcesMax - numStereo;
1999 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
2001 numSends = attrList[attrIdx + 1];
2002 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
2003 numSends = clampi(numSends, 0, MAX_SENDS);
2006 if(attrList[attrIdx] == ALC_HRTF_SOFT)
2008 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
2009 if(attrList[attrIdx + 1] == ALC_FALSE)
2010 hrtf_appreq = Hrtf_Disable;
2011 else if(attrList[attrIdx + 1] == ALC_TRUE)
2012 hrtf_appreq = Hrtf_Enable;
2013 else
2014 hrtf_appreq = Hrtf_Default;
2017 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
2019 hrtf_id = attrList[attrIdx + 1];
2020 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
2023 attrIdx += 2;
2025 #undef TRACE_ATTR
2027 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
2028 freq = maxu(freq, MIN_OUTPUT_RATE);
2030 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
2031 device->Frequency;
2032 /* SSE and Neon do best with the update size being a multiple of 4 */
2033 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2034 device->UpdateSize = (device->UpdateSize+3)&~3;
2036 device->Frequency = freq;
2037 device->NumMonoSources = numMono;
2038 device->NumStereoSources = numStereo;
2040 if(ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2041 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2042 else
2043 new_sends = numSends;
2046 if((device->Flags&DEVICE_RUNNING))
2047 return ALC_NO_ERROR;
2049 al_free(device->Uhj_Encoder);
2050 device->Uhj_Encoder = NULL;
2052 al_free(device->Bs2b);
2053 device->Bs2b = NULL;
2055 al_free(device->ChannelDelay[0].Buffer);
2056 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2058 device->ChannelDelay[i].Length = 0;
2059 device->ChannelDelay[i].Buffer = NULL;
2062 al_free(device->Dry.Buffer);
2063 device->Dry.Buffer = NULL;
2064 device->Dry.NumChannels = 0;
2065 device->FOAOut.Buffer = NULL;
2066 device->FOAOut.NumChannels = 0;
2067 device->RealOut.Buffer = NULL;
2068 device->RealOut.NumChannels = 0;
2070 UpdateClockBase(device);
2072 /*************************************************************************
2073 * Update device format request if HRTF is requested
2075 device->Hrtf.Status = ALC_HRTF_DISABLED_SOFT;
2076 if(device->Type != Loopback)
2078 const char *hrtf;
2079 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2081 if(strcasecmp(hrtf, "true") == 0)
2082 hrtf_userreq = Hrtf_Enable;
2083 else if(strcasecmp(hrtf, "false") == 0)
2084 hrtf_userreq = Hrtf_Disable;
2085 else if(strcasecmp(hrtf, "auto") != 0)
2086 ERR("Unexpected hrtf value: %s\n", hrtf);
2089 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2091 if(VECTOR_SIZE(device->Hrtf.List) == 0)
2093 VECTOR_DEINIT(device->Hrtf.List);
2094 device->Hrtf.List = EnumerateHrtf(device->DeviceName);
2096 if(VECTOR_SIZE(device->Hrtf.List) > 0)
2098 device->FmtChans = DevFmtStereo;
2099 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf.List))
2100 device->Frequency = VECTOR_ELEM(device->Hrtf.List, hrtf_id).hrtf->sampleRate;
2101 else
2102 device->Frequency = VECTOR_ELEM(device->Hrtf.List, 0).hrtf->sampleRate;
2103 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2105 else
2107 hrtf_userreq = Hrtf_Default;
2108 hrtf_appreq = Hrtf_Disable;
2109 device->Hrtf.Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2113 else if(hrtf_appreq == Hrtf_Enable)
2115 size_t i = VECTOR_SIZE(device->Hrtf.List);
2116 /* Loopback device. We don't need to match to a specific HRTF entry
2117 * here. If the requested ID matches, we'll pick that later, if not,
2118 * we'll try to auto-select one anyway. Just make sure one exists
2119 * that'll work.
2121 if(device->FmtChans == DevFmtStereo)
2123 if(VECTOR_SIZE(device->Hrtf.List) == 0)
2125 VECTOR_DEINIT(device->Hrtf.List);
2126 device->Hrtf.List = EnumerateHrtf(device->DeviceName);
2128 for(i = 0;i < VECTOR_SIZE(device->Hrtf.List);i++)
2130 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf.List, i).hrtf;
2131 if(hrtf->sampleRate == device->Frequency)
2132 break;
2135 if(i == VECTOR_SIZE(device->Hrtf.List))
2137 ERR("Requested format not HRTF compatible: %s, %uhz\n",
2138 DevFmtChannelsString(device->FmtChans), device->Frequency);
2139 hrtf_appreq = Hrtf_Disable;
2140 device->Hrtf.Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2144 oldFreq = device->Frequency;
2145 oldChans = device->FmtChans;
2146 oldType = device->FmtType;
2148 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2149 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2150 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2151 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2152 device->UpdateSize, device->NumUpdates
2155 if(V0(device->Backend,reset)() == ALC_FALSE)
2156 return ALC_INVALID_DEVICE;
2158 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2160 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2161 DevFmtChannelsString(device->FmtChans));
2162 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2164 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2166 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2167 DevFmtTypeString(device->FmtType));
2168 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2170 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2172 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2173 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2176 if((device->UpdateSize&3) != 0)
2178 if((CPUCapFlags&CPU_CAP_SSE))
2179 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2180 if((CPUCapFlags&CPU_CAP_NEON))
2181 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2184 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2185 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2186 device->Frequency, device->UpdateSize, device->NumUpdates
2189 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2190 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2191 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2193 /* Allocate extra channels for any post-filter output. */
2194 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2195 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2197 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2198 device->Dry.Buffer = al_calloc(16, size);
2199 if(!device->Dry.Buffer)
2201 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2202 return ALC_INVALID_DEVICE;
2205 if(device->RealOut.NumChannels != 0)
2206 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2207 device->FOAOut.NumChannels;
2208 else
2210 device->RealOut.Buffer = device->Dry.Buffer;
2211 device->RealOut.NumChannels = device->Dry.NumChannels;
2214 if(device->FOAOut.NumChannels != 0)
2215 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2216 else
2218 device->FOAOut.Buffer = device->Dry.Buffer;
2219 device->FOAOut.NumChannels = device->Dry.NumChannels;
2222 /* Need to delay returning failure until replacement Send arrays have been
2223 * allocated with the appropriate size.
2225 device->NumAuxSends = new_sends;
2226 update_failed = AL_FALSE;
2227 SetMixerFPUMode(&oldMode);
2228 if(device->DefaultSlot)
2230 ALeffectslot *slot = device->DefaultSlot;
2231 ALeffectState *state = slot->Effect.State;
2233 state->OutBuffer = device->Dry.Buffer;
2234 state->OutChannels = device->Dry.NumChannels;
2235 if(V(state,deviceUpdate)(device) == AL_FALSE)
2236 update_failed = AL_TRUE;
2237 else
2238 UpdateEffectSlotProps(slot);
2241 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2242 while(context)
2244 ALsizei pos;
2246 WriteLock(&context->PropLock);
2247 LockUIntMapRead(&context->EffectSlotMap);
2248 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2250 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2251 ALeffectState *state = slot->Effect.State;
2253 state->OutBuffer = device->Dry.Buffer;
2254 state->OutChannels = device->Dry.NumChannels;
2255 if(V(state,deviceUpdate)(device) == AL_FALSE)
2256 update_failed = AL_TRUE;
2257 else
2258 UpdateEffectSlotProps(slot);
2260 UnlockUIntMapRead(&context->EffectSlotMap);
2262 LockUIntMapRead(&context->SourceMap);
2263 for(pos = 0;pos < context->SourceMap.size;pos++)
2265 ALsource *source = context->SourceMap.values[pos];
2266 struct ALsourceProps *props;
2268 if(old_sends != device->NumAuxSends)
2270 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2271 ALsizei s;
2273 memcpy(sends, source->Send,
2274 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2276 for(s = device->NumAuxSends;s < old_sends;s++)
2278 if(source->Send[s].Slot)
2279 DecrementRef(&source->Send[s].Slot->ref);
2280 source->Send[s].Slot = NULL;
2282 al_free(source->Send);
2283 source->Send = sends;
2284 for(s = old_sends;s < device->NumAuxSends;s++)
2286 source->Send[s].Slot = NULL;
2287 source->Send[s].Gain = 1.0f;
2288 source->Send[s].GainHF = 1.0f;
2289 source->Send[s].HFReference = LOWPASSFREQREF;
2290 source->Send[s].GainLF = 1.0f;
2291 source->Send[s].LFReference = HIGHPASSFREQREF;
2295 source->NeedsUpdate = AL_TRUE;
2297 /* Clear any pre-existing source property structs, in case the
2298 * number of auxiliary sends changed. Playing (or paused) sources
2299 * will have updates respecified in UpdateAllSourceProps.
2301 props = ATOMIC_EXCHANGE_SEQ(struct ALsourceProps*, &source->Update, NULL);
2302 al_free(props);
2304 props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->FreeList, NULL,
2305 almemory_order_relaxed);
2306 while(props)
2308 struct ALsourceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
2309 al_free(props);
2310 props = next;
2313 AllocateVoices(context, context->MaxVoices, old_sends);
2314 UnlockUIntMapRead(&context->SourceMap);
2316 UpdateListenerProps(context);
2317 UpdateAllSourceProps(context);
2318 WriteUnlock(&context->PropLock);
2320 context = context->next;
2322 RestoreFPUMode(&oldMode);
2323 if(update_failed)
2324 return ALC_INVALID_DEVICE;
2326 if(!(device->Flags&DEVICE_PAUSED))
2328 if(V0(device->Backend,start)() == ALC_FALSE)
2329 return ALC_INVALID_DEVICE;
2330 device->Flags |= DEVICE_RUNNING;
2333 return ALC_NO_ERROR;
2336 /* FreeDevice
2338 * Frees the device structure, and destroys any objects the app failed to
2339 * delete. Called once there's no more references on the device.
2341 static ALCvoid FreeDevice(ALCdevice *device)
2343 ALsizei i;
2345 TRACE("%p\n", device);
2347 V0(device->Backend,close)();
2348 DELETE_OBJ(device->Backend);
2349 device->Backend = NULL;
2351 almtx_destroy(&device->BackendLock);
2353 if(device->DefaultSlot)
2355 DeinitEffectSlot(device->DefaultSlot);
2356 device->DefaultSlot = NULL;
2359 if(device->BufferMap.size > 0)
2361 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2362 (device->BufferMap.size==1)?"":"s");
2363 ReleaseALBuffers(device);
2365 ResetUIntMap(&device->BufferMap);
2367 if(device->EffectMap.size > 0)
2369 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2370 (device->EffectMap.size==1)?"":"s");
2371 ReleaseALEffects(device);
2373 ResetUIntMap(&device->EffectMap);
2375 if(device->FilterMap.size > 0)
2377 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2378 (device->FilterMap.size==1)?"":"s");
2379 ReleaseALFilters(device);
2381 ResetUIntMap(&device->FilterMap);
2383 AL_STRING_DEINIT(device->Hrtf.Name);
2384 FreeHrtfList(&device->Hrtf.List);
2386 al_free(device->Bs2b);
2387 device->Bs2b = NULL;
2389 al_free(device->Uhj_Encoder);
2390 device->Uhj_Encoder = NULL;
2392 bformatdec_free(device->AmbiDecoder);
2393 device->AmbiDecoder = NULL;
2395 ambiup_free(device->AmbiUp);
2396 device->AmbiUp = NULL;
2398 al_free(device->ChannelDelay[0].Buffer);
2399 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2401 device->ChannelDelay[i].Gain = 1.0f;
2402 device->ChannelDelay[i].Length = 0;
2403 device->ChannelDelay[i].Buffer = NULL;
2406 AL_STRING_DEINIT(device->DeviceName);
2408 al_free(device->Dry.Buffer);
2409 device->Dry.Buffer = NULL;
2410 device->Dry.NumChannels = 0;
2411 device->FOAOut.Buffer = NULL;
2412 device->FOAOut.NumChannels = 0;
2413 device->RealOut.Buffer = NULL;
2414 device->RealOut.NumChannels = 0;
2416 al_free(device);
2420 void ALCdevice_IncRef(ALCdevice *device)
2422 uint ref;
2423 ref = IncrementRef(&device->ref);
2424 TRACEREF("%p increasing refcount to %u\n", device, ref);
2427 void ALCdevice_DecRef(ALCdevice *device)
2429 uint ref;
2430 ref = DecrementRef(&device->ref);
2431 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2432 if(ref == 0) FreeDevice(device);
2435 /* VerifyDevice
2437 * Checks if the device handle is valid, and increments its ref count if so.
2439 static ALCboolean VerifyDevice(ALCdevice **device)
2441 ALCdevice *tmpDevice;
2443 LockLists();
2444 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2445 while(tmpDevice)
2447 if(tmpDevice == *device)
2449 ALCdevice_IncRef(tmpDevice);
2450 UnlockLists();
2451 return ALC_TRUE;
2453 tmpDevice = tmpDevice->next;
2455 UnlockLists();
2457 *device = NULL;
2458 return ALC_FALSE;
2462 /* InitContext
2464 * Initializes context fields
2466 static ALvoid InitContext(ALCcontext *Context)
2468 ALlistener *listener = Context->Listener;
2470 //Initialise listener
2471 listener->Gain = 1.0f;
2472 listener->MetersPerUnit = 1.0f;
2473 listener->Position[0] = 0.0f;
2474 listener->Position[1] = 0.0f;
2475 listener->Position[2] = 0.0f;
2476 listener->Velocity[0] = 0.0f;
2477 listener->Velocity[1] = 0.0f;
2478 listener->Velocity[2] = 0.0f;
2479 listener->Forward[0] = 0.0f;
2480 listener->Forward[1] = 0.0f;
2481 listener->Forward[2] = -1.0f;
2482 listener->Up[0] = 0.0f;
2483 listener->Up[1] = 1.0f;
2484 listener->Up[2] = 0.0f;
2486 aluMatrixfSet(&listener->Params.Matrix,
2487 1.0f, 0.0f, 0.0f, 0.0f,
2488 0.0f, 1.0f, 0.0f, 0.0f,
2489 0.0f, 0.0f, 1.0f, 0.0f,
2490 0.0f, 0.0f, 0.0f, 1.0f
2492 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2493 listener->Params.Gain = 1.0f;
2494 listener->Params.MetersPerUnit = 1.0f;
2495 listener->Params.DopplerFactor = 1.0f;
2496 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2498 ATOMIC_INIT(&listener->Update, NULL);
2499 ATOMIC_INIT(&listener->FreeList, NULL);
2501 //Validate Context
2502 InitRef(&Context->UpdateCount, 0);
2503 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2504 Context->GainBoost = 1.0f;
2505 RWLockInit(&Context->PropLock);
2506 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2507 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2508 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2510 //Set globals
2511 Context->DistanceModel = DefaultDistanceModel;
2512 Context->SourceDistanceModel = AL_FALSE;
2513 Context->DopplerFactor = 1.0f;
2514 Context->DopplerVelocity = 1.0f;
2515 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2516 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2518 Context->ExtensionList = alExtList;
2522 /* FreeContext
2524 * Cleans up the context, and destroys any remaining objects the app failed to
2525 * delete. Called once there's no more references on the context.
2527 static void FreeContext(ALCcontext *context)
2529 ALlistener *listener = context->Listener;
2530 struct ALlistenerProps *lprops;
2531 size_t count;
2533 TRACE("%p\n", context);
2535 if(context->SourceMap.size > 0)
2537 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2538 (context->SourceMap.size==1)?"":"s");
2539 ReleaseALSources(context);
2541 ResetUIntMap(&context->SourceMap);
2543 if(context->EffectSlotMap.size > 0)
2545 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2546 (context->EffectSlotMap.size==1)?"":"s");
2547 ReleaseALAuxiliaryEffectSlots(context);
2549 ResetUIntMap(&context->EffectSlotMap);
2551 al_free(context->Voices);
2552 context->Voices = NULL;
2553 context->VoiceCount = 0;
2554 context->MaxVoices = 0;
2556 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2558 TRACE("Freed unapplied listener update %p\n", lprops);
2559 al_free(lprops);
2561 count = 0;
2562 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
2563 while(lprops)
2565 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2566 al_free(lprops);
2567 lprops = next;
2568 ++count;
2570 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2572 ALCdevice_DecRef(context->Device);
2573 context->Device = NULL;
2575 //Invalidate context
2576 memset(context, 0, sizeof(ALCcontext));
2577 al_free(context);
2580 /* ReleaseContext
2582 * Removes the context reference from the given device and removes it from
2583 * being current on the running thread or globally.
2585 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2587 ALCcontext *origctx;
2589 if(altss_get(LocalContext) == context)
2591 WARN("%p released while current on thread\n", context);
2592 altss_set(LocalContext, NULL);
2593 ALCcontext_DecRef(context);
2596 origctx = context;
2597 if(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &GlobalContext, &origctx, NULL))
2598 ALCcontext_DecRef(context);
2600 ALCdevice_Lock(device);
2601 origctx = context;
2602 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &device->ContextList,
2603 &origctx, context->next))
2605 ALCcontext *volatile*list = &origctx->next;
2606 while(*list)
2608 if(*list == context)
2610 *list = (*list)->next;
2611 break;
2613 list = &(*list)->next;
2616 ALCdevice_Unlock(device);
2618 ALCcontext_DecRef(context);
2621 void ALCcontext_IncRef(ALCcontext *context)
2623 uint ref = IncrementRef(&context->ref);
2624 TRACEREF("%p increasing refcount to %u\n", context, ref);
2627 void ALCcontext_DecRef(ALCcontext *context)
2629 uint ref = DecrementRef(&context->ref);
2630 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2631 if(ref == 0) FreeContext(context);
2634 static void ReleaseThreadCtx(void *ptr)
2636 ALCcontext *context = ptr;
2637 uint ref = DecrementRef(&context->ref);
2638 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2639 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2642 /* VerifyContext
2644 * Checks that the given context is valid, and increments its reference count.
2646 static ALCboolean VerifyContext(ALCcontext **context)
2648 ALCdevice *dev;
2650 LockLists();
2651 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2652 while(dev)
2654 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2655 while(ctx)
2657 if(ctx == *context)
2659 ALCcontext_IncRef(ctx);
2660 UnlockLists();
2661 return ALC_TRUE;
2663 ctx = ctx->next;
2665 dev = dev->next;
2667 UnlockLists();
2669 *context = NULL;
2670 return ALC_FALSE;
2674 /* GetContextRef
2676 * Returns the currently active context for this thread, and adds a reference
2677 * without locking it.
2679 ALCcontext *GetContextRef(void)
2681 ALCcontext *context;
2683 context = altss_get(LocalContext);
2684 if(context)
2685 ALCcontext_IncRef(context);
2686 else
2688 LockLists();
2689 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2690 if(context)
2691 ALCcontext_IncRef(context);
2692 UnlockLists();
2695 return context;
2699 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2701 ALCdevice *device = context->Device;
2702 ALsizei num_sends = device->NumAuxSends;
2703 struct ALsourceProps *props;
2704 size_t sizeof_props;
2705 size_t sizeof_voice;
2706 ALvoice **voices;
2707 ALvoice *voice;
2708 ALsizei v = 0;
2709 size_t size;
2711 if(num_voices == context->MaxVoices && num_sends == old_sends)
2712 return;
2714 /* Allocate the voice pointers, voices, and the voices' stored source
2715 * property set (including the dynamically-sized Send[] array) in one
2716 * chunk.
2718 sizeof_props = RoundUp(offsetof(struct ALsourceProps, Send[num_sends]), 16);
2719 sizeof_voice = RoundUp(offsetof(ALvoice, Send[num_sends]), 16);
2720 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2722 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2723 /* The voice and property objects are stored interleaved since they're
2724 * paired together.
2726 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2727 props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
2729 if(context->Voices)
2731 ALsizei v_count = mini(context->VoiceCount, num_voices);
2732 for(;v < v_count;v++)
2734 ALsizei s_count = mini(old_sends, num_sends);
2735 ALsizei i;
2737 /* Copy the old voice data and source property set to the new
2738 * storage.
2740 *voice = *(context->Voices[v]);
2741 for(i = 0;i < s_count;i++)
2742 voice->Send[i] = context->Voices[v]->Send[i];
2743 *props = *(context->Voices[v]->Props);
2744 for(i = 0;i < s_count;i++)
2745 props->Send[i] = context->Voices[v]->Props->Send[i];
2747 /* Set this voice's property set pointer and voice reference. */
2748 voice->Props = props;
2749 voices[v] = voice;
2751 /* Increment pointers to the next storage space. */
2752 voice = (ALvoice*)((char*)props + sizeof_props);
2753 props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
2756 /* Finish setting the voices' property set pointers and references. */
2757 for(;v < num_voices;v++)
2759 voice->Props = props;
2760 voices[v] = voice;
2762 voice = (ALvoice*)((char*)props + sizeof_props);
2763 props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
2766 al_free(context->Voices);
2767 context->Voices = voices;
2768 context->MaxVoices = num_voices;
2769 context->VoiceCount = mini(context->VoiceCount, num_voices);
2773 /************************************************
2774 * Standard ALC functions
2775 ************************************************/
2777 /* alcGetError
2779 * Return last ALC generated error code for the given device
2781 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2783 ALCenum errorCode;
2785 if(VerifyDevice(&device))
2787 errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &device->LastError, ALC_NO_ERROR);
2788 ALCdevice_DecRef(device);
2790 else
2791 errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2793 return errorCode;
2797 /* alcSuspendContext
2799 * Suspends updates for the given context
2801 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2803 if(!SuspendDefers)
2804 return;
2806 if(!VerifyContext(&context))
2807 alcSetError(NULL, ALC_INVALID_CONTEXT);
2808 else
2810 ALCcontext_DeferUpdates(context, DeferAllowPlay);
2811 ALCcontext_DecRef(context);
2815 /* alcProcessContext
2817 * Resumes processing updates for the given context
2819 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2821 if(!SuspendDefers)
2822 return;
2824 if(!VerifyContext(&context))
2825 alcSetError(NULL, ALC_INVALID_CONTEXT);
2826 else
2828 ALCcontext_ProcessUpdates(context);
2829 ALCcontext_DecRef(context);
2834 /* alcGetString
2836 * Returns information about the device, and error strings
2838 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2840 const ALCchar *value = NULL;
2842 switch(param)
2844 case ALC_NO_ERROR:
2845 value = alcNoError;
2846 break;
2848 case ALC_INVALID_ENUM:
2849 value = alcErrInvalidEnum;
2850 break;
2852 case ALC_INVALID_VALUE:
2853 value = alcErrInvalidValue;
2854 break;
2856 case ALC_INVALID_DEVICE:
2857 value = alcErrInvalidDevice;
2858 break;
2860 case ALC_INVALID_CONTEXT:
2861 value = alcErrInvalidContext;
2862 break;
2864 case ALC_OUT_OF_MEMORY:
2865 value = alcErrOutOfMemory;
2866 break;
2868 case ALC_DEVICE_SPECIFIER:
2869 value = alcDefaultName;
2870 break;
2872 case ALC_ALL_DEVICES_SPECIFIER:
2873 if(VerifyDevice(&Device))
2875 value = al_string_get_cstr(Device->DeviceName);
2876 ALCdevice_DecRef(Device);
2878 else
2880 ProbeAllDevicesList();
2881 value = al_string_get_cstr(alcAllDevicesList);
2883 break;
2885 case ALC_CAPTURE_DEVICE_SPECIFIER:
2886 if(VerifyDevice(&Device))
2888 value = al_string_get_cstr(Device->DeviceName);
2889 ALCdevice_DecRef(Device);
2891 else
2893 ProbeCaptureDeviceList();
2894 value = al_string_get_cstr(alcCaptureDeviceList);
2896 break;
2898 /* Default devices are always first in the list */
2899 case ALC_DEFAULT_DEVICE_SPECIFIER:
2900 value = alcDefaultName;
2901 break;
2903 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2904 if(al_string_empty(alcAllDevicesList))
2905 ProbeAllDevicesList();
2907 VerifyDevice(&Device);
2909 free(alcDefaultAllDevicesSpecifier);
2910 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2911 if(!alcDefaultAllDevicesSpecifier)
2912 alcSetError(Device, ALC_OUT_OF_MEMORY);
2914 value = alcDefaultAllDevicesSpecifier;
2915 if(Device) ALCdevice_DecRef(Device);
2916 break;
2918 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2919 if(al_string_empty(alcCaptureDeviceList))
2920 ProbeCaptureDeviceList();
2922 VerifyDevice(&Device);
2924 free(alcCaptureDefaultDeviceSpecifier);
2925 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2926 if(!alcCaptureDefaultDeviceSpecifier)
2927 alcSetError(Device, ALC_OUT_OF_MEMORY);
2929 value = alcCaptureDefaultDeviceSpecifier;
2930 if(Device) ALCdevice_DecRef(Device);
2931 break;
2933 case ALC_EXTENSIONS:
2934 if(!VerifyDevice(&Device))
2935 value = alcNoDeviceExtList;
2936 else
2938 value = alcExtensionList;
2939 ALCdevice_DecRef(Device);
2941 break;
2943 case ALC_HRTF_SPECIFIER_SOFT:
2944 if(!VerifyDevice(&Device))
2945 alcSetError(NULL, ALC_INVALID_DEVICE);
2946 else
2948 almtx_lock(&Device->BackendLock);
2949 value = (Device->Hrtf.Handle ? al_string_get_cstr(Device->Hrtf.Name) : "");
2950 almtx_unlock(&Device->BackendLock);
2951 ALCdevice_DecRef(Device);
2953 break;
2955 default:
2956 VerifyDevice(&Device);
2957 alcSetError(Device, ALC_INVALID_ENUM);
2958 if(Device) ALCdevice_DecRef(Device);
2959 break;
2962 return value;
2966 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
2968 if(device->Type == Loopback && device->FmtChans >= DevFmtAmbi1 &&
2969 device->FmtChans <= DevFmtAmbi3)
2970 return 23;
2971 return 17;
2974 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2976 ALCsizei i;
2978 if(size <= 0 || values == NULL)
2980 alcSetError(device, ALC_INVALID_VALUE);
2981 return 0;
2984 if(!device)
2986 switch(param)
2988 case ALC_MAJOR_VERSION:
2989 values[0] = alcMajorVersion;
2990 return 1;
2991 case ALC_MINOR_VERSION:
2992 values[0] = alcMinorVersion;
2993 return 1;
2995 case ALC_ATTRIBUTES_SIZE:
2996 case ALC_ALL_ATTRIBUTES:
2997 case ALC_FREQUENCY:
2998 case ALC_REFRESH:
2999 case ALC_SYNC:
3000 case ALC_MONO_SOURCES:
3001 case ALC_STEREO_SOURCES:
3002 case ALC_CAPTURE_SAMPLES:
3003 case ALC_FORMAT_CHANNELS_SOFT:
3004 case ALC_FORMAT_TYPE_SOFT:
3005 case ALC_AMBISONIC_LAYOUT_SOFT:
3006 case ALC_AMBISONIC_SCALING_SOFT:
3007 case ALC_AMBISONIC_ORDER_SOFT:
3008 alcSetError(NULL, ALC_INVALID_DEVICE);
3009 return 0;
3011 default:
3012 alcSetError(NULL, ALC_INVALID_ENUM);
3013 return 0;
3015 return 0;
3018 if(device->Type == Capture)
3020 switch(param)
3022 case ALC_CAPTURE_SAMPLES:
3023 almtx_lock(&device->BackendLock);
3024 values[0] = V0(device->Backend,availableSamples)();
3025 almtx_unlock(&device->BackendLock);
3026 return 1;
3028 case ALC_CONNECTED:
3029 values[0] = device->Connected;
3030 return 1;
3032 default:
3033 alcSetError(device, ALC_INVALID_ENUM);
3034 return 0;
3036 return 0;
3039 /* render device */
3040 switch(param)
3042 case ALC_MAJOR_VERSION:
3043 values[0] = alcMajorVersion;
3044 return 1;
3046 case ALC_MINOR_VERSION:
3047 values[0] = alcMinorVersion;
3048 return 1;
3050 case ALC_EFX_MAJOR_VERSION:
3051 values[0] = alcEFXMajorVersion;
3052 return 1;
3054 case ALC_EFX_MINOR_VERSION:
3055 values[0] = alcEFXMinorVersion;
3056 return 1;
3058 case ALC_ATTRIBUTES_SIZE:
3059 values[0] = NumAttrsForDevice(device);
3060 return 1;
3062 case ALC_ALL_ATTRIBUTES:
3063 if(size < NumAttrsForDevice(device))
3065 alcSetError(device, ALC_INVALID_VALUE);
3066 return 0;
3069 i = 0;
3070 almtx_lock(&device->BackendLock);
3071 values[i++] = ALC_FREQUENCY;
3072 values[i++] = device->Frequency;
3074 if(device->Type != Loopback)
3076 values[i++] = ALC_REFRESH;
3077 values[i++] = device->Frequency / device->UpdateSize;
3079 values[i++] = ALC_SYNC;
3080 values[i++] = ALC_FALSE;
3082 else
3084 if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3)
3086 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3087 values[i++] = ALC_BFORMAT3D_SOFT;
3089 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3090 values[i++] = device->AmbiLayout;
3092 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3093 values[i++] = device->AmbiScale;
3095 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3096 values[i++] = device->FmtChans-DevFmtAmbi1+1;
3098 else
3100 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3101 values[i++] = device->FmtChans;
3104 values[i++] = ALC_FORMAT_TYPE_SOFT;
3105 values[i++] = device->FmtType;
3108 values[i++] = ALC_MONO_SOURCES;
3109 values[i++] = device->NumMonoSources;
3111 values[i++] = ALC_STEREO_SOURCES;
3112 values[i++] = device->NumStereoSources;
3114 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3115 values[i++] = device->NumAuxSends;
3117 values[i++] = ALC_HRTF_SOFT;
3118 values[i++] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE);
3120 values[i++] = ALC_HRTF_STATUS_SOFT;
3121 values[i++] = device->Hrtf.Status;
3122 almtx_unlock(&device->BackendLock);
3124 values[i++] = 0;
3125 return i;
3127 case ALC_FREQUENCY:
3128 values[0] = device->Frequency;
3129 return 1;
3131 case ALC_REFRESH:
3132 if(device->Type == Loopback)
3134 alcSetError(device, ALC_INVALID_DEVICE);
3135 return 0;
3137 almtx_lock(&device->BackendLock);
3138 values[0] = device->Frequency / device->UpdateSize;
3139 almtx_unlock(&device->BackendLock);
3140 return 1;
3142 case ALC_SYNC:
3143 if(device->Type == Loopback)
3145 alcSetError(device, ALC_INVALID_DEVICE);
3146 return 0;
3148 values[0] = ALC_FALSE;
3149 return 1;
3151 case ALC_FORMAT_CHANNELS_SOFT:
3152 if(device->Type != Loopback)
3154 alcSetError(device, ALC_INVALID_DEVICE);
3155 return 0;
3157 if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3)
3158 values[0] = ALC_BFORMAT3D_SOFT;
3159 else
3160 values[0] = device->FmtChans;
3161 return 1;
3163 case ALC_FORMAT_TYPE_SOFT:
3164 if(device->Type != Loopback)
3166 alcSetError(device, ALC_INVALID_DEVICE);
3167 return 0;
3169 values[0] = device->FmtType;
3170 return 1;
3172 case ALC_AMBISONIC_LAYOUT_SOFT:
3173 if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
3174 device->FmtChans <= DevFmtAmbi3))
3176 alcSetError(device, ALC_INVALID_DEVICE);
3177 return 0;
3179 values[0] = device->AmbiLayout;
3180 return 1;
3182 case ALC_AMBISONIC_SCALING_SOFT:
3183 if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
3184 device->FmtChans <= DevFmtAmbi3))
3186 alcSetError(device, ALC_INVALID_DEVICE);
3187 return 0;
3189 values[0] = device->AmbiScale;
3190 return 1;
3192 case ALC_AMBISONIC_ORDER_SOFT:
3193 if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
3194 device->FmtChans <= DevFmtAmbi3))
3196 alcSetError(device, ALC_INVALID_DEVICE);
3197 return 0;
3199 values[0] = device->FmtChans - DevFmtAmbi1 + 1;
3200 return 1;
3202 case ALC_MONO_SOURCES:
3203 values[0] = device->NumMonoSources;
3204 return 1;
3206 case ALC_STEREO_SOURCES:
3207 values[0] = device->NumStereoSources;
3208 return 1;
3210 case ALC_MAX_AUXILIARY_SENDS:
3211 values[0] = device->NumAuxSends;
3212 return 1;
3214 case ALC_CONNECTED:
3215 values[0] = device->Connected;
3216 return 1;
3218 case ALC_HRTF_SOFT:
3219 values[0] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE);
3220 return 1;
3222 case ALC_HRTF_STATUS_SOFT:
3223 values[0] = device->Hrtf.Status;
3224 return 1;
3226 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3227 almtx_lock(&device->BackendLock);
3228 FreeHrtfList(&device->Hrtf.List);
3229 device->Hrtf.List = EnumerateHrtf(device->DeviceName);
3230 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf.List);
3231 almtx_unlock(&device->BackendLock);
3232 return 1;
3234 default:
3235 alcSetError(device, ALC_INVALID_ENUM);
3236 return 0;
3238 return 0;
3241 /* alcGetIntegerv
3243 * Returns information about the device and the version of OpenAL
3245 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3247 VerifyDevice(&device);
3248 if(size <= 0 || values == NULL)
3249 alcSetError(device, ALC_INVALID_VALUE);
3250 else
3251 GetIntegerv(device, param, size, values);
3252 if(device) ALCdevice_DecRef(device);
3255 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3257 ALCint *ivals;
3258 ALsizei i;
3260 VerifyDevice(&device);
3261 if(size <= 0 || values == NULL)
3262 alcSetError(device, ALC_INVALID_VALUE);
3263 else if(!device || device->Type == Capture)
3265 ivals = malloc(size * sizeof(ALCint));
3266 size = GetIntegerv(device, pname, size, ivals);
3267 for(i = 0;i < size;i++)
3268 values[i] = ivals[i];
3269 free(ivals);
3271 else /* render device */
3273 ClockLatency clock;
3274 ALuint64 basecount;
3275 ALuint samplecount;
3276 ALuint refcount;
3278 switch(pname)
3280 case ALC_ATTRIBUTES_SIZE:
3281 *values = 21;
3282 break;
3284 case ALC_ALL_ATTRIBUTES:
3285 if(size < 21)
3286 alcSetError(device, ALC_INVALID_VALUE);
3287 else
3289 i = 0;
3290 almtx_lock(&device->BackendLock);
3291 values[i++] = ALC_FREQUENCY;
3292 values[i++] = device->Frequency;
3294 if(device->Type != Loopback)
3296 values[i++] = ALC_REFRESH;
3297 values[i++] = device->Frequency / device->UpdateSize;
3299 values[i++] = ALC_SYNC;
3300 values[i++] = ALC_FALSE;
3302 else
3304 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3305 values[i++] = device->FmtChans;
3307 values[i++] = ALC_FORMAT_TYPE_SOFT;
3308 values[i++] = device->FmtType;
3311 values[i++] = ALC_MONO_SOURCES;
3312 values[i++] = device->NumMonoSources;
3314 values[i++] = ALC_STEREO_SOURCES;
3315 values[i++] = device->NumStereoSources;
3317 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3318 values[i++] = device->NumAuxSends;
3320 values[i++] = ALC_HRTF_SOFT;
3321 values[i++] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE);
3323 values[i++] = ALC_HRTF_STATUS_SOFT;
3324 values[i++] = device->Hrtf.Status;
3326 clock = V0(device->Backend,getClockLatency)();
3327 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3328 values[i++] = clock.ClockTime;
3330 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3331 values[i++] = clock.Latency;
3332 almtx_unlock(&device->BackendLock);
3334 values[i++] = 0;
3336 break;
3338 case ALC_DEVICE_CLOCK_SOFT:
3339 almtx_lock(&device->BackendLock);
3340 do {
3341 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3342 althrd_yield();
3343 basecount = device->ClockBase;
3344 samplecount = device->SamplesDone;
3345 } while(refcount != ReadRef(&device->MixCount));
3346 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3347 almtx_unlock(&device->BackendLock);
3348 break;
3350 case ALC_DEVICE_LATENCY_SOFT:
3352 almtx_lock(&device->BackendLock);
3353 clock = V0(device->Backend,getClockLatency)();
3354 almtx_unlock(&device->BackendLock);
3355 *values = clock.Latency;
3357 break;
3359 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3360 if(size < 2)
3361 alcSetError(device, ALC_INVALID_VALUE);
3362 else
3364 ClockLatency clock;
3365 almtx_lock(&device->BackendLock);
3366 clock = V0(device->Backend,getClockLatency)();
3367 almtx_unlock(&device->BackendLock);
3368 values[0] = clock.ClockTime;
3369 values[1] = clock.Latency;
3371 break;
3373 default:
3374 ivals = malloc(size * sizeof(ALCint));
3375 size = GetIntegerv(device, pname, size, ivals);
3376 for(i = 0;i < size;i++)
3377 values[i] = ivals[i];
3378 free(ivals);
3379 break;
3382 if(device)
3383 ALCdevice_DecRef(device);
3387 /* alcIsExtensionPresent
3389 * Determines if there is support for a particular extension
3391 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3393 ALCboolean bResult = ALC_FALSE;
3395 VerifyDevice(&device);
3397 if(!extName)
3398 alcSetError(device, ALC_INVALID_VALUE);
3399 else
3401 size_t len = strlen(extName);
3402 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3403 while(ptr && *ptr)
3405 if(strncasecmp(ptr, extName, len) == 0 &&
3406 (ptr[len] == '\0' || isspace(ptr[len])))
3408 bResult = ALC_TRUE;
3409 break;
3411 if((ptr=strchr(ptr, ' ')) != NULL)
3413 do {
3414 ++ptr;
3415 } while(isspace(*ptr));
3419 if(device)
3420 ALCdevice_DecRef(device);
3421 return bResult;
3425 /* alcGetProcAddress
3427 * Retrieves the function address for a particular extension function
3429 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3431 ALCvoid *ptr = NULL;
3433 if(!funcName)
3435 VerifyDevice(&device);
3436 alcSetError(device, ALC_INVALID_VALUE);
3437 if(device) ALCdevice_DecRef(device);
3439 else
3441 ALsizei i = 0;
3442 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3443 i++;
3444 ptr = alcFunctions[i].address;
3447 return ptr;
3451 /* alcGetEnumValue
3453 * Get the value for a particular ALC enumeration name
3455 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3457 ALCenum val = 0;
3459 if(!enumName)
3461 VerifyDevice(&device);
3462 alcSetError(device, ALC_INVALID_VALUE);
3463 if(device) ALCdevice_DecRef(device);
3465 else
3467 ALsizei i = 0;
3468 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3469 i++;
3470 val = enumeration[i].value;
3473 return val;
3477 /* alcCreateContext
3479 * Create and attach a context to the given device.
3481 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3483 ALCcontext *ALContext;
3484 ALfloat valf;
3485 ALCenum err;
3487 LockLists();
3488 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3490 UnlockLists();
3491 alcSetError(device, ALC_INVALID_DEVICE);
3492 if(device) ALCdevice_DecRef(device);
3493 return NULL;
3495 almtx_lock(&device->BackendLock);
3496 UnlockLists();
3498 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3500 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3501 if(ALContext)
3503 InitRef(&ALContext->ref, 1);
3504 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3506 ALContext->Device = device;
3507 ATOMIC_INIT(&ALContext->ActiveAuxSlotList, NULL);
3509 ALContext->Voices = NULL;
3510 ALContext->MaxVoices = 0;
3511 ALContext->VoiceCount = 0;
3512 AllocateVoices(ALContext, 256, device->NumAuxSends);
3514 if(!ALContext || !ALContext->Voices)
3516 almtx_unlock(&device->BackendLock);
3518 if(ALContext)
3520 al_free(ALContext->Voices);
3521 ALContext->Voices = NULL;
3523 al_free(ALContext);
3524 ALContext = NULL;
3527 alcSetError(device, ALC_OUT_OF_MEMORY);
3528 ALCdevice_DecRef(device);
3529 return NULL;
3532 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3534 almtx_unlock(&device->BackendLock);
3536 al_free(ALContext->Voices);
3537 ALContext->Voices = NULL;
3539 al_free(ALContext);
3540 ALContext = NULL;
3542 alcSetError(device, err);
3543 if(err == ALC_INVALID_DEVICE)
3545 V0(device->Backend,lock)();
3546 aluHandleDisconnect(device);
3547 V0(device->Backend,unlock)();
3549 ALCdevice_DecRef(device);
3550 return NULL;
3553 ALCdevice_IncRef(ALContext->Device);
3554 InitContext(ALContext);
3556 if(ConfigValueFloat(al_string_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3558 if(!isfinite(valf))
3559 ERR("volume-adjust must be finite: %f\n", valf);
3560 else
3562 ALfloat db = clampf(valf, -24.0f, 24.0f);
3563 if(db != valf)
3564 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3565 ALContext->GainBoost = powf(10.0f, db/20.0f);
3566 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3569 UpdateListenerProps(ALContext);
3572 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3573 do {
3574 ALContext->next = head;
3575 } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCcontext*,
3576 &device->ContextList, &head, ALContext) == 0);
3578 almtx_unlock(&device->BackendLock);
3580 ALCdevice_DecRef(device);
3582 TRACE("Created context %p\n", ALContext);
3583 return ALContext;
3586 /* alcDestroyContext
3588 * Remove a context from its device
3590 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3592 ALCdevice *Device;
3594 LockLists();
3595 /* alcGetContextsDevice sets an error for invalid contexts */
3596 Device = alcGetContextsDevice(context);
3597 if(Device)
3599 almtx_lock(&Device->BackendLock);
3600 ReleaseContext(context, Device);
3601 if(!ATOMIC_LOAD_SEQ(&Device->ContextList))
3603 V0(Device->Backend,stop)();
3604 Device->Flags &= ~DEVICE_RUNNING;
3606 almtx_unlock(&Device->BackendLock);
3608 UnlockLists();
3612 /* alcGetCurrentContext
3614 * Returns the currently active context on the calling thread
3616 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3618 ALCcontext *Context = altss_get(LocalContext);
3619 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3620 return Context;
3623 /* alcGetThreadContext
3625 * Returns the currently active thread-local context
3627 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3629 return altss_get(LocalContext);
3633 /* alcMakeContextCurrent
3635 * Makes the given context the active process-wide context, and removes the
3636 * thread-local context for the calling thread.
3638 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3640 /* context must be valid or NULL */
3641 if(context && !VerifyContext(&context))
3643 alcSetError(NULL, ALC_INVALID_CONTEXT);
3644 return ALC_FALSE;
3646 /* context's reference count is already incremented */
3647 context = ATOMIC_EXCHANGE_SEQ(ALCcontext*, &GlobalContext, context);
3648 if(context) ALCcontext_DecRef(context);
3650 if((context=altss_get(LocalContext)) != NULL)
3652 altss_set(LocalContext, NULL);
3653 ALCcontext_DecRef(context);
3656 return ALC_TRUE;
3659 /* alcSetThreadContext
3661 * Makes the given context the active context for the current thread
3663 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3665 ALCcontext *old;
3667 /* context must be valid or NULL */
3668 if(context && !VerifyContext(&context))
3670 alcSetError(NULL, ALC_INVALID_CONTEXT);
3671 return ALC_FALSE;
3673 /* context's reference count is already incremented */
3674 old = altss_get(LocalContext);
3675 altss_set(LocalContext, context);
3676 if(old) ALCcontext_DecRef(old);
3678 return ALC_TRUE;
3682 /* alcGetContextsDevice
3684 * Returns the device that a particular context is attached to
3686 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3688 ALCdevice *Device;
3690 if(!VerifyContext(&Context))
3692 alcSetError(NULL, ALC_INVALID_CONTEXT);
3693 return NULL;
3695 Device = Context->Device;
3696 ALCcontext_DecRef(Context);
3698 return Device;
3702 /* alcOpenDevice
3704 * Opens the named device.
3706 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3708 const ALCchar *fmt;
3709 ALCdevice *device;
3710 ALCenum err;
3711 ALCsizei i;
3713 DO_INITCONFIG();
3715 if(!PlaybackBackend.name)
3717 alcSetError(NULL, ALC_INVALID_VALUE);
3718 return NULL;
3721 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3722 #ifdef _WIN32
3723 /* Some old Windows apps hardcode these expecting OpenAL to use a
3724 * specific audio API, even when they're not enumerated. Creative's
3725 * router effectively ignores them too.
3727 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3728 || strcasecmp(deviceName, "MMSYSTEM") == 0
3729 #endif
3731 deviceName = NULL;
3733 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3734 if(!device)
3736 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3737 return NULL;
3740 //Validate device
3741 InitRef(&device->ref, 1);
3742 device->Connected = ALC_TRUE;
3743 device->Type = Playback;
3744 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3746 device->Flags = 0;
3747 device->Bs2b = NULL;
3748 device->Uhj_Encoder = NULL;
3749 VECTOR_INIT(device->Hrtf.List);
3750 AL_STRING_INIT(device->Hrtf.Name);
3751 device->Render_Mode = NormalRender;
3752 AL_STRING_INIT(device->DeviceName);
3753 device->Dry.Buffer = NULL;
3754 device->Dry.NumChannels = 0;
3755 device->FOAOut.Buffer = NULL;
3756 device->FOAOut.NumChannels = 0;
3757 device->RealOut.Buffer = NULL;
3758 device->RealOut.NumChannels = 0;
3760 ATOMIC_INIT(&device->ContextList, NULL);
3762 device->ClockBase = 0;
3763 device->SamplesDone = 0;
3765 device->SourcesMax = 256;
3766 device->AuxiliaryEffectSlotMax = 64;
3767 device->NumAuxSends = DEFAULT_SENDS;
3769 InitUIntMap(&device->BufferMap, ~0);
3770 InitUIntMap(&device->EffectMap, ~0);
3771 InitUIntMap(&device->FilterMap, ~0);
3773 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3775 device->ChannelDelay[i].Gain = 1.0f;
3776 device->ChannelDelay[i].Length = 0;
3777 device->ChannelDelay[i].Buffer = NULL;
3780 //Set output format
3781 device->FmtChans = DevFmtChannelsDefault;
3782 device->FmtType = DevFmtTypeDefault;
3783 device->Frequency = DEFAULT_OUTPUT_RATE;
3784 device->IsHeadphones = AL_FALSE;
3785 device->AmbiLayout = AmbiLayout_Default;
3786 device->AmbiScale = AmbiNorm_Default;
3787 device->NumUpdates = 3;
3788 device->UpdateSize = 1024;
3790 if(!PlaybackBackend.getFactory)
3791 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3792 ALCbackend_Playback);
3793 else
3795 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3796 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3798 if(!device->Backend)
3800 al_free(device);
3801 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3802 return NULL;
3806 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3808 static const struct {
3809 const char name[16];
3810 enum DevFmtChannels chans;
3811 } chanlist[] = {
3812 { "mono", DevFmtMono },
3813 { "stereo", DevFmtStereo },
3814 { "quad", DevFmtQuad },
3815 { "surround51", DevFmtX51 },
3816 { "surround61", DevFmtX61 },
3817 { "surround71", DevFmtX71 },
3818 { "surround51rear", DevFmtX51Rear },
3819 { "ambi1", DevFmtAmbi1 },
3820 { "ambi2", DevFmtAmbi2 },
3821 { "ambi3", DevFmtAmbi3 },
3823 size_t i;
3825 for(i = 0;i < COUNTOF(chanlist);i++)
3827 if(strcasecmp(chanlist[i].name, fmt) == 0)
3829 device->FmtChans = chanlist[i].chans;
3830 device->Flags |= DEVICE_CHANNELS_REQUEST;
3831 break;
3834 if(i == COUNTOF(chanlist))
3835 ERR("Unsupported channels: %s\n", fmt);
3837 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3839 static const struct {
3840 const char name[16];
3841 enum DevFmtType type;
3842 } typelist[] = {
3843 { "int8", DevFmtByte },
3844 { "uint8", DevFmtUByte },
3845 { "int16", DevFmtShort },
3846 { "uint16", DevFmtUShort },
3847 { "int32", DevFmtInt },
3848 { "uint32", DevFmtUInt },
3849 { "float32", DevFmtFloat },
3851 size_t i;
3853 for(i = 0;i < COUNTOF(typelist);i++)
3855 if(strcasecmp(typelist[i].name, fmt) == 0)
3857 device->FmtType = typelist[i].type;
3858 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3859 break;
3862 if(i == COUNTOF(typelist))
3863 ERR("Unsupported sample-type: %s\n", fmt);
3866 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3868 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3869 if(device->Frequency < MIN_OUTPUT_RATE)
3870 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3871 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3874 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3875 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3877 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3878 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3879 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3880 device->UpdateSize = (device->UpdateSize+3)&~3;
3882 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
3883 if(device->SourcesMax == 0) device->SourcesMax = 256;
3885 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3886 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
3888 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
3889 device->NumAuxSends = clampi(
3890 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
3893 device->NumStereoSources = 1;
3894 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
3896 // Find a playback device to open
3897 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3899 DELETE_OBJ(device->Backend);
3900 al_free(device);
3901 alcSetError(NULL, err);
3902 return NULL;
3904 almtx_init(&device->BackendLock, almtx_plain);
3906 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
3908 if(strcasecmp(fmt, "fuma") == 0)
3910 device->AmbiLayout = AmbiLayout_FuMa;
3911 device->AmbiScale = AmbiNorm_FuMa;
3913 else if(strcasecmp(fmt, "acn+sn3d") == 0)
3915 device->AmbiLayout = AmbiLayout_ACN;
3916 device->AmbiScale = AmbiNorm_SN3D;
3918 else if(strcasecmp(fmt, "acn+n3d") == 0)
3920 device->AmbiLayout = AmbiLayout_ACN;
3921 device->AmbiScale = AmbiNorm_N3D;
3923 else
3924 ERR("Unsupported ambi-format: %s\n", fmt);
3927 if(DefaultEffect.type != AL_EFFECT_NULL)
3929 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3930 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3932 device->DefaultSlot = NULL;
3933 ERR("Failed to initialize the default effect slot\n");
3935 else
3937 aluInitEffectPanning(device->DefaultSlot);
3938 if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3940 DeinitEffectSlot(device->DefaultSlot);
3941 device->DefaultSlot = NULL;
3942 ERR("Failed to initialize the default effect\n");
3948 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
3949 do {
3950 device->next = head;
3951 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
3954 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3955 return device;
3958 /* alcCloseDevice
3960 * Closes the given device.
3962 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3964 ALCdevice *iter, *origdev;
3965 ALCcontext *ctx;
3967 LockLists();
3968 iter = ATOMIC_LOAD_SEQ(&DeviceList);
3969 do {
3970 if(iter == device)
3971 break;
3972 } while((iter=iter->next) != NULL);
3973 if(!iter || iter->Type == Capture)
3975 alcSetError(iter, ALC_INVALID_DEVICE);
3976 UnlockLists();
3977 return ALC_FALSE;
3979 almtx_lock(&device->BackendLock);
3981 origdev = device;
3982 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next))
3984 ALCdevice *volatile*list = &origdev->next;
3985 while(*list)
3987 if(*list == device)
3989 *list = (*list)->next;
3990 break;
3992 list = &(*list)->next;
3995 UnlockLists();
3997 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
3998 while(ctx != NULL)
4000 ALCcontext *next = ctx->next;
4001 WARN("Releasing context %p\n", ctx);
4002 ReleaseContext(ctx, device);
4003 ctx = next;
4005 if((device->Flags&DEVICE_RUNNING))
4006 V0(device->Backend,stop)();
4007 device->Flags &= ~DEVICE_RUNNING;
4008 almtx_unlock(&device->BackendLock);
4010 ALCdevice_DecRef(device);
4012 return ALC_TRUE;
4016 /************************************************
4017 * ALC capture functions
4018 ************************************************/
4019 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4021 ALCdevice *device = NULL;
4022 ALCenum err;
4023 ALCsizei i;
4025 DO_INITCONFIG();
4027 if(!CaptureBackend.name)
4029 alcSetError(NULL, ALC_INVALID_VALUE);
4030 return NULL;
4033 if(samples <= 0)
4035 alcSetError(NULL, ALC_INVALID_VALUE);
4036 return NULL;
4039 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4040 deviceName = NULL;
4042 device = al_calloc(16, sizeof(ALCdevice));
4043 if(!device)
4045 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4046 return NULL;
4049 //Validate device
4050 InitRef(&device->ref, 1);
4051 device->Connected = ALC_TRUE;
4052 device->Type = Capture;
4054 VECTOR_INIT(device->Hrtf.List);
4055 AL_STRING_INIT(device->Hrtf.Name);
4057 AL_STRING_INIT(device->DeviceName);
4058 device->Dry.Buffer = NULL;
4059 device->Dry.NumChannels = 0;
4060 device->FOAOut.Buffer = NULL;
4061 device->FOAOut.NumChannels = 0;
4062 device->RealOut.Buffer = NULL;
4063 device->RealOut.NumChannels = 0;
4065 InitUIntMap(&device->BufferMap, ~0);
4066 InitUIntMap(&device->EffectMap, ~0);
4067 InitUIntMap(&device->FilterMap, ~0);
4069 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4071 device->ChannelDelay[i].Gain = 1.0f;
4072 device->ChannelDelay[i].Length = 0;
4073 device->ChannelDelay[i].Buffer = NULL;
4076 if(!CaptureBackend.getFactory)
4077 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
4078 ALCbackend_Capture);
4079 else
4081 ALCbackendFactory *factory = CaptureBackend.getFactory();
4082 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4084 if(!device->Backend)
4086 al_free(device);
4087 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4088 return NULL;
4091 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4092 device->Frequency = frequency;
4094 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4095 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4097 al_free(device);
4098 alcSetError(NULL, ALC_INVALID_ENUM);
4099 return NULL;
4101 device->IsHeadphones = AL_FALSE;
4102 device->AmbiLayout = AmbiLayout_Default;
4103 device->AmbiScale = AmbiNorm_Default;
4105 device->UpdateSize = samples;
4106 device->NumUpdates = 1;
4108 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4110 al_free(device);
4111 alcSetError(NULL, err);
4112 return NULL;
4114 almtx_init(&device->BackendLock, almtx_plain);
4117 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4118 do {
4119 device->next = head;
4120 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
4123 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
4124 return device;
4127 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4129 ALCdevice *iter, *origdev;
4131 LockLists();
4132 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4133 do {
4134 if(iter == device)
4135 break;
4136 } while((iter=iter->next) != NULL);
4137 if(!iter || iter->Type != Capture)
4139 alcSetError(iter, ALC_INVALID_DEVICE);
4140 UnlockLists();
4141 return ALC_FALSE;
4144 origdev = device;
4145 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next))
4147 ALCdevice *volatile*list = &origdev->next;
4148 while(*list)
4150 if(*list == device)
4152 *list = (*list)->next;
4153 break;
4155 list = &(*list)->next;
4158 UnlockLists();
4160 ALCdevice_DecRef(device);
4162 return ALC_TRUE;
4165 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4167 if(!VerifyDevice(&device) || device->Type != Capture)
4168 alcSetError(device, ALC_INVALID_DEVICE);
4169 else
4171 almtx_lock(&device->BackendLock);
4172 if(!device->Connected)
4173 alcSetError(device, ALC_INVALID_DEVICE);
4174 else if(!(device->Flags&DEVICE_RUNNING))
4176 if(V0(device->Backend,start)())
4177 device->Flags |= DEVICE_RUNNING;
4178 else
4180 aluHandleDisconnect(device);
4181 alcSetError(device, ALC_INVALID_DEVICE);
4184 almtx_unlock(&device->BackendLock);
4187 if(device) ALCdevice_DecRef(device);
4190 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4192 if(!VerifyDevice(&device) || device->Type != Capture)
4193 alcSetError(device, ALC_INVALID_DEVICE);
4194 else
4196 almtx_lock(&device->BackendLock);
4197 if((device->Flags&DEVICE_RUNNING))
4198 V0(device->Backend,stop)();
4199 device->Flags &= ~DEVICE_RUNNING;
4200 almtx_unlock(&device->BackendLock);
4203 if(device) ALCdevice_DecRef(device);
4206 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4208 if(!VerifyDevice(&device) || device->Type != Capture)
4209 alcSetError(device, ALC_INVALID_DEVICE);
4210 else
4212 ALCenum err = ALC_INVALID_VALUE;
4214 almtx_lock(&device->BackendLock);
4215 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4216 err = V(device->Backend,captureSamples)(buffer, samples);
4217 almtx_unlock(&device->BackendLock);
4219 if(err != ALC_NO_ERROR)
4220 alcSetError(device, err);
4222 if(device) ALCdevice_DecRef(device);
4226 /************************************************
4227 * ALC loopback functions
4228 ************************************************/
4230 /* alcLoopbackOpenDeviceSOFT
4232 * Open a loopback device, for manual rendering.
4234 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4236 ALCbackendFactory *factory;
4237 ALCdevice *device;
4238 ALCsizei i;
4240 DO_INITCONFIG();
4242 /* Make sure the device name, if specified, is us. */
4243 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4245 alcSetError(NULL, ALC_INVALID_VALUE);
4246 return NULL;
4249 device = al_calloc(16, sizeof(ALCdevice));
4250 if(!device)
4252 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4253 return NULL;
4256 //Validate device
4257 InitRef(&device->ref, 1);
4258 device->Connected = ALC_TRUE;
4259 device->Type = Loopback;
4260 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4262 device->Flags = 0;
4263 VECTOR_INIT(device->Hrtf.List);
4264 AL_STRING_INIT(device->Hrtf.Name);
4265 device->Bs2b = NULL;
4266 device->Uhj_Encoder = NULL;
4267 device->Render_Mode = NormalRender;
4268 AL_STRING_INIT(device->DeviceName);
4269 device->Dry.Buffer = NULL;
4270 device->Dry.NumChannels = 0;
4271 device->FOAOut.Buffer = NULL;
4272 device->FOAOut.NumChannels = 0;
4273 device->RealOut.Buffer = NULL;
4274 device->RealOut.NumChannels = 0;
4276 ATOMIC_INIT(&device->ContextList, NULL);
4278 device->ClockBase = 0;
4279 device->SamplesDone = 0;
4281 device->SourcesMax = 256;
4282 device->AuxiliaryEffectSlotMax = 64;
4283 device->NumAuxSends = DEFAULT_SENDS;
4285 InitUIntMap(&device->BufferMap, ~0);
4286 InitUIntMap(&device->EffectMap, ~0);
4287 InitUIntMap(&device->FilterMap, ~0);
4289 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4291 device->ChannelDelay[i].Gain = 1.0f;
4292 device->ChannelDelay[i].Length = 0;
4293 device->ChannelDelay[i].Buffer = NULL;
4296 factory = ALCloopbackFactory_getFactory();
4297 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4298 if(!device->Backend)
4300 al_free(device);
4301 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4302 return NULL;
4304 almtx_init(&device->BackendLock, almtx_plain);
4306 //Set output format
4307 device->NumUpdates = 0;
4308 device->UpdateSize = 0;
4310 device->Frequency = DEFAULT_OUTPUT_RATE;
4311 device->FmtChans = DevFmtChannelsDefault;
4312 device->FmtType = DevFmtTypeDefault;
4313 device->IsHeadphones = AL_FALSE;
4314 device->AmbiLayout = AmbiLayout_Default;
4315 device->AmbiScale = AmbiNorm_Default;
4317 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4318 if(device->SourcesMax == 0) device->SourcesMax = 256;
4320 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4321 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4323 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4324 device->NumAuxSends = clampi(
4325 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4328 device->NumStereoSources = 1;
4329 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4331 // Open the "backend"
4332 V(device->Backend,open)("Loopback");
4335 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4336 do {
4337 device->next = head;
4338 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
4341 TRACE("Created device %p\n", device);
4342 return device;
4345 /* alcIsRenderFormatSupportedSOFT
4347 * Determines if the loopback device supports the given format for rendering.
4349 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4351 ALCboolean ret = ALC_FALSE;
4353 if(!VerifyDevice(&device) || device->Type != Loopback)
4354 alcSetError(device, ALC_INVALID_DEVICE);
4355 else if(freq <= 0)
4356 alcSetError(device, ALC_INVALID_VALUE);
4357 else
4359 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4360 ret = ALC_TRUE;
4362 if(device) ALCdevice_DecRef(device);
4364 return ret;
4367 /* alcRenderSamplesSOFT
4369 * Renders some samples into a buffer, using the format last set by the
4370 * attributes given to alcCreateContext.
4372 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4374 if(!VerifyDevice(&device) || device->Type != Loopback)
4375 alcSetError(device, ALC_INVALID_DEVICE);
4376 else if(samples < 0 || (samples > 0 && buffer == NULL))
4377 alcSetError(device, ALC_INVALID_VALUE);
4378 else
4380 V0(device->Backend,lock)();
4381 aluMixData(device, buffer, samples);
4382 V0(device->Backend,unlock)();
4384 if(device) ALCdevice_DecRef(device);
4388 /************************************************
4389 * ALC loopback2 functions
4390 ************************************************/
4392 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4394 ALCboolean ret = ALC_FALSE;
4396 if(!VerifyDevice(&device) || device->Type != Loopback)
4397 alcSetError(device, ALC_INVALID_DEVICE);
4398 else if(order <= 0)
4399 alcSetError(device, ALC_INVALID_VALUE);
4400 else
4402 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4403 ret = ALC_TRUE;
4405 if(device) ALCdevice_DecRef(device);
4407 return ret;
4410 /************************************************
4411 * ALC DSP pause/resume functions
4412 ************************************************/
4414 /* alcDevicePauseSOFT
4416 * Pause the DSP to stop audio processing.
4418 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4420 if(!VerifyDevice(&device) || device->Type != Playback)
4421 alcSetError(device, ALC_INVALID_DEVICE);
4422 else
4424 almtx_lock(&device->BackendLock);
4425 if((device->Flags&DEVICE_RUNNING))
4426 V0(device->Backend,stop)();
4427 device->Flags &= ~DEVICE_RUNNING;
4428 device->Flags |= DEVICE_PAUSED;
4429 almtx_unlock(&device->BackendLock);
4431 if(device) ALCdevice_DecRef(device);
4434 /* alcDeviceResumeSOFT
4436 * Resume the DSP to restart audio processing.
4438 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4440 if(!VerifyDevice(&device) || device->Type != Playback)
4441 alcSetError(device, ALC_INVALID_DEVICE);
4442 else
4444 almtx_lock(&device->BackendLock);
4445 if((device->Flags&DEVICE_PAUSED))
4447 device->Flags &= ~DEVICE_PAUSED;
4448 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4450 if(V0(device->Backend,start)() != ALC_FALSE)
4451 device->Flags |= DEVICE_RUNNING;
4452 else
4454 alcSetError(device, ALC_INVALID_DEVICE);
4455 V0(device->Backend,lock)();
4456 aluHandleDisconnect(device);
4457 V0(device->Backend,unlock)();
4461 almtx_unlock(&device->BackendLock);
4463 if(device) ALCdevice_DecRef(device);
4467 /************************************************
4468 * ALC HRTF functions
4469 ************************************************/
4471 /* alcGetStringiSOFT
4473 * Gets a string parameter at the given index.
4475 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4477 const ALCchar *str = NULL;
4479 if(!VerifyDevice(&device) || device->Type == Capture)
4480 alcSetError(device, ALC_INVALID_DEVICE);
4481 else switch(paramName)
4483 case ALC_HRTF_SPECIFIER_SOFT:
4484 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf.List))
4485 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf.List, index).name);
4486 else
4487 alcSetError(device, ALC_INVALID_VALUE);
4488 break;
4490 default:
4491 alcSetError(device, ALC_INVALID_ENUM);
4492 break;
4494 if(device) ALCdevice_DecRef(device);
4496 return str;
4499 /* alcResetDeviceSOFT
4501 * Resets the given device output, using the specified attribute list.
4503 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4505 ALCenum err;
4507 LockLists();
4508 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4510 UnlockLists();
4511 alcSetError(device, ALC_INVALID_DEVICE);
4512 if(device) ALCdevice_DecRef(device);
4513 return ALC_FALSE;
4515 almtx_lock(&device->BackendLock);
4516 UnlockLists();
4518 err = UpdateDeviceParams(device, attribs);
4519 almtx_unlock(&device->BackendLock);
4521 if(err != ALC_NO_ERROR)
4523 alcSetError(device, err);
4524 if(err == ALC_INVALID_DEVICE)
4526 V0(device->Backend,lock)();
4527 aluHandleDisconnect(device);
4528 V0(device->Backend,unlock)();
4530 ALCdevice_DecRef(device);
4531 return ALC_FALSE;
4533 ALCdevice_DecRef(device);
4535 return ALC_TRUE;