Remove an unnecessary variable
[openal-soft.git] / Alc / ALc.c
blob882a8cb02630789ec2fc187a16ddb6158a1c5884
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;
1708 /* Tell the mixer to stop applying updates, then wait for any active
1709 * updating to finish, before providing updates.
1711 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE);
1712 while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
1713 althrd_yield();
1715 UpdateListenerProps(context);
1716 UpdateAllEffectSlotProps(context);
1718 LockUIntMapRead(&context->SourceMap);
1719 V0(device->Backend,lock)();
1720 for(pos = 0;pos < context->VoiceCount;pos++)
1722 ALvoice *voice = context->Voices[pos];
1723 ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire);
1724 if(source && source->OffsetType != AL_NONE)
1726 WriteLock(&source->queue_lock);
1727 ApplyOffset(source, voice);
1728 WriteUnlock(&source->queue_lock);
1731 for(pos = 0;pos < context->SourceMap.size;pos++)
1733 ALsource *source = context->SourceMap.values[pos];
1734 ALenum new_state = source->new_state;
1735 source->new_state = AL_NONE;
1736 if(new_state)
1737 SetSourceState(source, context, new_state);
1739 V0(device->Backend,unlock)();
1740 UnlockUIntMapRead(&context->SourceMap);
1742 UpdateAllSourceProps(context);
1744 /* Now with all updates declared, let the mixer continue applying them
1745 * so they all happen at once.
1747 ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE);
1749 ReadUnlock(&context->PropLock);
1753 /* alcSetError
1755 * Stores the latest ALC device error
1757 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1759 WARN("Error generated on device %p, code 0x%04x\n", device, errorCode);
1760 if(TrapALCError)
1762 #ifdef _WIN32
1763 /* DebugBreak() will cause an exception if there is no debugger */
1764 if(IsDebuggerPresent())
1765 DebugBreak();
1766 #elif defined(SIGTRAP)
1767 raise(SIGTRAP);
1768 #endif
1771 if(device)
1772 ATOMIC_STORE_SEQ(&device->LastError, errorCode);
1773 else
1774 ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode);
1778 /* UpdateClockBase
1780 * Updates the device's base clock time with however many samples have been
1781 * done. This is used so frequency changes on the device don't cause the time
1782 * to jump forward or back. Must not be called while the device is running/
1783 * mixing.
1785 static inline void UpdateClockBase(ALCdevice *device)
1787 IncrementRef(&device->MixCount);
1788 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1789 device->SamplesDone = 0;
1790 IncrementRef(&device->MixCount);
1793 /* UpdateDeviceParams
1795 * Updates device parameters according to the attribute list (caller is
1796 * responsible for holding the list lock).
1798 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1800 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1801 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1802 const ALsizei old_sends = device->NumAuxSends;
1803 ALsizei new_sends = device->NumAuxSends;
1804 enum DevFmtChannels oldChans;
1805 enum DevFmtType oldType;
1806 ALboolean update_failed;
1807 ALCsizei hrtf_id = -1;
1808 ALCcontext *context;
1809 ALCuint oldFreq;
1810 FPUCtl oldMode;
1811 size_t size;
1812 ALCsizei i;
1814 // Check for attributes
1815 if(device->Type == Loopback)
1817 ALCsizei numMono, numStereo, numSends;
1818 ALCenum alayout = AL_NONE;
1819 ALCenum ascale = AL_NONE;
1820 ALCenum schans = AL_NONE;
1821 ALCenum stype = AL_NONE;
1822 ALCsizei attrIdx = 0;
1823 ALCsizei aorder = 0;
1824 ALCuint freq = 0;
1826 if(!attrList)
1828 WARN("Missing attributes for loopback device\n");
1829 return ALC_INVALID_VALUE;
1832 numMono = device->NumMonoSources;
1833 numStereo = device->NumStereoSources;
1834 numSends = old_sends;
1836 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1837 while(attrList[attrIdx])
1839 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1841 schans = attrList[attrIdx + 1];
1842 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans);
1843 if(!IsValidALCChannels(schans))
1844 return ALC_INVALID_VALUE;
1847 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1849 stype = attrList[attrIdx + 1];
1850 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype);
1851 if(!IsValidALCType(stype))
1852 return ALC_INVALID_VALUE;
1855 if(attrList[attrIdx] == ALC_FREQUENCY)
1857 freq = attrList[attrIdx + 1];
1858 TRACE_ATTR(ALC_FREQUENCY, freq);
1859 if(freq < MIN_OUTPUT_RATE)
1860 return ALC_INVALID_VALUE;
1863 if(attrList[attrIdx] == ALC_AMBISONIC_LAYOUT_SOFT)
1865 alayout = attrList[attrIdx + 1];
1866 TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout);
1867 if(!IsValidAmbiLayout(alayout))
1868 return ALC_INVALID_VALUE;
1871 if(attrList[attrIdx] == ALC_AMBISONIC_SCALING_SOFT)
1873 ascale = attrList[attrIdx + 1];
1874 TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale);
1875 if(!IsValidAmbiScaling(ascale))
1876 return ALC_INVALID_VALUE;
1879 if(attrList[attrIdx] == ALC_AMBISONIC_ORDER_SOFT)
1881 aorder = attrList[attrIdx + 1];
1882 TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder);
1883 if(aorder < 1 || aorder > MAX_AMBI_ORDER)
1884 return ALC_INVALID_VALUE;
1887 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1889 numStereo = attrList[attrIdx + 1];
1890 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1892 numStereo = clampi(numStereo, 0, device->SourcesMax);
1893 numMono = device->SourcesMax - numStereo;
1896 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1898 numSends = attrList[attrIdx + 1];
1899 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1900 numSends = clampi(numSends, 0, MAX_SENDS);
1903 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1905 ALCint val = attrList[attrIdx + 1];
1906 TRACE_ATTR(ALC_HRTF_SOFT, val);
1907 if(val == ALC_FALSE)
1908 hrtf_appreq = Hrtf_Disable;
1909 else if(val == ALC_TRUE)
1910 hrtf_appreq = Hrtf_Enable;
1911 else
1912 hrtf_appreq = Hrtf_Default;
1915 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1917 hrtf_id = attrList[attrIdx + 1];
1918 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1921 attrIdx += 2;
1923 #undef TRACE_ATTR
1925 if(!schans || !stype || !freq)
1927 WARN("Missing format for loopback device\n");
1928 return ALC_INVALID_VALUE;
1930 if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder))
1932 WARN("Missing ambisonic info for loopback device\n");
1933 return ALC_INVALID_VALUE;
1936 if((device->Flags&DEVICE_RUNNING))
1937 V0(device->Backend,stop)();
1938 device->Flags &= ~DEVICE_RUNNING;
1940 UpdateClockBase(device);
1942 if(schans == ALC_BFORMAT3D_SOFT)
1944 device->FmtChans = DevFmtAmbi1 + aorder;
1945 device->AmbiLayout = alayout;
1946 device->AmbiScale = ascale;
1948 else
1949 device->FmtChans = schans;
1950 device->Frequency = freq;
1951 device->FmtType = stype;
1952 device->NumMonoSources = numMono;
1953 device->NumStereoSources = numStereo;
1955 if(ConfigValueInt(NULL, NULL, "sends", &new_sends))
1956 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
1957 else
1958 new_sends = numSends;
1960 else if(attrList && attrList[0])
1962 ALCsizei numMono, numStereo, numSends;
1963 ALCsizei attrIdx = 0;
1964 ALCuint freq;
1966 /* If a context is already running on the device, stop playback so the
1967 * device attributes can be updated. */
1968 if((device->Flags&DEVICE_RUNNING))
1969 V0(device->Backend,stop)();
1970 device->Flags &= ~DEVICE_RUNNING;
1972 UpdateClockBase(device);
1974 freq = device->Frequency;
1975 numMono = device->NumMonoSources;
1976 numStereo = device->NumStereoSources;
1977 numSends = old_sends;
1979 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1980 while(attrList[attrIdx])
1982 if(attrList[attrIdx] == ALC_FREQUENCY)
1984 freq = attrList[attrIdx + 1];
1985 TRACE_ATTR(ALC_FREQUENCY, freq);
1986 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1989 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1991 numStereo = attrList[attrIdx + 1];
1992 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1994 numStereo = clampi(numStereo, 0, device->SourcesMax);
1995 numMono = device->SourcesMax - numStereo;
1998 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
2000 numSends = attrList[attrIdx + 1];
2001 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
2002 numSends = clampi(numSends, 0, MAX_SENDS);
2005 if(attrList[attrIdx] == ALC_HRTF_SOFT)
2007 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
2008 if(attrList[attrIdx + 1] == ALC_FALSE)
2009 hrtf_appreq = Hrtf_Disable;
2010 else if(attrList[attrIdx + 1] == ALC_TRUE)
2011 hrtf_appreq = Hrtf_Enable;
2012 else
2013 hrtf_appreq = Hrtf_Default;
2016 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
2018 hrtf_id = attrList[attrIdx + 1];
2019 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
2022 attrIdx += 2;
2024 #undef TRACE_ATTR
2026 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
2027 freq = maxu(freq, MIN_OUTPUT_RATE);
2029 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
2030 device->Frequency;
2031 /* SSE and Neon do best with the update size being a multiple of 4 */
2032 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
2033 device->UpdateSize = (device->UpdateSize+3)&~3;
2035 device->Frequency = freq;
2036 device->NumMonoSources = numMono;
2037 device->NumStereoSources = numStereo;
2039 if(ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &new_sends))
2040 new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS));
2041 else
2042 new_sends = numSends;
2045 if((device->Flags&DEVICE_RUNNING))
2046 return ALC_NO_ERROR;
2048 al_free(device->Uhj_Encoder);
2049 device->Uhj_Encoder = NULL;
2051 al_free(device->Bs2b);
2052 device->Bs2b = NULL;
2054 al_free(device->ChannelDelay[0].Buffer);
2055 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2057 device->ChannelDelay[i].Length = 0;
2058 device->ChannelDelay[i].Buffer = NULL;
2061 al_free(device->Dry.Buffer);
2062 device->Dry.Buffer = NULL;
2063 device->Dry.NumChannels = 0;
2064 device->FOAOut.Buffer = NULL;
2065 device->FOAOut.NumChannels = 0;
2066 device->RealOut.Buffer = NULL;
2067 device->RealOut.NumChannels = 0;
2069 UpdateClockBase(device);
2071 /*************************************************************************
2072 * Update device format request if HRTF is requested
2074 device->Hrtf.Status = ALC_HRTF_DISABLED_SOFT;
2075 if(device->Type != Loopback)
2077 const char *hrtf;
2078 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
2080 if(strcasecmp(hrtf, "true") == 0)
2081 hrtf_userreq = Hrtf_Enable;
2082 else if(strcasecmp(hrtf, "false") == 0)
2083 hrtf_userreq = Hrtf_Disable;
2084 else if(strcasecmp(hrtf, "auto") != 0)
2085 ERR("Unexpected hrtf value: %s\n", hrtf);
2088 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
2090 if(VECTOR_SIZE(device->Hrtf.List) == 0)
2092 VECTOR_DEINIT(device->Hrtf.List);
2093 device->Hrtf.List = EnumerateHrtf(device->DeviceName);
2095 if(VECTOR_SIZE(device->Hrtf.List) > 0)
2097 device->FmtChans = DevFmtStereo;
2098 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf.List))
2099 device->Frequency = VECTOR_ELEM(device->Hrtf.List, hrtf_id).hrtf->sampleRate;
2100 else
2101 device->Frequency = VECTOR_ELEM(device->Hrtf.List, 0).hrtf->sampleRate;
2102 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
2104 else
2106 hrtf_userreq = Hrtf_Default;
2107 hrtf_appreq = Hrtf_Disable;
2108 device->Hrtf.Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2112 else if(hrtf_appreq == Hrtf_Enable)
2114 size_t i = VECTOR_SIZE(device->Hrtf.List);
2115 /* Loopback device. We don't need to match to a specific HRTF entry
2116 * here. If the requested ID matches, we'll pick that later, if not,
2117 * we'll try to auto-select one anyway. Just make sure one exists
2118 * that'll work.
2120 if(device->FmtChans == DevFmtStereo)
2122 if(VECTOR_SIZE(device->Hrtf.List) == 0)
2124 VECTOR_DEINIT(device->Hrtf.List);
2125 device->Hrtf.List = EnumerateHrtf(device->DeviceName);
2127 for(i = 0;i < VECTOR_SIZE(device->Hrtf.List);i++)
2129 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf.List, i).hrtf;
2130 if(hrtf->sampleRate == device->Frequency)
2131 break;
2134 if(i == VECTOR_SIZE(device->Hrtf.List))
2136 ERR("Requested format not HRTF compatible: %s, %uhz\n",
2137 DevFmtChannelsString(device->FmtChans), device->Frequency);
2138 hrtf_appreq = Hrtf_Disable;
2139 device->Hrtf.Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2143 oldFreq = device->Frequency;
2144 oldChans = device->FmtChans;
2145 oldType = device->FmtType;
2147 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
2148 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
2149 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
2150 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
2151 device->UpdateSize, device->NumUpdates
2154 if(V0(device->Backend,reset)() == ALC_FALSE)
2155 return ALC_INVALID_DEVICE;
2157 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
2159 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2160 DevFmtChannelsString(device->FmtChans));
2161 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
2163 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2165 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2166 DevFmtTypeString(device->FmtType));
2167 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
2169 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
2171 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2172 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
2175 if((device->UpdateSize&3) != 0)
2177 if((CPUCapFlags&CPU_CAP_SSE))
2178 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2179 if((CPUCapFlags&CPU_CAP_NEON))
2180 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
2183 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
2184 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2185 device->Frequency, device->UpdateSize, device->NumUpdates
2188 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
2189 TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels,
2190 device->FOAOut.NumChannels, device->RealOut.NumChannels);
2192 /* Allocate extra channels for any post-filter output. */
2193 size = (device->Dry.NumChannels + device->FOAOut.NumChannels +
2194 device->RealOut.NumChannels)*sizeof(device->Dry.Buffer[0]);
2196 TRACE("Allocating "SZFMT" channels, "SZFMT" bytes\n", size/sizeof(device->Dry.Buffer[0]), size);
2197 device->Dry.Buffer = al_calloc(16, size);
2198 if(!device->Dry.Buffer)
2200 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2201 return ALC_INVALID_DEVICE;
2204 if(device->RealOut.NumChannels != 0)
2205 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels +
2206 device->FOAOut.NumChannels;
2207 else
2209 device->RealOut.Buffer = device->Dry.Buffer;
2210 device->RealOut.NumChannels = device->Dry.NumChannels;
2213 if(device->FOAOut.NumChannels != 0)
2214 device->FOAOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2215 else
2217 device->FOAOut.Buffer = device->Dry.Buffer;
2218 device->FOAOut.NumChannels = device->Dry.NumChannels;
2221 /* Need to delay returning failure until replacement Send arrays have been
2222 * allocated with the appropriate size.
2224 device->NumAuxSends = new_sends;
2225 update_failed = AL_FALSE;
2226 SetMixerFPUMode(&oldMode);
2227 if(device->DefaultSlot)
2229 ALeffectslot *slot = device->DefaultSlot;
2230 ALeffectState *state = slot->Effect.State;
2232 state->OutBuffer = device->Dry.Buffer;
2233 state->OutChannels = device->Dry.NumChannels;
2234 if(V(state,deviceUpdate)(device) == AL_FALSE)
2235 update_failed = AL_TRUE;
2236 else
2237 UpdateEffectSlotProps(slot);
2240 context = ATOMIC_LOAD_SEQ(&device->ContextList);
2241 while(context)
2243 ALsizei pos;
2245 WriteLock(&context->PropLock);
2246 LockUIntMapRead(&context->EffectSlotMap);
2247 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2249 ALeffectslot *slot = context->EffectSlotMap.values[pos];
2250 ALeffectState *state = slot->Effect.State;
2252 state->OutBuffer = device->Dry.Buffer;
2253 state->OutChannels = device->Dry.NumChannels;
2254 if(V(state,deviceUpdate)(device) == AL_FALSE)
2255 update_failed = AL_TRUE;
2256 else
2257 UpdateEffectSlotProps(slot);
2259 UnlockUIntMapRead(&context->EffectSlotMap);
2261 LockUIntMapRead(&context->SourceMap);
2262 for(pos = 0;pos < context->SourceMap.size;pos++)
2264 ALsource *source = context->SourceMap.values[pos];
2265 struct ALsourceProps *props;
2267 if(old_sends != device->NumAuxSends)
2269 ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0]));
2270 ALsizei s;
2272 memcpy(sends, source->Send,
2273 mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0])
2275 for(s = device->NumAuxSends;s < old_sends;s++)
2277 if(source->Send[s].Slot)
2278 DecrementRef(&source->Send[s].Slot->ref);
2279 source->Send[s].Slot = NULL;
2281 al_free(source->Send);
2282 source->Send = sends;
2283 for(s = old_sends;s < device->NumAuxSends;s++)
2285 source->Send[s].Slot = NULL;
2286 source->Send[s].Gain = 1.0f;
2287 source->Send[s].GainHF = 1.0f;
2288 source->Send[s].HFReference = LOWPASSFREQREF;
2289 source->Send[s].GainLF = 1.0f;
2290 source->Send[s].LFReference = HIGHPASSFREQREF;
2294 source->NeedsUpdate = AL_TRUE;
2296 /* Clear any pre-existing source property structs, in case the
2297 * number of auxiliary sends changed. Playing (or paused) sources
2298 * will have updates respecified in UpdateAllSourceProps.
2300 props = ATOMIC_EXCHANGE_SEQ(struct ALsourceProps*, &source->Update, NULL);
2301 al_free(props);
2303 props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->FreeList, NULL,
2304 almemory_order_relaxed);
2305 while(props)
2307 struct ALsourceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
2308 al_free(props);
2309 props = next;
2312 AllocateVoices(context, context->MaxVoices, old_sends);
2313 UnlockUIntMapRead(&context->SourceMap);
2315 UpdateListenerProps(context);
2316 UpdateAllSourceProps(context);
2317 WriteUnlock(&context->PropLock);
2319 context = context->next;
2321 RestoreFPUMode(&oldMode);
2322 if(update_failed)
2323 return ALC_INVALID_DEVICE;
2325 if(!(device->Flags&DEVICE_PAUSED))
2327 if(V0(device->Backend,start)() == ALC_FALSE)
2328 return ALC_INVALID_DEVICE;
2329 device->Flags |= DEVICE_RUNNING;
2332 return ALC_NO_ERROR;
2335 /* FreeDevice
2337 * Frees the device structure, and destroys any objects the app failed to
2338 * delete. Called once there's no more references on the device.
2340 static ALCvoid FreeDevice(ALCdevice *device)
2342 ALsizei i;
2344 TRACE("%p\n", device);
2346 V0(device->Backend,close)();
2347 DELETE_OBJ(device->Backend);
2348 device->Backend = NULL;
2350 almtx_destroy(&device->BackendLock);
2352 if(device->DefaultSlot)
2354 DeinitEffectSlot(device->DefaultSlot);
2355 device->DefaultSlot = NULL;
2358 if(device->BufferMap.size > 0)
2360 WARN("(%p) Deleting %d Buffer%s\n", device, device->BufferMap.size,
2361 (device->BufferMap.size==1)?"":"s");
2362 ReleaseALBuffers(device);
2364 ResetUIntMap(&device->BufferMap);
2366 if(device->EffectMap.size > 0)
2368 WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
2369 (device->EffectMap.size==1)?"":"s");
2370 ReleaseALEffects(device);
2372 ResetUIntMap(&device->EffectMap);
2374 if(device->FilterMap.size > 0)
2376 WARN("(%p) Deleting %d Filter%s\n", device, device->FilterMap.size,
2377 (device->FilterMap.size==1)?"":"s");
2378 ReleaseALFilters(device);
2380 ResetUIntMap(&device->FilterMap);
2382 AL_STRING_DEINIT(device->Hrtf.Name);
2383 FreeHrtfList(&device->Hrtf.List);
2385 al_free(device->Bs2b);
2386 device->Bs2b = NULL;
2388 al_free(device->Uhj_Encoder);
2389 device->Uhj_Encoder = NULL;
2391 bformatdec_free(device->AmbiDecoder);
2392 device->AmbiDecoder = NULL;
2394 ambiup_free(device->AmbiUp);
2395 device->AmbiUp = NULL;
2397 al_free(device->ChannelDelay[0].Buffer);
2398 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
2400 device->ChannelDelay[i].Gain = 1.0f;
2401 device->ChannelDelay[i].Length = 0;
2402 device->ChannelDelay[i].Buffer = NULL;
2405 AL_STRING_DEINIT(device->DeviceName);
2407 al_free(device->Dry.Buffer);
2408 device->Dry.Buffer = NULL;
2409 device->Dry.NumChannels = 0;
2410 device->FOAOut.Buffer = NULL;
2411 device->FOAOut.NumChannels = 0;
2412 device->RealOut.Buffer = NULL;
2413 device->RealOut.NumChannels = 0;
2415 al_free(device);
2419 void ALCdevice_IncRef(ALCdevice *device)
2421 uint ref;
2422 ref = IncrementRef(&device->ref);
2423 TRACEREF("%p increasing refcount to %u\n", device, ref);
2426 void ALCdevice_DecRef(ALCdevice *device)
2428 uint ref;
2429 ref = DecrementRef(&device->ref);
2430 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2431 if(ref == 0) FreeDevice(device);
2434 /* VerifyDevice
2436 * Checks if the device handle is valid, and increments its ref count if so.
2438 static ALCboolean VerifyDevice(ALCdevice **device)
2440 ALCdevice *tmpDevice;
2442 LockLists();
2443 tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList);
2444 while(tmpDevice)
2446 if(tmpDevice == *device)
2448 ALCdevice_IncRef(tmpDevice);
2449 UnlockLists();
2450 return ALC_TRUE;
2452 tmpDevice = tmpDevice->next;
2454 UnlockLists();
2456 *device = NULL;
2457 return ALC_FALSE;
2461 /* InitContext
2463 * Initializes context fields
2465 static ALvoid InitContext(ALCcontext *Context)
2467 ALlistener *listener = Context->Listener;
2469 //Initialise listener
2470 listener->Gain = 1.0f;
2471 listener->MetersPerUnit = 1.0f;
2472 listener->Position[0] = 0.0f;
2473 listener->Position[1] = 0.0f;
2474 listener->Position[2] = 0.0f;
2475 listener->Velocity[0] = 0.0f;
2476 listener->Velocity[1] = 0.0f;
2477 listener->Velocity[2] = 0.0f;
2478 listener->Forward[0] = 0.0f;
2479 listener->Forward[1] = 0.0f;
2480 listener->Forward[2] = -1.0f;
2481 listener->Up[0] = 0.0f;
2482 listener->Up[1] = 1.0f;
2483 listener->Up[2] = 0.0f;
2485 aluMatrixfSet(&listener->Params.Matrix,
2486 1.0f, 0.0f, 0.0f, 0.0f,
2487 0.0f, 1.0f, 0.0f, 0.0f,
2488 0.0f, 0.0f, 1.0f, 0.0f,
2489 0.0f, 0.0f, 0.0f, 1.0f
2491 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2492 listener->Params.Gain = 1.0f;
2493 listener->Params.MetersPerUnit = 1.0f;
2494 listener->Params.DopplerFactor = 1.0f;
2495 listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2497 ATOMIC_INIT(&listener->Update, NULL);
2498 ATOMIC_INIT(&listener->FreeList, NULL);
2500 //Validate Context
2501 InitRef(&Context->UpdateCount, 0);
2502 ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE);
2503 Context->GainBoost = 1.0f;
2504 RWLockInit(&Context->PropLock);
2505 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2506 InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax);
2507 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2509 //Set globals
2510 Context->DistanceModel = DefaultDistanceModel;
2511 Context->SourceDistanceModel = AL_FALSE;
2512 Context->DopplerFactor = 1.0f;
2513 Context->DopplerVelocity = 1.0f;
2514 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2515 ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
2517 Context->ExtensionList = alExtList;
2521 /* FreeContext
2523 * Cleans up the context, and destroys any remaining objects the app failed to
2524 * delete. Called once there's no more references on the context.
2526 static void FreeContext(ALCcontext *context)
2528 ALlistener *listener = context->Listener;
2529 struct ALlistenerProps *lprops;
2530 size_t count;
2532 TRACE("%p\n", context);
2534 if(context->SourceMap.size > 0)
2536 WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size,
2537 (context->SourceMap.size==1)?"":"s");
2538 ReleaseALSources(context);
2540 ResetUIntMap(&context->SourceMap);
2542 if(context->EffectSlotMap.size > 0)
2544 WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
2545 (context->EffectSlotMap.size==1)?"":"s");
2546 ReleaseALAuxiliaryEffectSlots(context);
2548 ResetUIntMap(&context->EffectSlotMap);
2550 al_free(context->Voices);
2551 context->Voices = NULL;
2552 context->VoiceCount = 0;
2553 context->MaxVoices = 0;
2555 if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
2557 TRACE("Freed unapplied listener update %p\n", lprops);
2558 al_free(lprops);
2560 count = 0;
2561 lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
2562 while(lprops)
2564 struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
2565 al_free(lprops);
2566 lprops = next;
2567 ++count;
2569 TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
2571 ALCdevice_DecRef(context->Device);
2572 context->Device = NULL;
2574 //Invalidate context
2575 memset(context, 0, sizeof(ALCcontext));
2576 al_free(context);
2579 /* ReleaseContext
2581 * Removes the context reference from the given device and removes it from
2582 * being current on the running thread or globally.
2584 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2586 ALCcontext *origctx;
2588 if(altss_get(LocalContext) == context)
2590 WARN("%p released while current on thread\n", context);
2591 altss_set(LocalContext, NULL);
2592 ALCcontext_DecRef(context);
2595 origctx = context;
2596 if(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &GlobalContext, &origctx, NULL))
2597 ALCcontext_DecRef(context);
2599 ALCdevice_Lock(device);
2600 origctx = context;
2601 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &device->ContextList,
2602 &origctx, context->next))
2604 ALCcontext *volatile*list = &origctx->next;
2605 while(*list)
2607 if(*list == context)
2609 *list = (*list)->next;
2610 break;
2612 list = &(*list)->next;
2615 ALCdevice_Unlock(device);
2617 ALCcontext_DecRef(context);
2620 void ALCcontext_IncRef(ALCcontext *context)
2622 uint ref = IncrementRef(&context->ref);
2623 TRACEREF("%p increasing refcount to %u\n", context, ref);
2626 void ALCcontext_DecRef(ALCcontext *context)
2628 uint ref = DecrementRef(&context->ref);
2629 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2630 if(ref == 0) FreeContext(context);
2633 static void ReleaseThreadCtx(void *ptr)
2635 ALCcontext *context = ptr;
2636 uint ref = DecrementRef(&context->ref);
2637 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2638 ERR("Context %p current for thread being destroyed, possible leak!\n", context);
2641 /* VerifyContext
2643 * Checks that the given context is valid, and increments its reference count.
2645 static ALCboolean VerifyContext(ALCcontext **context)
2647 ALCdevice *dev;
2649 LockLists();
2650 dev = ATOMIC_LOAD_SEQ(&DeviceList);
2651 while(dev)
2653 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire);
2654 while(ctx)
2656 if(ctx == *context)
2658 ALCcontext_IncRef(ctx);
2659 UnlockLists();
2660 return ALC_TRUE;
2662 ctx = ctx->next;
2664 dev = dev->next;
2666 UnlockLists();
2668 *context = NULL;
2669 return ALC_FALSE;
2673 /* GetContextRef
2675 * Returns the currently active context for this thread, and adds a reference
2676 * without locking it.
2678 ALCcontext *GetContextRef(void)
2680 ALCcontext *context;
2682 context = altss_get(LocalContext);
2683 if(context)
2684 ALCcontext_IncRef(context);
2685 else
2687 LockLists();
2688 context = ATOMIC_LOAD_SEQ(&GlobalContext);
2689 if(context)
2690 ALCcontext_IncRef(context);
2691 UnlockLists();
2694 return context;
2698 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
2700 ALCdevice *device = context->Device;
2701 ALsizei num_sends = device->NumAuxSends;
2702 struct ALsourceProps *props;
2703 size_t sizeof_props;
2704 size_t sizeof_voice;
2705 ALvoice **voices;
2706 ALvoice *voice;
2707 ALsizei v = 0;
2708 size_t size;
2710 if(num_voices == context->MaxVoices && num_sends == old_sends)
2711 return;
2713 /* Allocate the voice pointers, voices, and the voices' stored source
2714 * property set (including the dynamically-sized Send[] array) in one
2715 * chunk.
2717 sizeof_props = RoundUp(offsetof(struct ALsourceProps, Send[num_sends]), 16);
2718 sizeof_voice = RoundUp(offsetof(ALvoice, Send[num_sends]), 16);
2719 size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
2721 voices = al_calloc(16, RoundUp(size*num_voices, 16));
2722 /* The voice and property objects are stored interleaved since they're
2723 * paired together.
2725 voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
2726 props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
2728 if(context->Voices)
2730 ALsizei v_count = mini(context->VoiceCount, num_voices);
2731 for(;v < v_count;v++)
2733 ALsizei s_count = mini(old_sends, num_sends);
2734 ALsizei i;
2736 /* Copy the old voice data and source property set to the new
2737 * storage.
2739 *voice = *(context->Voices[v]);
2740 for(i = 0;i < s_count;i++)
2741 voice->Send[i] = context->Voices[v]->Send[i];
2742 *props = *(context->Voices[v]->Props);
2743 for(i = 0;i < s_count;i++)
2744 props->Send[i] = context->Voices[v]->Props->Send[i];
2746 /* Set this voice's property set pointer and voice reference. */
2747 voice->Props = props;
2748 voices[v] = voice;
2750 /* Increment pointers to the next storage space. */
2751 voice = (ALvoice*)((char*)props + sizeof_props);
2752 props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
2755 /* Finish setting the voices' property set pointers and references. */
2756 for(;v < num_voices;v++)
2758 voice->Props = props;
2759 voices[v] = voice;
2761 voice = (ALvoice*)((char*)props + sizeof_props);
2762 props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
2765 al_free(context->Voices);
2766 context->Voices = voices;
2767 context->MaxVoices = num_voices;
2768 context->VoiceCount = mini(context->VoiceCount, num_voices);
2772 /************************************************
2773 * Standard ALC functions
2774 ************************************************/
2776 /* alcGetError
2778 * Return last ALC generated error code for the given device
2780 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2782 ALCenum errorCode;
2784 if(VerifyDevice(&device))
2786 errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &device->LastError, ALC_NO_ERROR);
2787 ALCdevice_DecRef(device);
2789 else
2790 errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2792 return errorCode;
2796 /* alcSuspendContext
2798 * Suspends updates for the given context
2800 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2802 if(!SuspendDefers)
2803 return;
2805 if(!VerifyContext(&context))
2806 alcSetError(NULL, ALC_INVALID_CONTEXT);
2807 else
2809 ALCcontext_DeferUpdates(context, DeferAllowPlay);
2810 ALCcontext_DecRef(context);
2814 /* alcProcessContext
2816 * Resumes processing updates for the given context
2818 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2820 if(!SuspendDefers)
2821 return;
2823 if(!VerifyContext(&context))
2824 alcSetError(NULL, ALC_INVALID_CONTEXT);
2825 else
2827 ALCcontext_ProcessUpdates(context);
2828 ALCcontext_DecRef(context);
2833 /* alcGetString
2835 * Returns information about the device, and error strings
2837 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2839 const ALCchar *value = NULL;
2841 switch(param)
2843 case ALC_NO_ERROR:
2844 value = alcNoError;
2845 break;
2847 case ALC_INVALID_ENUM:
2848 value = alcErrInvalidEnum;
2849 break;
2851 case ALC_INVALID_VALUE:
2852 value = alcErrInvalidValue;
2853 break;
2855 case ALC_INVALID_DEVICE:
2856 value = alcErrInvalidDevice;
2857 break;
2859 case ALC_INVALID_CONTEXT:
2860 value = alcErrInvalidContext;
2861 break;
2863 case ALC_OUT_OF_MEMORY:
2864 value = alcErrOutOfMemory;
2865 break;
2867 case ALC_DEVICE_SPECIFIER:
2868 value = alcDefaultName;
2869 break;
2871 case ALC_ALL_DEVICES_SPECIFIER:
2872 if(VerifyDevice(&Device))
2874 value = al_string_get_cstr(Device->DeviceName);
2875 ALCdevice_DecRef(Device);
2877 else
2879 ProbeAllDevicesList();
2880 value = al_string_get_cstr(alcAllDevicesList);
2882 break;
2884 case ALC_CAPTURE_DEVICE_SPECIFIER:
2885 if(VerifyDevice(&Device))
2887 value = al_string_get_cstr(Device->DeviceName);
2888 ALCdevice_DecRef(Device);
2890 else
2892 ProbeCaptureDeviceList();
2893 value = al_string_get_cstr(alcCaptureDeviceList);
2895 break;
2897 /* Default devices are always first in the list */
2898 case ALC_DEFAULT_DEVICE_SPECIFIER:
2899 value = alcDefaultName;
2900 break;
2902 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2903 if(al_string_empty(alcAllDevicesList))
2904 ProbeAllDevicesList();
2906 VerifyDevice(&Device);
2908 free(alcDefaultAllDevicesSpecifier);
2909 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2910 if(!alcDefaultAllDevicesSpecifier)
2911 alcSetError(Device, ALC_OUT_OF_MEMORY);
2913 value = alcDefaultAllDevicesSpecifier;
2914 if(Device) ALCdevice_DecRef(Device);
2915 break;
2917 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2918 if(al_string_empty(alcCaptureDeviceList))
2919 ProbeCaptureDeviceList();
2921 VerifyDevice(&Device);
2923 free(alcCaptureDefaultDeviceSpecifier);
2924 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2925 if(!alcCaptureDefaultDeviceSpecifier)
2926 alcSetError(Device, ALC_OUT_OF_MEMORY);
2928 value = alcCaptureDefaultDeviceSpecifier;
2929 if(Device) ALCdevice_DecRef(Device);
2930 break;
2932 case ALC_EXTENSIONS:
2933 if(!VerifyDevice(&Device))
2934 value = alcNoDeviceExtList;
2935 else
2937 value = alcExtensionList;
2938 ALCdevice_DecRef(Device);
2940 break;
2942 case ALC_HRTF_SPECIFIER_SOFT:
2943 if(!VerifyDevice(&Device))
2944 alcSetError(NULL, ALC_INVALID_DEVICE);
2945 else
2947 almtx_lock(&Device->BackendLock);
2948 value = (Device->Hrtf.Handle ? al_string_get_cstr(Device->Hrtf.Name) : "");
2949 almtx_unlock(&Device->BackendLock);
2950 ALCdevice_DecRef(Device);
2952 break;
2954 default:
2955 VerifyDevice(&Device);
2956 alcSetError(Device, ALC_INVALID_ENUM);
2957 if(Device) ALCdevice_DecRef(Device);
2958 break;
2961 return value;
2965 static inline ALCsizei NumAttrsForDevice(ALCdevice *device)
2967 if(device->Type == Loopback && device->FmtChans >= DevFmtAmbi1 &&
2968 device->FmtChans <= DevFmtAmbi3)
2969 return 23;
2970 return 17;
2973 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2975 ALCsizei i;
2977 if(size <= 0 || values == NULL)
2979 alcSetError(device, ALC_INVALID_VALUE);
2980 return 0;
2983 if(!device)
2985 switch(param)
2987 case ALC_MAJOR_VERSION:
2988 values[0] = alcMajorVersion;
2989 return 1;
2990 case ALC_MINOR_VERSION:
2991 values[0] = alcMinorVersion;
2992 return 1;
2994 case ALC_ATTRIBUTES_SIZE:
2995 case ALC_ALL_ATTRIBUTES:
2996 case ALC_FREQUENCY:
2997 case ALC_REFRESH:
2998 case ALC_SYNC:
2999 case ALC_MONO_SOURCES:
3000 case ALC_STEREO_SOURCES:
3001 case ALC_CAPTURE_SAMPLES:
3002 case ALC_FORMAT_CHANNELS_SOFT:
3003 case ALC_FORMAT_TYPE_SOFT:
3004 case ALC_AMBISONIC_LAYOUT_SOFT:
3005 case ALC_AMBISONIC_SCALING_SOFT:
3006 case ALC_AMBISONIC_ORDER_SOFT:
3007 alcSetError(NULL, ALC_INVALID_DEVICE);
3008 return 0;
3010 default:
3011 alcSetError(NULL, ALC_INVALID_ENUM);
3012 return 0;
3014 return 0;
3017 if(device->Type == Capture)
3019 switch(param)
3021 case ALC_CAPTURE_SAMPLES:
3022 almtx_lock(&device->BackendLock);
3023 values[0] = V0(device->Backend,availableSamples)();
3024 almtx_unlock(&device->BackendLock);
3025 return 1;
3027 case ALC_CONNECTED:
3028 values[0] = device->Connected;
3029 return 1;
3031 default:
3032 alcSetError(device, ALC_INVALID_ENUM);
3033 return 0;
3035 return 0;
3038 /* render device */
3039 switch(param)
3041 case ALC_MAJOR_VERSION:
3042 values[0] = alcMajorVersion;
3043 return 1;
3045 case ALC_MINOR_VERSION:
3046 values[0] = alcMinorVersion;
3047 return 1;
3049 case ALC_EFX_MAJOR_VERSION:
3050 values[0] = alcEFXMajorVersion;
3051 return 1;
3053 case ALC_EFX_MINOR_VERSION:
3054 values[0] = alcEFXMinorVersion;
3055 return 1;
3057 case ALC_ATTRIBUTES_SIZE:
3058 values[0] = NumAttrsForDevice(device);
3059 return 1;
3061 case ALC_ALL_ATTRIBUTES:
3062 if(size < NumAttrsForDevice(device))
3064 alcSetError(device, ALC_INVALID_VALUE);
3065 return 0;
3068 i = 0;
3069 almtx_lock(&device->BackendLock);
3070 values[i++] = ALC_FREQUENCY;
3071 values[i++] = device->Frequency;
3073 if(device->Type != Loopback)
3075 values[i++] = ALC_REFRESH;
3076 values[i++] = device->Frequency / device->UpdateSize;
3078 values[i++] = ALC_SYNC;
3079 values[i++] = ALC_FALSE;
3081 else
3083 if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3)
3085 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3086 values[i++] = ALC_BFORMAT3D_SOFT;
3088 values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3089 values[i++] = device->AmbiLayout;
3091 values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3092 values[i++] = device->AmbiScale;
3094 values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3095 values[i++] = device->FmtChans-DevFmtAmbi1+1;
3097 else
3099 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3100 values[i++] = device->FmtChans;
3103 values[i++] = ALC_FORMAT_TYPE_SOFT;
3104 values[i++] = device->FmtType;
3107 values[i++] = ALC_MONO_SOURCES;
3108 values[i++] = device->NumMonoSources;
3110 values[i++] = ALC_STEREO_SOURCES;
3111 values[i++] = device->NumStereoSources;
3113 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3114 values[i++] = device->NumAuxSends;
3116 values[i++] = ALC_HRTF_SOFT;
3117 values[i++] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE);
3119 values[i++] = ALC_HRTF_STATUS_SOFT;
3120 values[i++] = device->Hrtf.Status;
3121 almtx_unlock(&device->BackendLock);
3123 values[i++] = 0;
3124 return i;
3126 case ALC_FREQUENCY:
3127 values[0] = device->Frequency;
3128 return 1;
3130 case ALC_REFRESH:
3131 if(device->Type == Loopback)
3133 alcSetError(device, ALC_INVALID_DEVICE);
3134 return 0;
3136 almtx_lock(&device->BackendLock);
3137 values[0] = device->Frequency / device->UpdateSize;
3138 almtx_unlock(&device->BackendLock);
3139 return 1;
3141 case ALC_SYNC:
3142 if(device->Type == Loopback)
3144 alcSetError(device, ALC_INVALID_DEVICE);
3145 return 0;
3147 values[0] = ALC_FALSE;
3148 return 1;
3150 case ALC_FORMAT_CHANNELS_SOFT:
3151 if(device->Type != Loopback)
3153 alcSetError(device, ALC_INVALID_DEVICE);
3154 return 0;
3156 if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3)
3157 values[0] = ALC_BFORMAT3D_SOFT;
3158 else
3159 values[0] = device->FmtChans;
3160 return 1;
3162 case ALC_FORMAT_TYPE_SOFT:
3163 if(device->Type != Loopback)
3165 alcSetError(device, ALC_INVALID_DEVICE);
3166 return 0;
3168 values[0] = device->FmtType;
3169 return 1;
3171 case ALC_AMBISONIC_LAYOUT_SOFT:
3172 if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
3173 device->FmtChans <= DevFmtAmbi3))
3175 alcSetError(device, ALC_INVALID_DEVICE);
3176 return 0;
3178 values[0] = device->AmbiLayout;
3179 return 1;
3181 case ALC_AMBISONIC_SCALING_SOFT:
3182 if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
3183 device->FmtChans <= DevFmtAmbi3))
3185 alcSetError(device, ALC_INVALID_DEVICE);
3186 return 0;
3188 values[0] = device->AmbiScale;
3189 return 1;
3191 case ALC_AMBISONIC_ORDER_SOFT:
3192 if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 &&
3193 device->FmtChans <= DevFmtAmbi3))
3195 alcSetError(device, ALC_INVALID_DEVICE);
3196 return 0;
3198 values[0] = device->FmtChans - DevFmtAmbi1 + 1;
3199 return 1;
3201 case ALC_MONO_SOURCES:
3202 values[0] = device->NumMonoSources;
3203 return 1;
3205 case ALC_STEREO_SOURCES:
3206 values[0] = device->NumStereoSources;
3207 return 1;
3209 case ALC_MAX_AUXILIARY_SENDS:
3210 values[0] = device->NumAuxSends;
3211 return 1;
3213 case ALC_CONNECTED:
3214 values[0] = device->Connected;
3215 return 1;
3217 case ALC_HRTF_SOFT:
3218 values[0] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE);
3219 return 1;
3221 case ALC_HRTF_STATUS_SOFT:
3222 values[0] = device->Hrtf.Status;
3223 return 1;
3225 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3226 almtx_lock(&device->BackendLock);
3227 FreeHrtfList(&device->Hrtf.List);
3228 device->Hrtf.List = EnumerateHrtf(device->DeviceName);
3229 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf.List);
3230 almtx_unlock(&device->BackendLock);
3231 return 1;
3233 default:
3234 alcSetError(device, ALC_INVALID_ENUM);
3235 return 0;
3237 return 0;
3240 /* alcGetIntegerv
3242 * Returns information about the device and the version of OpenAL
3244 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3246 VerifyDevice(&device);
3247 if(size <= 0 || values == NULL)
3248 alcSetError(device, ALC_INVALID_VALUE);
3249 else
3250 GetIntegerv(device, param, size, values);
3251 if(device) ALCdevice_DecRef(device);
3254 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3256 ALCint *ivals;
3257 ALsizei i;
3259 VerifyDevice(&device);
3260 if(size <= 0 || values == NULL)
3261 alcSetError(device, ALC_INVALID_VALUE);
3262 else if(!device || device->Type == Capture)
3264 ivals = malloc(size * sizeof(ALCint));
3265 size = GetIntegerv(device, pname, size, ivals);
3266 for(i = 0;i < size;i++)
3267 values[i] = ivals[i];
3268 free(ivals);
3270 else /* render device */
3272 ClockLatency clock;
3273 ALuint64 basecount;
3274 ALuint samplecount;
3275 ALuint refcount;
3277 switch(pname)
3279 case ALC_ATTRIBUTES_SIZE:
3280 *values = 21;
3281 break;
3283 case ALC_ALL_ATTRIBUTES:
3284 if(size < 21)
3285 alcSetError(device, ALC_INVALID_VALUE);
3286 else
3288 i = 0;
3289 almtx_lock(&device->BackendLock);
3290 values[i++] = ALC_FREQUENCY;
3291 values[i++] = device->Frequency;
3293 if(device->Type != Loopback)
3295 values[i++] = ALC_REFRESH;
3296 values[i++] = device->Frequency / device->UpdateSize;
3298 values[i++] = ALC_SYNC;
3299 values[i++] = ALC_FALSE;
3301 else
3303 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3304 values[i++] = device->FmtChans;
3306 values[i++] = ALC_FORMAT_TYPE_SOFT;
3307 values[i++] = device->FmtType;
3310 values[i++] = ALC_MONO_SOURCES;
3311 values[i++] = device->NumMonoSources;
3313 values[i++] = ALC_STEREO_SOURCES;
3314 values[i++] = device->NumStereoSources;
3316 values[i++] = ALC_MAX_AUXILIARY_SENDS;
3317 values[i++] = device->NumAuxSends;
3319 values[i++] = ALC_HRTF_SOFT;
3320 values[i++] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE);
3322 values[i++] = ALC_HRTF_STATUS_SOFT;
3323 values[i++] = device->Hrtf.Status;
3325 clock = V0(device->Backend,getClockLatency)();
3326 values[i++] = ALC_DEVICE_CLOCK_SOFT;
3327 values[i++] = clock.ClockTime;
3329 values[i++] = ALC_DEVICE_LATENCY_SOFT;
3330 values[i++] = clock.Latency;
3331 almtx_unlock(&device->BackendLock);
3333 values[i++] = 0;
3335 break;
3337 case ALC_DEVICE_CLOCK_SOFT:
3338 almtx_lock(&device->BackendLock);
3339 do {
3340 while(((refcount=ReadRef(&device->MixCount))&1) != 0)
3341 althrd_yield();
3342 basecount = device->ClockBase;
3343 samplecount = device->SamplesDone;
3344 } while(refcount != ReadRef(&device->MixCount));
3345 *values = basecount + (samplecount*DEVICE_CLOCK_RES/device->Frequency);
3346 almtx_unlock(&device->BackendLock);
3347 break;
3349 case ALC_DEVICE_LATENCY_SOFT:
3351 almtx_lock(&device->BackendLock);
3352 clock = V0(device->Backend,getClockLatency)();
3353 almtx_unlock(&device->BackendLock);
3354 *values = clock.Latency;
3356 break;
3358 case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3359 if(size < 2)
3360 alcSetError(device, ALC_INVALID_VALUE);
3361 else
3363 ClockLatency clock;
3364 almtx_lock(&device->BackendLock);
3365 clock = V0(device->Backend,getClockLatency)();
3366 almtx_unlock(&device->BackendLock);
3367 values[0] = clock.ClockTime;
3368 values[1] = clock.Latency;
3370 break;
3372 default:
3373 ivals = malloc(size * sizeof(ALCint));
3374 size = GetIntegerv(device, pname, size, ivals);
3375 for(i = 0;i < size;i++)
3376 values[i] = ivals[i];
3377 free(ivals);
3378 break;
3381 if(device)
3382 ALCdevice_DecRef(device);
3386 /* alcIsExtensionPresent
3388 * Determines if there is support for a particular extension
3390 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3392 ALCboolean bResult = ALC_FALSE;
3394 VerifyDevice(&device);
3396 if(!extName)
3397 alcSetError(device, ALC_INVALID_VALUE);
3398 else
3400 size_t len = strlen(extName);
3401 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3402 while(ptr && *ptr)
3404 if(strncasecmp(ptr, extName, len) == 0 &&
3405 (ptr[len] == '\0' || isspace(ptr[len])))
3407 bResult = ALC_TRUE;
3408 break;
3410 if((ptr=strchr(ptr, ' ')) != NULL)
3412 do {
3413 ++ptr;
3414 } while(isspace(*ptr));
3418 if(device)
3419 ALCdevice_DecRef(device);
3420 return bResult;
3424 /* alcGetProcAddress
3426 * Retrieves the function address for a particular extension function
3428 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3430 ALCvoid *ptr = NULL;
3432 if(!funcName)
3434 VerifyDevice(&device);
3435 alcSetError(device, ALC_INVALID_VALUE);
3436 if(device) ALCdevice_DecRef(device);
3438 else
3440 ALsizei i = 0;
3441 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3442 i++;
3443 ptr = alcFunctions[i].address;
3446 return ptr;
3450 /* alcGetEnumValue
3452 * Get the value for a particular ALC enumeration name
3454 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3456 ALCenum val = 0;
3458 if(!enumName)
3460 VerifyDevice(&device);
3461 alcSetError(device, ALC_INVALID_VALUE);
3462 if(device) ALCdevice_DecRef(device);
3464 else
3466 ALsizei i = 0;
3467 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3468 i++;
3469 val = enumeration[i].value;
3472 return val;
3476 /* alcCreateContext
3478 * Create and attach a context to the given device.
3480 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3482 ALCcontext *ALContext;
3483 ALfloat valf;
3484 ALCenum err;
3486 LockLists();
3487 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3489 UnlockLists();
3490 alcSetError(device, ALC_INVALID_DEVICE);
3491 if(device) ALCdevice_DecRef(device);
3492 return NULL;
3494 almtx_lock(&device->BackendLock);
3495 UnlockLists();
3497 ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR);
3499 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3500 if(ALContext)
3502 InitRef(&ALContext->ref, 1);
3503 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3505 ALContext->Device = device;
3506 ATOMIC_INIT(&ALContext->ActiveAuxSlotList, NULL);
3508 ALContext->Voices = NULL;
3509 ALContext->MaxVoices = 0;
3510 ALContext->VoiceCount = 0;
3511 AllocateVoices(ALContext, 256, device->NumAuxSends);
3513 if(!ALContext || !ALContext->Voices)
3515 almtx_unlock(&device->BackendLock);
3517 if(ALContext)
3519 al_free(ALContext->Voices);
3520 ALContext->Voices = NULL;
3522 al_free(ALContext);
3523 ALContext = NULL;
3526 alcSetError(device, ALC_OUT_OF_MEMORY);
3527 ALCdevice_DecRef(device);
3528 return NULL;
3531 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3533 almtx_unlock(&device->BackendLock);
3535 al_free(ALContext->Voices);
3536 ALContext->Voices = NULL;
3538 al_free(ALContext);
3539 ALContext = NULL;
3541 alcSetError(device, err);
3542 if(err == ALC_INVALID_DEVICE)
3544 V0(device->Backend,lock)();
3545 aluHandleDisconnect(device);
3546 V0(device->Backend,unlock)();
3548 ALCdevice_DecRef(device);
3549 return NULL;
3552 ALCdevice_IncRef(ALContext->Device);
3553 InitContext(ALContext);
3555 if(ConfigValueFloat(al_string_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf))
3557 if(!isfinite(valf))
3558 ERR("volume-adjust must be finite: %f\n", valf);
3559 else
3561 ALfloat db = clampf(valf, -24.0f, 24.0f);
3562 if(db != valf)
3563 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3564 ALContext->GainBoost = powf(10.0f, db/20.0f);
3565 TRACE("volume-adjust gain: %f\n", ALContext->GainBoost);
3568 UpdateListenerProps(ALContext);
3571 ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList);
3572 do {
3573 ALContext->next = head;
3574 } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCcontext*,
3575 &device->ContextList, &head, ALContext) == 0);
3577 almtx_unlock(&device->BackendLock);
3579 ALCdevice_DecRef(device);
3581 TRACE("Created context %p\n", ALContext);
3582 return ALContext;
3585 /* alcDestroyContext
3587 * Remove a context from its device
3589 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3591 ALCdevice *Device;
3593 LockLists();
3594 /* alcGetContextsDevice sets an error for invalid contexts */
3595 Device = alcGetContextsDevice(context);
3596 if(Device)
3598 almtx_lock(&Device->BackendLock);
3599 ReleaseContext(context, Device);
3600 if(!ATOMIC_LOAD_SEQ(&Device->ContextList))
3602 V0(Device->Backend,stop)();
3603 Device->Flags &= ~DEVICE_RUNNING;
3605 almtx_unlock(&Device->BackendLock);
3607 UnlockLists();
3611 /* alcGetCurrentContext
3613 * Returns the currently active context on the calling thread
3615 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3617 ALCcontext *Context = altss_get(LocalContext);
3618 if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext);
3619 return Context;
3622 /* alcGetThreadContext
3624 * Returns the currently active thread-local context
3626 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3628 return altss_get(LocalContext);
3632 /* alcMakeContextCurrent
3634 * Makes the given context the active process-wide context, and removes the
3635 * thread-local context for the calling thread.
3637 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3639 /* context must be valid or NULL */
3640 if(context && !VerifyContext(&context))
3642 alcSetError(NULL, ALC_INVALID_CONTEXT);
3643 return ALC_FALSE;
3645 /* context's reference count is already incremented */
3646 context = ATOMIC_EXCHANGE_SEQ(ALCcontext*, &GlobalContext, context);
3647 if(context) ALCcontext_DecRef(context);
3649 if((context=altss_get(LocalContext)) != NULL)
3651 altss_set(LocalContext, NULL);
3652 ALCcontext_DecRef(context);
3655 return ALC_TRUE;
3658 /* alcSetThreadContext
3660 * Makes the given context the active context for the current thread
3662 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3664 ALCcontext *old;
3666 /* context must be valid or NULL */
3667 if(context && !VerifyContext(&context))
3669 alcSetError(NULL, ALC_INVALID_CONTEXT);
3670 return ALC_FALSE;
3672 /* context's reference count is already incremented */
3673 old = altss_get(LocalContext);
3674 altss_set(LocalContext, context);
3675 if(old) ALCcontext_DecRef(old);
3677 return ALC_TRUE;
3681 /* alcGetContextsDevice
3683 * Returns the device that a particular context is attached to
3685 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3687 ALCdevice *Device;
3689 if(!VerifyContext(&Context))
3691 alcSetError(NULL, ALC_INVALID_CONTEXT);
3692 return NULL;
3694 Device = Context->Device;
3695 ALCcontext_DecRef(Context);
3697 return Device;
3701 /* alcOpenDevice
3703 * Opens the named device.
3705 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3707 const ALCchar *fmt;
3708 ALCdevice *device;
3709 ALCenum err;
3710 ALCsizei i;
3712 DO_INITCONFIG();
3714 if(!PlaybackBackend.name)
3716 alcSetError(NULL, ALC_INVALID_VALUE);
3717 return NULL;
3720 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3721 #ifdef _WIN32
3722 /* Some old Windows apps hardcode these expecting OpenAL to use a
3723 * specific audio API, even when they're not enumerated. Creative's
3724 * router effectively ignores them too.
3726 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3727 || strcasecmp(deviceName, "MMSYSTEM") == 0
3728 #endif
3730 deviceName = NULL;
3732 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3733 if(!device)
3735 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3736 return NULL;
3739 //Validate device
3740 InitRef(&device->ref, 1);
3741 device->Connected = ALC_TRUE;
3742 device->Type = Playback;
3743 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3745 device->Flags = 0;
3746 device->Bs2b = NULL;
3747 device->Uhj_Encoder = NULL;
3748 VECTOR_INIT(device->Hrtf.List);
3749 AL_STRING_INIT(device->Hrtf.Name);
3750 device->Render_Mode = NormalRender;
3751 AL_STRING_INIT(device->DeviceName);
3752 device->Dry.Buffer = NULL;
3753 device->Dry.NumChannels = 0;
3754 device->FOAOut.Buffer = NULL;
3755 device->FOAOut.NumChannels = 0;
3756 device->RealOut.Buffer = NULL;
3757 device->RealOut.NumChannels = 0;
3759 ATOMIC_INIT(&device->ContextList, NULL);
3761 device->ClockBase = 0;
3762 device->SamplesDone = 0;
3764 device->SourcesMax = 256;
3765 device->AuxiliaryEffectSlotMax = 64;
3766 device->NumAuxSends = DEFAULT_SENDS;
3768 InitUIntMap(&device->BufferMap, ~0);
3769 InitUIntMap(&device->EffectMap, ~0);
3770 InitUIntMap(&device->FilterMap, ~0);
3772 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
3774 device->ChannelDelay[i].Gain = 1.0f;
3775 device->ChannelDelay[i].Length = 0;
3776 device->ChannelDelay[i].Buffer = NULL;
3779 //Set output format
3780 device->FmtChans = DevFmtChannelsDefault;
3781 device->FmtType = DevFmtTypeDefault;
3782 device->Frequency = DEFAULT_OUTPUT_RATE;
3783 device->IsHeadphones = AL_FALSE;
3784 device->AmbiLayout = AmbiLayout_Default;
3785 device->AmbiScale = AmbiNorm_Default;
3786 device->NumUpdates = 3;
3787 device->UpdateSize = 1024;
3789 if(!PlaybackBackend.getFactory)
3790 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3791 ALCbackend_Playback);
3792 else
3794 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3795 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3797 if(!device->Backend)
3799 al_free(device);
3800 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3801 return NULL;
3805 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3807 static const struct {
3808 const char name[16];
3809 enum DevFmtChannels chans;
3810 } chanlist[] = {
3811 { "mono", DevFmtMono },
3812 { "stereo", DevFmtStereo },
3813 { "quad", DevFmtQuad },
3814 { "surround51", DevFmtX51 },
3815 { "surround61", DevFmtX61 },
3816 { "surround71", DevFmtX71 },
3817 { "surround51rear", DevFmtX51Rear },
3818 { "ambi1", DevFmtAmbi1 },
3819 { "ambi2", DevFmtAmbi2 },
3820 { "ambi3", DevFmtAmbi3 },
3822 size_t i;
3824 for(i = 0;i < COUNTOF(chanlist);i++)
3826 if(strcasecmp(chanlist[i].name, fmt) == 0)
3828 device->FmtChans = chanlist[i].chans;
3829 device->Flags |= DEVICE_CHANNELS_REQUEST;
3830 break;
3833 if(i == COUNTOF(chanlist))
3834 ERR("Unsupported channels: %s\n", fmt);
3836 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3838 static const struct {
3839 const char name[16];
3840 enum DevFmtType type;
3841 } typelist[] = {
3842 { "int8", DevFmtByte },
3843 { "uint8", DevFmtUByte },
3844 { "int16", DevFmtShort },
3845 { "uint16", DevFmtUShort },
3846 { "int32", DevFmtInt },
3847 { "uint32", DevFmtUInt },
3848 { "float32", DevFmtFloat },
3850 size_t i;
3852 for(i = 0;i < COUNTOF(typelist);i++)
3854 if(strcasecmp(typelist[i].name, fmt) == 0)
3856 device->FmtType = typelist[i].type;
3857 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3858 break;
3861 if(i == COUNTOF(typelist))
3862 ERR("Unsupported sample-type: %s\n", fmt);
3865 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3867 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3868 if(device->Frequency < MIN_OUTPUT_RATE)
3869 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3870 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3873 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3874 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3876 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3877 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3878 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3879 device->UpdateSize = (device->UpdateSize+3)&~3;
3881 ConfigValueUInt(deviceName, NULL, "sources", &device->SourcesMax);
3882 if(device->SourcesMax == 0) device->SourcesMax = 256;
3884 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3885 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
3887 if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends))
3888 device->NumAuxSends = clampi(
3889 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
3892 device->NumStereoSources = 1;
3893 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
3895 // Find a playback device to open
3896 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3898 DELETE_OBJ(device->Backend);
3899 al_free(device);
3900 alcSetError(NULL, err);
3901 return NULL;
3903 almtx_init(&device->BackendLock, almtx_plain);
3905 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
3907 if(strcasecmp(fmt, "fuma") == 0)
3909 device->AmbiLayout = AmbiLayout_FuMa;
3910 device->AmbiScale = AmbiNorm_FuMa;
3912 else if(strcasecmp(fmt, "acn+sn3d") == 0)
3914 device->AmbiLayout = AmbiLayout_ACN;
3915 device->AmbiScale = AmbiNorm_SN3D;
3917 else if(strcasecmp(fmt, "acn+n3d") == 0)
3919 device->AmbiLayout = AmbiLayout_ACN;
3920 device->AmbiScale = AmbiNorm_N3D;
3922 else
3923 ERR("Unsupported ambi-format: %s\n", fmt);
3926 if(DefaultEffect.type != AL_EFFECT_NULL)
3928 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3929 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3931 device->DefaultSlot = NULL;
3932 ERR("Failed to initialize the default effect slot\n");
3934 else
3936 aluInitEffectPanning(device->DefaultSlot);
3937 if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3939 DeinitEffectSlot(device->DefaultSlot);
3940 device->DefaultSlot = NULL;
3941 ERR("Failed to initialize the default effect\n");
3947 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
3948 do {
3949 device->next = head;
3950 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
3953 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3954 return device;
3957 /* alcCloseDevice
3959 * Closes the given device.
3961 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3963 ALCdevice *iter, *origdev;
3964 ALCcontext *ctx;
3966 LockLists();
3967 iter = ATOMIC_LOAD_SEQ(&DeviceList);
3968 do {
3969 if(iter == device)
3970 break;
3971 } while((iter=iter->next) != NULL);
3972 if(!iter || iter->Type == Capture)
3974 alcSetError(iter, ALC_INVALID_DEVICE);
3975 UnlockLists();
3976 return ALC_FALSE;
3978 almtx_lock(&device->BackendLock);
3980 origdev = device;
3981 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next))
3983 ALCdevice *volatile*list = &origdev->next;
3984 while(*list)
3986 if(*list == device)
3988 *list = (*list)->next;
3989 break;
3991 list = &(*list)->next;
3994 UnlockLists();
3996 ctx = ATOMIC_LOAD_SEQ(&device->ContextList);
3997 while(ctx != NULL)
3999 ALCcontext *next = ctx->next;
4000 WARN("Releasing context %p\n", ctx);
4001 ReleaseContext(ctx, device);
4002 ctx = next;
4004 if((device->Flags&DEVICE_RUNNING))
4005 V0(device->Backend,stop)();
4006 device->Flags &= ~DEVICE_RUNNING;
4007 almtx_unlock(&device->BackendLock);
4009 ALCdevice_DecRef(device);
4011 return ALC_TRUE;
4015 /************************************************
4016 * ALC capture functions
4017 ************************************************/
4018 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
4020 ALCdevice *device = NULL;
4021 ALCenum err;
4022 ALCsizei i;
4024 DO_INITCONFIG();
4026 if(!CaptureBackend.name)
4028 alcSetError(NULL, ALC_INVALID_VALUE);
4029 return NULL;
4032 if(samples <= 0)
4034 alcSetError(NULL, ALC_INVALID_VALUE);
4035 return NULL;
4038 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
4039 deviceName = NULL;
4041 device = al_calloc(16, sizeof(ALCdevice));
4042 if(!device)
4044 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4045 return NULL;
4048 //Validate device
4049 InitRef(&device->ref, 1);
4050 device->Connected = ALC_TRUE;
4051 device->Type = Capture;
4053 VECTOR_INIT(device->Hrtf.List);
4054 AL_STRING_INIT(device->Hrtf.Name);
4056 AL_STRING_INIT(device->DeviceName);
4057 device->Dry.Buffer = NULL;
4058 device->Dry.NumChannels = 0;
4059 device->FOAOut.Buffer = NULL;
4060 device->FOAOut.NumChannels = 0;
4061 device->RealOut.Buffer = NULL;
4062 device->RealOut.NumChannels = 0;
4064 InitUIntMap(&device->BufferMap, ~0);
4065 InitUIntMap(&device->EffectMap, ~0);
4066 InitUIntMap(&device->FilterMap, ~0);
4068 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4070 device->ChannelDelay[i].Gain = 1.0f;
4071 device->ChannelDelay[i].Length = 0;
4072 device->ChannelDelay[i].Buffer = NULL;
4075 if(!CaptureBackend.getFactory)
4076 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
4077 ALCbackend_Capture);
4078 else
4080 ALCbackendFactory *factory = CaptureBackend.getFactory();
4081 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
4083 if(!device->Backend)
4085 al_free(device);
4086 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4087 return NULL;
4090 device->Flags |= DEVICE_FREQUENCY_REQUEST;
4091 device->Frequency = frequency;
4093 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
4094 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
4096 al_free(device);
4097 alcSetError(NULL, ALC_INVALID_ENUM);
4098 return NULL;
4100 device->IsHeadphones = AL_FALSE;
4101 device->AmbiLayout = AmbiLayout_Default;
4102 device->AmbiScale = AmbiNorm_Default;
4104 device->UpdateSize = samples;
4105 device->NumUpdates = 1;
4107 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
4109 al_free(device);
4110 alcSetError(NULL, err);
4111 return NULL;
4113 almtx_init(&device->BackendLock, almtx_plain);
4116 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4117 do {
4118 device->next = head;
4119 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
4122 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
4123 return device;
4126 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
4128 ALCdevice *iter, *origdev;
4130 LockLists();
4131 iter = ATOMIC_LOAD_SEQ(&DeviceList);
4132 do {
4133 if(iter == device)
4134 break;
4135 } while((iter=iter->next) != NULL);
4136 if(!iter || iter->Type != Capture)
4138 alcSetError(iter, ALC_INVALID_DEVICE);
4139 UnlockLists();
4140 return ALC_FALSE;
4143 origdev = device;
4144 if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next))
4146 ALCdevice *volatile*list = &origdev->next;
4147 while(*list)
4149 if(*list == device)
4151 *list = (*list)->next;
4152 break;
4154 list = &(*list)->next;
4157 UnlockLists();
4159 ALCdevice_DecRef(device);
4161 return ALC_TRUE;
4164 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
4166 if(!VerifyDevice(&device) || device->Type != Capture)
4167 alcSetError(device, ALC_INVALID_DEVICE);
4168 else
4170 almtx_lock(&device->BackendLock);
4171 if(!device->Connected)
4172 alcSetError(device, ALC_INVALID_DEVICE);
4173 else if(!(device->Flags&DEVICE_RUNNING))
4175 if(V0(device->Backend,start)())
4176 device->Flags |= DEVICE_RUNNING;
4177 else
4179 aluHandleDisconnect(device);
4180 alcSetError(device, ALC_INVALID_DEVICE);
4183 almtx_unlock(&device->BackendLock);
4186 if(device) ALCdevice_DecRef(device);
4189 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
4191 if(!VerifyDevice(&device) || device->Type != Capture)
4192 alcSetError(device, ALC_INVALID_DEVICE);
4193 else
4195 almtx_lock(&device->BackendLock);
4196 if((device->Flags&DEVICE_RUNNING))
4197 V0(device->Backend,stop)();
4198 device->Flags &= ~DEVICE_RUNNING;
4199 almtx_unlock(&device->BackendLock);
4202 if(device) ALCdevice_DecRef(device);
4205 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4207 if(!VerifyDevice(&device) || device->Type != Capture)
4208 alcSetError(device, ALC_INVALID_DEVICE);
4209 else
4211 ALCenum err = ALC_INVALID_VALUE;
4213 almtx_lock(&device->BackendLock);
4214 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
4215 err = V(device->Backend,captureSamples)(buffer, samples);
4216 almtx_unlock(&device->BackendLock);
4218 if(err != ALC_NO_ERROR)
4219 alcSetError(device, err);
4221 if(device) ALCdevice_DecRef(device);
4225 /************************************************
4226 * ALC loopback functions
4227 ************************************************/
4229 /* alcLoopbackOpenDeviceSOFT
4231 * Open a loopback device, for manual rendering.
4233 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
4235 ALCbackendFactory *factory;
4236 ALCdevice *device;
4237 ALCsizei i;
4239 DO_INITCONFIG();
4241 /* Make sure the device name, if specified, is us. */
4242 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
4244 alcSetError(NULL, ALC_INVALID_VALUE);
4245 return NULL;
4248 device = al_calloc(16, sizeof(ALCdevice));
4249 if(!device)
4251 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4252 return NULL;
4255 //Validate device
4256 InitRef(&device->ref, 1);
4257 device->Connected = ALC_TRUE;
4258 device->Type = Loopback;
4259 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
4261 device->Flags = 0;
4262 VECTOR_INIT(device->Hrtf.List);
4263 AL_STRING_INIT(device->Hrtf.Name);
4264 device->Bs2b = NULL;
4265 device->Uhj_Encoder = NULL;
4266 device->Render_Mode = NormalRender;
4267 AL_STRING_INIT(device->DeviceName);
4268 device->Dry.Buffer = NULL;
4269 device->Dry.NumChannels = 0;
4270 device->FOAOut.Buffer = NULL;
4271 device->FOAOut.NumChannels = 0;
4272 device->RealOut.Buffer = NULL;
4273 device->RealOut.NumChannels = 0;
4275 ATOMIC_INIT(&device->ContextList, NULL);
4277 device->ClockBase = 0;
4278 device->SamplesDone = 0;
4280 device->SourcesMax = 256;
4281 device->AuxiliaryEffectSlotMax = 64;
4282 device->NumAuxSends = DEFAULT_SENDS;
4284 InitUIntMap(&device->BufferMap, ~0);
4285 InitUIntMap(&device->EffectMap, ~0);
4286 InitUIntMap(&device->FilterMap, ~0);
4288 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
4290 device->ChannelDelay[i].Gain = 1.0f;
4291 device->ChannelDelay[i].Length = 0;
4292 device->ChannelDelay[i].Buffer = NULL;
4295 factory = ALCloopbackFactory_getFactory();
4296 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
4297 if(!device->Backend)
4299 al_free(device);
4300 alcSetError(NULL, ALC_OUT_OF_MEMORY);
4301 return NULL;
4303 almtx_init(&device->BackendLock, almtx_plain);
4305 //Set output format
4306 device->NumUpdates = 0;
4307 device->UpdateSize = 0;
4309 device->Frequency = DEFAULT_OUTPUT_RATE;
4310 device->FmtChans = DevFmtChannelsDefault;
4311 device->FmtType = DevFmtTypeDefault;
4312 device->IsHeadphones = AL_FALSE;
4313 device->AmbiLayout = AmbiLayout_Default;
4314 device->AmbiScale = AmbiNorm_Default;
4316 ConfigValueUInt(NULL, NULL, "sources", &device->SourcesMax);
4317 if(device->SourcesMax == 0) device->SourcesMax = 256;
4319 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
4320 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64;
4322 if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends))
4323 device->NumAuxSends = clampi(
4324 DEFAULT_SENDS, 0, clampi(device->NumAuxSends, 0, MAX_SENDS)
4327 device->NumStereoSources = 1;
4328 device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
4330 // Open the "backend"
4331 V(device->Backend,open)("Loopback");
4334 ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
4335 do {
4336 device->next = head;
4337 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device));
4340 TRACE("Created device %p\n", device);
4341 return device;
4344 /* alcIsRenderFormatSupportedSOFT
4346 * Determines if the loopback device supports the given format for rendering.
4348 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
4350 ALCboolean ret = ALC_FALSE;
4352 if(!VerifyDevice(&device) || device->Type != Loopback)
4353 alcSetError(device, ALC_INVALID_DEVICE);
4354 else if(freq <= 0)
4355 alcSetError(device, ALC_INVALID_VALUE);
4356 else
4358 if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
4359 ret = ALC_TRUE;
4361 if(device) ALCdevice_DecRef(device);
4363 return ret;
4366 /* alcRenderSamplesSOFT
4368 * Renders some samples into a buffer, using the format last set by the
4369 * attributes given to alcCreateContext.
4371 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
4373 if(!VerifyDevice(&device) || device->Type != Loopback)
4374 alcSetError(device, ALC_INVALID_DEVICE);
4375 else if(samples < 0 || (samples > 0 && buffer == NULL))
4376 alcSetError(device, ALC_INVALID_VALUE);
4377 else
4379 V0(device->Backend,lock)();
4380 aluMixData(device, buffer, samples);
4381 V0(device->Backend,unlock)();
4383 if(device) ALCdevice_DecRef(device);
4387 /************************************************
4388 * ALC loopback2 functions
4389 ************************************************/
4391 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order)
4393 ALCboolean ret = ALC_FALSE;
4395 if(!VerifyDevice(&device) || device->Type != Loopback)
4396 alcSetError(device, ALC_INVALID_DEVICE);
4397 else if(order <= 0)
4398 alcSetError(device, ALC_INVALID_VALUE);
4399 else
4401 if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER)
4402 ret = ALC_TRUE;
4404 if(device) ALCdevice_DecRef(device);
4406 return ret;
4409 /************************************************
4410 * ALC DSP pause/resume functions
4411 ************************************************/
4413 /* alcDevicePauseSOFT
4415 * Pause the DSP to stop audio processing.
4417 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
4419 if(!VerifyDevice(&device) || device->Type != Playback)
4420 alcSetError(device, ALC_INVALID_DEVICE);
4421 else
4423 almtx_lock(&device->BackendLock);
4424 if((device->Flags&DEVICE_RUNNING))
4425 V0(device->Backend,stop)();
4426 device->Flags &= ~DEVICE_RUNNING;
4427 device->Flags |= DEVICE_PAUSED;
4428 almtx_unlock(&device->BackendLock);
4430 if(device) ALCdevice_DecRef(device);
4433 /* alcDeviceResumeSOFT
4435 * Resume the DSP to restart audio processing.
4437 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
4439 if(!VerifyDevice(&device) || device->Type != Playback)
4440 alcSetError(device, ALC_INVALID_DEVICE);
4441 else
4443 almtx_lock(&device->BackendLock);
4444 if((device->Flags&DEVICE_PAUSED))
4446 device->Flags &= ~DEVICE_PAUSED;
4447 if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL)
4449 if(V0(device->Backend,start)() != ALC_FALSE)
4450 device->Flags |= DEVICE_RUNNING;
4451 else
4453 alcSetError(device, ALC_INVALID_DEVICE);
4454 V0(device->Backend,lock)();
4455 aluHandleDisconnect(device);
4456 V0(device->Backend,unlock)();
4460 almtx_unlock(&device->BackendLock);
4462 if(device) ALCdevice_DecRef(device);
4466 /************************************************
4467 * ALC HRTF functions
4468 ************************************************/
4470 /* alcGetStringiSOFT
4472 * Gets a string parameter at the given index.
4474 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
4476 const ALCchar *str = NULL;
4478 if(!VerifyDevice(&device) || device->Type == Capture)
4479 alcSetError(device, ALC_INVALID_DEVICE);
4480 else switch(paramName)
4482 case ALC_HRTF_SPECIFIER_SOFT:
4483 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf.List))
4484 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf.List, index).name);
4485 else
4486 alcSetError(device, ALC_INVALID_VALUE);
4487 break;
4489 default:
4490 alcSetError(device, ALC_INVALID_ENUM);
4491 break;
4493 if(device) ALCdevice_DecRef(device);
4495 return str;
4498 /* alcResetDeviceSOFT
4500 * Resets the given device output, using the specified attribute list.
4502 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4504 ALCenum err;
4506 LockLists();
4507 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
4509 UnlockLists();
4510 alcSetError(device, ALC_INVALID_DEVICE);
4511 if(device) ALCdevice_DecRef(device);
4512 return ALC_FALSE;
4514 almtx_lock(&device->BackendLock);
4515 UnlockLists();
4517 err = UpdateDeviceParams(device, attribs);
4518 almtx_unlock(&device->BackendLock);
4520 if(err != ALC_NO_ERROR)
4522 alcSetError(device, err);
4523 if(err == ALC_INVALID_DEVICE)
4525 V0(device->Backend,lock)();
4526 aluHandleDisconnect(device);
4527 V0(device->Backend,unlock)();
4529 ALCdevice_DecRef(device);
4530 return ALC_FALSE;
4532 ALCdevice_DecRef(device);
4534 return ALC_TRUE;