Remove unnecessary code for the now-unused write offset
[openal-soft.git] / Alc / ALc.c
blobd9cf4e699d0f333bde9d651cd04975c8912bb8c5
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 <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include <ctype.h>
28 #include <signal.h>
30 #include "alMain.h"
31 #include "alSource.h"
32 #include "alListener.h"
33 #include "alThunk.h"
34 #include "alSource.h"
35 #include "alBuffer.h"
36 #include "alAuxEffectSlot.h"
37 #include "alError.h"
38 #include "bformatdec.h"
39 #include "alu.h"
41 #include "compat.h"
42 #include "threads.h"
43 #include "alstring.h"
44 #include "almalloc.h"
46 #include "backends/base.h"
49 /************************************************
50 * Backends
51 ************************************************/
52 struct BackendInfo {
53 const char *name;
54 ALCbackendFactory* (*getFactory)(void);
55 ALCboolean (*Init)(BackendFuncs*);
56 void (*Deinit)(void);
57 void (*Probe)(enum DevProbe);
58 BackendFuncs Funcs;
61 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
62 static struct BackendInfo BackendList[] = {
63 #ifdef HAVE_JACK
64 { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
65 #endif
66 #ifdef HAVE_PULSEAUDIO
67 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
68 #endif
69 #ifdef HAVE_ALSA
70 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
71 #endif
72 #ifdef HAVE_COREAUDIO
73 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
74 #endif
75 #ifdef HAVE_OSS
76 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
77 #endif
78 #ifdef HAVE_SOLARIS
79 { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
80 #endif
81 #ifdef HAVE_SNDIO
82 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
83 #endif
84 #ifdef HAVE_QSA
85 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
86 #endif
87 #ifdef HAVE_MMDEVAPI
88 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
89 #endif
90 #ifdef HAVE_DSOUND
91 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
92 #endif
93 #ifdef HAVE_WINMM
94 { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
95 #endif
96 #ifdef HAVE_PORTAUDIO
97 { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
98 #endif
99 #ifdef HAVE_OPENSL
100 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
101 #endif
103 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
104 #ifdef HAVE_WAVE
105 { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
106 #endif
108 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
110 #undef EmptyFuncs
112 static struct BackendInfo PlaybackBackend;
113 static struct BackendInfo CaptureBackend;
116 /************************************************
117 * Functions, enums, and errors
118 ************************************************/
119 typedef struct ALCfunction {
120 const ALCchar *funcName;
121 ALCvoid *address;
122 } ALCfunction;
124 typedef struct ALCenums {
125 const ALCchar *enumName;
126 ALCenum value;
127 } ALCenums;
129 #define DECL(x) { #x, (ALCvoid*)(x) }
130 static const ALCfunction alcFunctions[] = {
131 DECL(alcCreateContext),
132 DECL(alcMakeContextCurrent),
133 DECL(alcProcessContext),
134 DECL(alcSuspendContext),
135 DECL(alcDestroyContext),
136 DECL(alcGetCurrentContext),
137 DECL(alcGetContextsDevice),
138 DECL(alcOpenDevice),
139 DECL(alcCloseDevice),
140 DECL(alcGetError),
141 DECL(alcIsExtensionPresent),
142 DECL(alcGetProcAddress),
143 DECL(alcGetEnumValue),
144 DECL(alcGetString),
145 DECL(alcGetIntegerv),
146 DECL(alcCaptureOpenDevice),
147 DECL(alcCaptureCloseDevice),
148 DECL(alcCaptureStart),
149 DECL(alcCaptureStop),
150 DECL(alcCaptureSamples),
152 DECL(alcSetThreadContext),
153 DECL(alcGetThreadContext),
155 DECL(alcLoopbackOpenDeviceSOFT),
156 DECL(alcIsRenderFormatSupportedSOFT),
157 DECL(alcRenderSamplesSOFT),
159 DECL(alcDevicePauseSOFT),
160 DECL(alcDeviceResumeSOFT),
162 DECL(alcGetStringiSOFT),
163 DECL(alcResetDeviceSOFT),
165 DECL(alcGetInteger64vSOFT),
167 DECL(alEnable),
168 DECL(alDisable),
169 DECL(alIsEnabled),
170 DECL(alGetString),
171 DECL(alGetBooleanv),
172 DECL(alGetIntegerv),
173 DECL(alGetFloatv),
174 DECL(alGetDoublev),
175 DECL(alGetBoolean),
176 DECL(alGetInteger),
177 DECL(alGetFloat),
178 DECL(alGetDouble),
179 DECL(alGetError),
180 DECL(alIsExtensionPresent),
181 DECL(alGetProcAddress),
182 DECL(alGetEnumValue),
183 DECL(alListenerf),
184 DECL(alListener3f),
185 DECL(alListenerfv),
186 DECL(alListeneri),
187 DECL(alListener3i),
188 DECL(alListeneriv),
189 DECL(alGetListenerf),
190 DECL(alGetListener3f),
191 DECL(alGetListenerfv),
192 DECL(alGetListeneri),
193 DECL(alGetListener3i),
194 DECL(alGetListeneriv),
195 DECL(alGenSources),
196 DECL(alDeleteSources),
197 DECL(alIsSource),
198 DECL(alSourcef),
199 DECL(alSource3f),
200 DECL(alSourcefv),
201 DECL(alSourcei),
202 DECL(alSource3i),
203 DECL(alSourceiv),
204 DECL(alGetSourcef),
205 DECL(alGetSource3f),
206 DECL(alGetSourcefv),
207 DECL(alGetSourcei),
208 DECL(alGetSource3i),
209 DECL(alGetSourceiv),
210 DECL(alSourcePlayv),
211 DECL(alSourceStopv),
212 DECL(alSourceRewindv),
213 DECL(alSourcePausev),
214 DECL(alSourcePlay),
215 DECL(alSourceStop),
216 DECL(alSourceRewind),
217 DECL(alSourcePause),
218 DECL(alSourceQueueBuffers),
219 DECL(alSourceUnqueueBuffers),
220 DECL(alGenBuffers),
221 DECL(alDeleteBuffers),
222 DECL(alIsBuffer),
223 DECL(alBufferData),
224 DECL(alBufferf),
225 DECL(alBuffer3f),
226 DECL(alBufferfv),
227 DECL(alBufferi),
228 DECL(alBuffer3i),
229 DECL(alBufferiv),
230 DECL(alGetBufferf),
231 DECL(alGetBuffer3f),
232 DECL(alGetBufferfv),
233 DECL(alGetBufferi),
234 DECL(alGetBuffer3i),
235 DECL(alGetBufferiv),
236 DECL(alDopplerFactor),
237 DECL(alDopplerVelocity),
238 DECL(alSpeedOfSound),
239 DECL(alDistanceModel),
241 DECL(alGenFilters),
242 DECL(alDeleteFilters),
243 DECL(alIsFilter),
244 DECL(alFilteri),
245 DECL(alFilteriv),
246 DECL(alFilterf),
247 DECL(alFilterfv),
248 DECL(alGetFilteri),
249 DECL(alGetFilteriv),
250 DECL(alGetFilterf),
251 DECL(alGetFilterfv),
252 DECL(alGenEffects),
253 DECL(alDeleteEffects),
254 DECL(alIsEffect),
255 DECL(alEffecti),
256 DECL(alEffectiv),
257 DECL(alEffectf),
258 DECL(alEffectfv),
259 DECL(alGetEffecti),
260 DECL(alGetEffectiv),
261 DECL(alGetEffectf),
262 DECL(alGetEffectfv),
263 DECL(alGenAuxiliaryEffectSlots),
264 DECL(alDeleteAuxiliaryEffectSlots),
265 DECL(alIsAuxiliaryEffectSlot),
266 DECL(alAuxiliaryEffectSloti),
267 DECL(alAuxiliaryEffectSlotiv),
268 DECL(alAuxiliaryEffectSlotf),
269 DECL(alAuxiliaryEffectSlotfv),
270 DECL(alGetAuxiliaryEffectSloti),
271 DECL(alGetAuxiliaryEffectSlotiv),
272 DECL(alGetAuxiliaryEffectSlotf),
273 DECL(alGetAuxiliaryEffectSlotfv),
275 DECL(alDeferUpdatesSOFT),
276 DECL(alProcessUpdatesSOFT),
278 DECL(alSourcedSOFT),
279 DECL(alSource3dSOFT),
280 DECL(alSourcedvSOFT),
281 DECL(alGetSourcedSOFT),
282 DECL(alGetSource3dSOFT),
283 DECL(alGetSourcedvSOFT),
284 DECL(alSourcei64SOFT),
285 DECL(alSource3i64SOFT),
286 DECL(alSourcei64vSOFT),
287 DECL(alGetSourcei64SOFT),
288 DECL(alGetSource3i64SOFT),
289 DECL(alGetSourcei64vSOFT),
291 { NULL, NULL }
293 #undef DECL
295 #define DECL(x) { #x, (x) }
296 static const ALCenums enumeration[] = {
297 DECL(ALC_INVALID),
298 DECL(ALC_FALSE),
299 DECL(ALC_TRUE),
301 DECL(ALC_MAJOR_VERSION),
302 DECL(ALC_MINOR_VERSION),
303 DECL(ALC_ATTRIBUTES_SIZE),
304 DECL(ALC_ALL_ATTRIBUTES),
305 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
306 DECL(ALC_DEVICE_SPECIFIER),
307 DECL(ALC_ALL_DEVICES_SPECIFIER),
308 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
309 DECL(ALC_EXTENSIONS),
310 DECL(ALC_FREQUENCY),
311 DECL(ALC_REFRESH),
312 DECL(ALC_SYNC),
313 DECL(ALC_MONO_SOURCES),
314 DECL(ALC_STEREO_SOURCES),
315 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
316 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
317 DECL(ALC_CAPTURE_SAMPLES),
318 DECL(ALC_CONNECTED),
320 DECL(ALC_EFX_MAJOR_VERSION),
321 DECL(ALC_EFX_MINOR_VERSION),
322 DECL(ALC_MAX_AUXILIARY_SENDS),
324 DECL(ALC_FORMAT_CHANNELS_SOFT),
325 DECL(ALC_FORMAT_TYPE_SOFT),
327 DECL(ALC_MONO_SOFT),
328 DECL(ALC_STEREO_SOFT),
329 DECL(ALC_QUAD_SOFT),
330 DECL(ALC_5POINT1_SOFT),
331 DECL(ALC_6POINT1_SOFT),
332 DECL(ALC_7POINT1_SOFT),
334 DECL(ALC_BYTE_SOFT),
335 DECL(ALC_UNSIGNED_BYTE_SOFT),
336 DECL(ALC_SHORT_SOFT),
337 DECL(ALC_UNSIGNED_SHORT_SOFT),
338 DECL(ALC_INT_SOFT),
339 DECL(ALC_UNSIGNED_INT_SOFT),
340 DECL(ALC_FLOAT_SOFT),
342 DECL(ALC_HRTF_SOFT),
343 DECL(ALC_DONT_CARE_SOFT),
344 DECL(ALC_HRTF_STATUS_SOFT),
345 DECL(ALC_HRTF_DISABLED_SOFT),
346 DECL(ALC_HRTF_ENABLED_SOFT),
347 DECL(ALC_HRTF_DENIED_SOFT),
348 DECL(ALC_HRTF_REQUIRED_SOFT),
349 DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
350 DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
351 DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
352 DECL(ALC_HRTF_SPECIFIER_SOFT),
353 DECL(ALC_HRTF_ID_SOFT),
355 DECL(ALC_NO_ERROR),
356 DECL(ALC_INVALID_DEVICE),
357 DECL(ALC_INVALID_CONTEXT),
358 DECL(ALC_INVALID_ENUM),
359 DECL(ALC_INVALID_VALUE),
360 DECL(ALC_OUT_OF_MEMORY),
363 DECL(AL_INVALID),
364 DECL(AL_NONE),
365 DECL(AL_FALSE),
366 DECL(AL_TRUE),
368 DECL(AL_SOURCE_RELATIVE),
369 DECL(AL_CONE_INNER_ANGLE),
370 DECL(AL_CONE_OUTER_ANGLE),
371 DECL(AL_PITCH),
372 DECL(AL_POSITION),
373 DECL(AL_DIRECTION),
374 DECL(AL_VELOCITY),
375 DECL(AL_LOOPING),
376 DECL(AL_BUFFER),
377 DECL(AL_GAIN),
378 DECL(AL_MIN_GAIN),
379 DECL(AL_MAX_GAIN),
380 DECL(AL_ORIENTATION),
381 DECL(AL_REFERENCE_DISTANCE),
382 DECL(AL_ROLLOFF_FACTOR),
383 DECL(AL_CONE_OUTER_GAIN),
384 DECL(AL_MAX_DISTANCE),
385 DECL(AL_SEC_OFFSET),
386 DECL(AL_SAMPLE_OFFSET),
387 DECL(AL_BYTE_OFFSET),
388 DECL(AL_SOURCE_TYPE),
389 DECL(AL_STATIC),
390 DECL(AL_STREAMING),
391 DECL(AL_UNDETERMINED),
392 DECL(AL_METERS_PER_UNIT),
393 DECL(AL_LOOP_POINTS_SOFT),
394 DECL(AL_DIRECT_CHANNELS_SOFT),
396 DECL(AL_DIRECT_FILTER),
397 DECL(AL_AUXILIARY_SEND_FILTER),
398 DECL(AL_AIR_ABSORPTION_FACTOR),
399 DECL(AL_ROOM_ROLLOFF_FACTOR),
400 DECL(AL_CONE_OUTER_GAINHF),
401 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
402 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
403 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
405 DECL(AL_SOURCE_STATE),
406 DECL(AL_INITIAL),
407 DECL(AL_PLAYING),
408 DECL(AL_PAUSED),
409 DECL(AL_STOPPED),
411 DECL(AL_BUFFERS_QUEUED),
412 DECL(AL_BUFFERS_PROCESSED),
414 DECL(AL_FORMAT_MONO8),
415 DECL(AL_FORMAT_MONO16),
416 DECL(AL_FORMAT_MONO_FLOAT32),
417 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
418 DECL(AL_FORMAT_STEREO8),
419 DECL(AL_FORMAT_STEREO16),
420 DECL(AL_FORMAT_STEREO_FLOAT32),
421 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
422 DECL(AL_FORMAT_MONO_IMA4),
423 DECL(AL_FORMAT_STEREO_IMA4),
424 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
425 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
426 DECL(AL_FORMAT_QUAD8_LOKI),
427 DECL(AL_FORMAT_QUAD16_LOKI),
428 DECL(AL_FORMAT_QUAD8),
429 DECL(AL_FORMAT_QUAD16),
430 DECL(AL_FORMAT_QUAD32),
431 DECL(AL_FORMAT_51CHN8),
432 DECL(AL_FORMAT_51CHN16),
433 DECL(AL_FORMAT_51CHN32),
434 DECL(AL_FORMAT_61CHN8),
435 DECL(AL_FORMAT_61CHN16),
436 DECL(AL_FORMAT_61CHN32),
437 DECL(AL_FORMAT_71CHN8),
438 DECL(AL_FORMAT_71CHN16),
439 DECL(AL_FORMAT_71CHN32),
440 DECL(AL_FORMAT_REAR8),
441 DECL(AL_FORMAT_REAR16),
442 DECL(AL_FORMAT_REAR32),
443 DECL(AL_FORMAT_MONO_MULAW),
444 DECL(AL_FORMAT_MONO_MULAW_EXT),
445 DECL(AL_FORMAT_STEREO_MULAW),
446 DECL(AL_FORMAT_STEREO_MULAW_EXT),
447 DECL(AL_FORMAT_QUAD_MULAW),
448 DECL(AL_FORMAT_51CHN_MULAW),
449 DECL(AL_FORMAT_61CHN_MULAW),
450 DECL(AL_FORMAT_71CHN_MULAW),
451 DECL(AL_FORMAT_REAR_MULAW),
452 DECL(AL_FORMAT_MONO_ALAW_EXT),
453 DECL(AL_FORMAT_STEREO_ALAW_EXT),
455 DECL(AL_MONO8_SOFT),
456 DECL(AL_MONO16_SOFT),
457 DECL(AL_MONO32F_SOFT),
458 DECL(AL_STEREO8_SOFT),
459 DECL(AL_STEREO16_SOFT),
460 DECL(AL_STEREO32F_SOFT),
461 DECL(AL_QUAD8_SOFT),
462 DECL(AL_QUAD16_SOFT),
463 DECL(AL_QUAD32F_SOFT),
464 DECL(AL_REAR8_SOFT),
465 DECL(AL_REAR16_SOFT),
466 DECL(AL_REAR32F_SOFT),
467 DECL(AL_5POINT1_8_SOFT),
468 DECL(AL_5POINT1_16_SOFT),
469 DECL(AL_5POINT1_32F_SOFT),
470 DECL(AL_6POINT1_8_SOFT),
471 DECL(AL_6POINT1_16_SOFT),
472 DECL(AL_6POINT1_32F_SOFT),
473 DECL(AL_7POINT1_8_SOFT),
474 DECL(AL_7POINT1_16_SOFT),
475 DECL(AL_7POINT1_32F_SOFT),
476 DECL(AL_FORMAT_BFORMAT2D_8),
477 DECL(AL_FORMAT_BFORMAT2D_16),
478 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
479 DECL(AL_FORMAT_BFORMAT2D_MULAW),
480 DECL(AL_FORMAT_BFORMAT3D_8),
481 DECL(AL_FORMAT_BFORMAT3D_16),
482 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
483 DECL(AL_FORMAT_BFORMAT3D_MULAW),
485 DECL(AL_MONO_SOFT),
486 DECL(AL_STEREO_SOFT),
487 DECL(AL_QUAD_SOFT),
488 DECL(AL_REAR_SOFT),
489 DECL(AL_5POINT1_SOFT),
490 DECL(AL_6POINT1_SOFT),
491 DECL(AL_7POINT1_SOFT),
493 DECL(AL_BYTE_SOFT),
494 DECL(AL_UNSIGNED_BYTE_SOFT),
495 DECL(AL_SHORT_SOFT),
496 DECL(AL_UNSIGNED_SHORT_SOFT),
497 DECL(AL_INT_SOFT),
498 DECL(AL_UNSIGNED_INT_SOFT),
499 DECL(AL_FLOAT_SOFT),
500 DECL(AL_DOUBLE_SOFT),
501 DECL(AL_BYTE3_SOFT),
502 DECL(AL_UNSIGNED_BYTE3_SOFT),
504 DECL(AL_FREQUENCY),
505 DECL(AL_BITS),
506 DECL(AL_CHANNELS),
507 DECL(AL_SIZE),
508 DECL(AL_INTERNAL_FORMAT_SOFT),
509 DECL(AL_BYTE_LENGTH_SOFT),
510 DECL(AL_SAMPLE_LENGTH_SOFT),
511 DECL(AL_SEC_LENGTH_SOFT),
512 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
513 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
515 DECL(AL_SOURCE_RADIUS),
517 DECL(AL_STEREO_ANGLES),
519 DECL(AL_UNUSED),
520 DECL(AL_PENDING),
521 DECL(AL_PROCESSED),
523 DECL(AL_NO_ERROR),
524 DECL(AL_INVALID_NAME),
525 DECL(AL_INVALID_ENUM),
526 DECL(AL_INVALID_VALUE),
527 DECL(AL_INVALID_OPERATION),
528 DECL(AL_OUT_OF_MEMORY),
530 DECL(AL_VENDOR),
531 DECL(AL_VERSION),
532 DECL(AL_RENDERER),
533 DECL(AL_EXTENSIONS),
535 DECL(AL_DOPPLER_FACTOR),
536 DECL(AL_DOPPLER_VELOCITY),
537 DECL(AL_DISTANCE_MODEL),
538 DECL(AL_SPEED_OF_SOUND),
539 DECL(AL_SOURCE_DISTANCE_MODEL),
540 DECL(AL_DEFERRED_UPDATES_SOFT),
542 DECL(AL_INVERSE_DISTANCE),
543 DECL(AL_INVERSE_DISTANCE_CLAMPED),
544 DECL(AL_LINEAR_DISTANCE),
545 DECL(AL_LINEAR_DISTANCE_CLAMPED),
546 DECL(AL_EXPONENT_DISTANCE),
547 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
549 DECL(AL_FILTER_TYPE),
550 DECL(AL_FILTER_NULL),
551 DECL(AL_FILTER_LOWPASS),
552 DECL(AL_FILTER_HIGHPASS),
553 DECL(AL_FILTER_BANDPASS),
555 DECL(AL_LOWPASS_GAIN),
556 DECL(AL_LOWPASS_GAINHF),
558 DECL(AL_HIGHPASS_GAIN),
559 DECL(AL_HIGHPASS_GAINLF),
561 DECL(AL_BANDPASS_GAIN),
562 DECL(AL_BANDPASS_GAINHF),
563 DECL(AL_BANDPASS_GAINLF),
565 DECL(AL_EFFECT_TYPE),
566 DECL(AL_EFFECT_NULL),
567 DECL(AL_EFFECT_REVERB),
568 DECL(AL_EFFECT_EAXREVERB),
569 DECL(AL_EFFECT_CHORUS),
570 DECL(AL_EFFECT_DISTORTION),
571 DECL(AL_EFFECT_ECHO),
572 DECL(AL_EFFECT_FLANGER),
573 #if 0
574 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
575 DECL(AL_EFFECT_VOCAL_MORPHER),
576 DECL(AL_EFFECT_PITCH_SHIFTER),
577 #endif
578 DECL(AL_EFFECT_RING_MODULATOR),
579 #if 0
580 DECL(AL_EFFECT_AUTOWAH),
581 #endif
582 DECL(AL_EFFECT_COMPRESSOR),
583 DECL(AL_EFFECT_EQUALIZER),
584 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
585 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
587 DECL(AL_EAXREVERB_DENSITY),
588 DECL(AL_EAXREVERB_DIFFUSION),
589 DECL(AL_EAXREVERB_GAIN),
590 DECL(AL_EAXREVERB_GAINHF),
591 DECL(AL_EAXREVERB_GAINLF),
592 DECL(AL_EAXREVERB_DECAY_TIME),
593 DECL(AL_EAXREVERB_DECAY_HFRATIO),
594 DECL(AL_EAXREVERB_DECAY_LFRATIO),
595 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
596 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
597 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
598 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
599 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
600 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
601 DECL(AL_EAXREVERB_ECHO_TIME),
602 DECL(AL_EAXREVERB_ECHO_DEPTH),
603 DECL(AL_EAXREVERB_MODULATION_TIME),
604 DECL(AL_EAXREVERB_MODULATION_DEPTH),
605 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
606 DECL(AL_EAXREVERB_HFREFERENCE),
607 DECL(AL_EAXREVERB_LFREFERENCE),
608 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
609 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
611 DECL(AL_REVERB_DENSITY),
612 DECL(AL_REVERB_DIFFUSION),
613 DECL(AL_REVERB_GAIN),
614 DECL(AL_REVERB_GAINHF),
615 DECL(AL_REVERB_DECAY_TIME),
616 DECL(AL_REVERB_DECAY_HFRATIO),
617 DECL(AL_REVERB_REFLECTIONS_GAIN),
618 DECL(AL_REVERB_REFLECTIONS_DELAY),
619 DECL(AL_REVERB_LATE_REVERB_GAIN),
620 DECL(AL_REVERB_LATE_REVERB_DELAY),
621 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
622 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
623 DECL(AL_REVERB_DECAY_HFLIMIT),
625 DECL(AL_CHORUS_WAVEFORM),
626 DECL(AL_CHORUS_PHASE),
627 DECL(AL_CHORUS_RATE),
628 DECL(AL_CHORUS_DEPTH),
629 DECL(AL_CHORUS_FEEDBACK),
630 DECL(AL_CHORUS_DELAY),
632 DECL(AL_DISTORTION_EDGE),
633 DECL(AL_DISTORTION_GAIN),
634 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
635 DECL(AL_DISTORTION_EQCENTER),
636 DECL(AL_DISTORTION_EQBANDWIDTH),
638 DECL(AL_ECHO_DELAY),
639 DECL(AL_ECHO_LRDELAY),
640 DECL(AL_ECHO_DAMPING),
641 DECL(AL_ECHO_FEEDBACK),
642 DECL(AL_ECHO_SPREAD),
644 DECL(AL_FLANGER_WAVEFORM),
645 DECL(AL_FLANGER_PHASE),
646 DECL(AL_FLANGER_RATE),
647 DECL(AL_FLANGER_DEPTH),
648 DECL(AL_FLANGER_FEEDBACK),
649 DECL(AL_FLANGER_DELAY),
651 DECL(AL_RING_MODULATOR_FREQUENCY),
652 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
653 DECL(AL_RING_MODULATOR_WAVEFORM),
655 #if 0
656 DECL(AL_AUTOWAH_ATTACK_TIME),
657 DECL(AL_AUTOWAH_PEAK_GAIN),
658 DECL(AL_AUTOWAH_RELEASE_TIME),
659 DECL(AL_AUTOWAH_RESONANCE),
660 #endif
662 DECL(AL_COMPRESSOR_ONOFF),
664 DECL(AL_EQUALIZER_LOW_GAIN),
665 DECL(AL_EQUALIZER_LOW_CUTOFF),
666 DECL(AL_EQUALIZER_MID1_GAIN),
667 DECL(AL_EQUALIZER_MID1_CENTER),
668 DECL(AL_EQUALIZER_MID1_WIDTH),
669 DECL(AL_EQUALIZER_MID2_GAIN),
670 DECL(AL_EQUALIZER_MID2_CENTER),
671 DECL(AL_EQUALIZER_MID2_WIDTH),
672 DECL(AL_EQUALIZER_HIGH_GAIN),
673 DECL(AL_EQUALIZER_HIGH_CUTOFF),
675 DECL(AL_DEDICATED_GAIN),
677 { NULL, (ALCenum)0 }
679 #undef DECL
681 static const ALCchar alcNoError[] = "No Error";
682 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
683 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
684 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
685 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
686 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
689 /************************************************
690 * Global variables
691 ************************************************/
693 /* Enumerated device names */
694 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
696 static al_string alcAllDevicesList;
697 static al_string alcCaptureDeviceList;
699 /* Default is always the first in the list */
700 static ALCchar *alcDefaultAllDevicesSpecifier;
701 static ALCchar *alcCaptureDefaultDeviceSpecifier;
703 /* Default context extensions */
704 static const ALchar alExtList[] =
705 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
706 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
707 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
708 "AL_EXT_source_distance_model AL_EXT_SOURCE_RADIUS AL_EXT_STEREO_ANGLES "
709 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_deferred_updates "
710 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
711 "AL_SOFT_source_latency AL_SOFT_source_length";
713 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
715 /* Thread-local current context */
716 static altss_t LocalContext;
717 /* Process-wide current context */
718 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
720 /* Mixing thread piority level */
721 ALint RTPrioLevel;
723 FILE *LogFile;
724 #ifdef _DEBUG
725 enum LogLevel LogLevel = LogWarning;
726 #else
727 enum LogLevel LogLevel = LogError;
728 #endif
730 /* Flag to trap ALC device errors */
731 static ALCboolean TrapALCError = ALC_FALSE;
733 /* One-time configuration init control */
734 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
736 /* Default effect that applies to sources that don't have an effect on send 0 */
737 static ALeffect DefaultEffect;
739 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
740 * updates.
742 static ALCboolean SuspendDefers = ALC_TRUE;
745 /************************************************
746 * ALC information
747 ************************************************/
748 static const ALCchar alcNoDeviceExtList[] =
749 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
750 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
751 static const ALCchar alcExtensionList[] =
752 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
753 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
754 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
755 "ALC_SOFT_loopback ALC_SOFT_pause_device";
756 static const ALCint alcMajorVersion = 1;
757 static const ALCint alcMinorVersion = 1;
759 static const ALCint alcEFXMajorVersion = 1;
760 static const ALCint alcEFXMinorVersion = 0;
763 /************************************************
764 * Device lists
765 ************************************************/
766 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
768 static almtx_t ListLock;
769 static inline void LockLists(void)
771 int lockret = almtx_lock(&ListLock);
772 assert(lockret == althrd_success);
774 static inline void UnlockLists(void)
776 int unlockret = almtx_unlock(&ListLock);
777 assert(unlockret == althrd_success);
780 /************************************************
781 * Library initialization
782 ************************************************/
783 #if defined(_WIN32)
784 static void alc_init(void);
785 static void alc_deinit(void);
786 static void alc_deinit_safe(void);
788 #ifndef AL_LIBTYPE_STATIC
789 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
791 switch(reason)
793 case DLL_PROCESS_ATTACH:
794 /* Pin the DLL so we won't get unloaded until the process terminates */
795 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
796 (WCHAR*)hModule, &hModule);
797 alc_init();
798 break;
800 case DLL_THREAD_DETACH:
801 break;
803 case DLL_PROCESS_DETACH:
804 if(!lpReserved)
805 alc_deinit();
806 else
807 alc_deinit_safe();
808 break;
810 return TRUE;
812 #elif defined(_MSC_VER)
813 #pragma section(".CRT$XCU",read)
814 static void alc_constructor(void);
815 static void alc_destructor(void);
816 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
818 static void alc_constructor(void)
820 atexit(alc_destructor);
821 alc_init();
824 static void alc_destructor(void)
826 alc_deinit();
828 #elif defined(HAVE_GCC_DESTRUCTOR)
829 static void alc_init(void) __attribute__((constructor));
830 static void alc_deinit(void) __attribute__((destructor));
831 #else
832 #error "No static initialization available on this platform!"
833 #endif
835 #elif defined(HAVE_GCC_DESTRUCTOR)
837 static void alc_init(void) __attribute__((constructor));
838 static void alc_deinit(void) __attribute__((destructor));
840 #else
841 #error "No global initialization available on this platform!"
842 #endif
844 static void ReleaseThreadCtx(void *ptr);
845 static void alc_init(void)
847 const char *str;
848 int ret;
850 LogFile = stderr;
852 AL_STRING_INIT(alcAllDevicesList);
853 AL_STRING_INIT(alcCaptureDeviceList);
855 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
856 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
857 ConeScale *= 0.5f;
859 str = getenv("__ALSOFT_REVERSE_Z");
860 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
861 ZScale *= -1.0f;
863 ret = altss_create(&LocalContext, ReleaseThreadCtx);
864 assert(ret == althrd_success);
866 ret = almtx_init(&ListLock, almtx_recursive);
867 assert(ret == althrd_success);
869 ThunkInit();
872 static void alc_initconfig(void)
874 const char *devs, *str;
875 ALuint capfilter;
876 float valf;
877 int i, n;
879 str = getenv("ALSOFT_LOGLEVEL");
880 if(str)
882 long lvl = strtol(str, NULL, 0);
883 if(lvl >= NoLog && lvl <= LogRef)
884 LogLevel = lvl;
887 str = getenv("ALSOFT_LOGFILE");
888 if(str && str[0])
890 FILE *logfile = al_fopen(str, "wt");
891 if(logfile) LogFile = logfile;
892 else ERR("Failed to open log file '%s'\n", str);
896 char buf[1024] = "";
897 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
898 for(i = 1;BackendList[i].name;i++)
899 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
900 TRACE("Supported backends: %s\n", buf);
902 ReadALConfig();
904 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
905 if(str && *str)
907 if(strcasecmp(str, "ignore") == 0)
909 SuspendDefers = ALC_FALSE;
910 TRACE("Selected context suspend behavior, \"ignore\"\n");
912 else
913 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
916 capfilter = 0;
917 #if defined(HAVE_SSE4_1)
918 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
919 #elif defined(HAVE_SSE3)
920 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
921 #elif defined(HAVE_SSE2)
922 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
923 #elif defined(HAVE_SSE)
924 capfilter |= CPU_CAP_SSE;
925 #endif
926 #ifdef HAVE_NEON
927 capfilter |= CPU_CAP_NEON;
928 #endif
929 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
931 if(strcasecmp(str, "all") == 0)
932 capfilter = 0;
933 else
935 size_t len;
936 const char *next = str;
938 do {
939 str = next;
940 while(isspace(str[0]))
941 str++;
942 next = strchr(str, ',');
944 if(!str[0] || str[0] == ',')
945 continue;
947 len = (next ? ((size_t)(next-str)) : strlen(str));
948 while(len > 0 && isspace(str[len-1]))
949 len--;
950 if(len == 3 && strncasecmp(str, "sse", len) == 0)
951 capfilter &= ~CPU_CAP_SSE;
952 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
953 capfilter &= ~CPU_CAP_SSE2;
954 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
955 capfilter &= ~CPU_CAP_SSE3;
956 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
957 capfilter &= ~CPU_CAP_SSE4_1;
958 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
959 capfilter &= ~CPU_CAP_NEON;
960 else
961 WARN("Invalid CPU extension \"%s\"\n", str);
962 } while(next++);
965 FillCPUCaps(capfilter);
967 #ifdef _WIN32
968 RTPrioLevel = 1;
969 #else
970 RTPrioLevel = 0;
971 #endif
972 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
974 aluInitMixer();
976 str = getenv("ALSOFT_TRAP_ERROR");
977 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
979 TrapALError = AL_TRUE;
980 TrapALCError = AL_TRUE;
982 else
984 str = getenv("ALSOFT_TRAP_AL_ERROR");
985 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
986 TrapALError = AL_TRUE;
987 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
989 str = getenv("ALSOFT_TRAP_ALC_ERROR");
990 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
991 TrapALCError = ALC_TRUE;
992 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
995 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
996 ReverbBoost *= powf(10.0f, valf / 20.0f);
998 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1000 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1001 ConfigValueStr(NULL, NULL, "drivers", &devs))
1003 int n;
1004 size_t len;
1005 const char *next = devs;
1006 int endlist, delitem;
1008 i = 0;
1009 do {
1010 devs = next;
1011 while(isspace(devs[0]))
1012 devs++;
1013 next = strchr(devs, ',');
1015 delitem = (devs[0] == '-');
1016 if(devs[0] == '-') devs++;
1018 if(!devs[0] || devs[0] == ',')
1020 endlist = 0;
1021 continue;
1023 endlist = 1;
1025 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1026 while(len > 0 && isspace(devs[len-1]))
1027 len--;
1028 for(n = i;BackendList[n].name;n++)
1030 if(len == strlen(BackendList[n].name) &&
1031 strncmp(BackendList[n].name, devs, len) == 0)
1033 if(delitem)
1035 do {
1036 BackendList[n] = BackendList[n+1];
1037 ++n;
1038 } while(BackendList[n].name);
1040 else
1042 struct BackendInfo Bkp = BackendList[n];
1043 while(n > i)
1045 BackendList[n] = BackendList[n-1];
1046 --n;
1048 BackendList[n] = Bkp;
1050 i++;
1052 break;
1055 } while(next++);
1057 if(endlist)
1059 BackendList[i].name = NULL;
1060 BackendList[i].getFactory = NULL;
1061 BackendList[i].Init = NULL;
1062 BackendList[i].Deinit = NULL;
1063 BackendList[i].Probe = NULL;
1067 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1069 if(BackendList[i].getFactory)
1071 ALCbackendFactory *factory = BackendList[i].getFactory();
1072 if(!V0(factory,init)())
1074 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1075 continue;
1078 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1079 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1081 PlaybackBackend = BackendList[i];
1082 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1084 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1086 CaptureBackend = BackendList[i];
1087 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1090 continue;
1093 if(!BackendList[i].Init(&BackendList[i].Funcs))
1095 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1096 continue;
1099 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1100 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1102 PlaybackBackend = BackendList[i];
1103 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1105 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1107 CaptureBackend = BackendList[i];
1108 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1112 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1113 V0(factory,init)();
1116 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1118 size_t len;
1119 const char *next = str;
1121 do {
1122 str = next;
1123 next = strchr(str, ',');
1125 if(!str[0] || next == str)
1126 continue;
1128 len = (next ? ((size_t)(next-str)) : strlen(str));
1129 for(n = 0;EffectList[n].name;n++)
1131 if(len == strlen(EffectList[n].name) &&
1132 strncmp(EffectList[n].name, str, len) == 0)
1133 DisabledEffects[EffectList[n].type] = AL_TRUE;
1135 } while(next++);
1138 InitEffectFactoryMap();
1140 InitEffect(&DefaultEffect);
1141 str = getenv("ALSOFT_DEFAULT_REVERB");
1142 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1143 LoadReverbPreset(str, &DefaultEffect);
1145 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1148 /************************************************
1149 * Library deinitialization
1150 ************************************************/
1151 static void alc_cleanup(void)
1153 ALCdevice *dev;
1155 AL_STRING_DEINIT(alcAllDevicesList);
1156 AL_STRING_DEINIT(alcCaptureDeviceList);
1158 free(alcDefaultAllDevicesSpecifier);
1159 alcDefaultAllDevicesSpecifier = NULL;
1160 free(alcCaptureDefaultDeviceSpecifier);
1161 alcCaptureDefaultDeviceSpecifier = NULL;
1163 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1165 ALCuint num = 0;
1166 do {
1167 num++;
1168 } while((dev=dev->next) != NULL);
1169 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1172 DeinitEffectFactoryMap();
1175 static void alc_deinit_safe(void)
1177 alc_cleanup();
1179 FreeHrtfs();
1180 FreeALConfig();
1182 ThunkExit();
1183 almtx_destroy(&ListLock);
1184 altss_delete(LocalContext);
1186 if(LogFile != stderr)
1187 fclose(LogFile);
1188 LogFile = NULL;
1191 static void alc_deinit(void)
1193 int i;
1195 alc_cleanup();
1197 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1198 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1200 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1202 if(!BackendList[i].getFactory)
1203 BackendList[i].Deinit();
1204 else
1206 ALCbackendFactory *factory = BackendList[i].getFactory();
1207 V0(factory,deinit)();
1211 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1212 V0(factory,deinit)();
1215 alc_deinit_safe();
1219 /************************************************
1220 * Device enumeration
1221 ************************************************/
1222 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1224 DO_INITCONFIG();
1226 LockLists();
1227 al_string_clear(list);
1229 if(!backendinfo->getFactory)
1230 backendinfo->Probe(type);
1231 else
1233 ALCbackendFactory *factory = backendinfo->getFactory();
1234 V(factory,probe)(type);
1237 UnlockLists();
1239 static void ProbeAllDevicesList(void)
1240 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1241 static void ProbeCaptureDeviceList(void)
1242 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1244 static void AppendDevice(const ALCchar *name, al_string *devnames)
1246 size_t len = strlen(name);
1247 if(len > 0)
1248 al_string_append_range(devnames, name, name+len+1);
1250 void AppendAllDevicesList(const ALCchar *name)
1251 { AppendDevice(name, &alcAllDevicesList); }
1252 void AppendCaptureDeviceList(const ALCchar *name)
1253 { AppendDevice(name, &alcCaptureDeviceList); }
1256 /************************************************
1257 * Device format information
1258 ************************************************/
1259 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1261 switch(type)
1263 case DevFmtByte: return "Signed Byte";
1264 case DevFmtUByte: return "Unsigned Byte";
1265 case DevFmtShort: return "Signed Short";
1266 case DevFmtUShort: return "Unsigned Short";
1267 case DevFmtInt: return "Signed Int";
1268 case DevFmtUInt: return "Unsigned Int";
1269 case DevFmtFloat: return "Float";
1271 return "(unknown type)";
1273 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1275 switch(chans)
1277 case DevFmtMono: return "Mono";
1278 case DevFmtStereo: return "Stereo";
1279 case DevFmtQuad: return "Quadraphonic";
1280 case DevFmtX51: return "5.1 Surround";
1281 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1282 case DevFmtX61: return "6.1 Surround";
1283 case DevFmtX71: return "7.1 Surround";
1284 case DevFmtBFormat3D: return "B-Format 3D";
1286 return "(unknown channels)";
1289 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1290 ALuint BytesFromDevFmt(enum DevFmtType type)
1292 switch(type)
1294 case DevFmtByte: return sizeof(ALbyte);
1295 case DevFmtUByte: return sizeof(ALubyte);
1296 case DevFmtShort: return sizeof(ALshort);
1297 case DevFmtUShort: return sizeof(ALushort);
1298 case DevFmtInt: return sizeof(ALint);
1299 case DevFmtUInt: return sizeof(ALuint);
1300 case DevFmtFloat: return sizeof(ALfloat);
1302 return 0;
1304 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1306 switch(chans)
1308 case DevFmtMono: return 1;
1309 case DevFmtStereo: return 2;
1310 case DevFmtQuad: return 4;
1311 case DevFmtX51: return 6;
1312 case DevFmtX51Rear: return 6;
1313 case DevFmtX61: return 7;
1314 case DevFmtX71: return 8;
1315 case DevFmtBFormat3D: return 4;
1317 return 0;
1320 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1321 enum DevFmtChannels *chans, enum DevFmtType *type)
1323 static const struct {
1324 ALenum format;
1325 enum DevFmtChannels channels;
1326 enum DevFmtType type;
1327 } list[] = {
1328 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1329 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1330 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1332 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1333 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1334 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1336 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1337 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1338 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1340 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1341 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1342 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1344 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1345 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1346 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1348 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1349 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1350 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1352 ALuint i;
1354 for(i = 0;i < COUNTOF(list);i++)
1356 if(list[i].format == format)
1358 *chans = list[i].channels;
1359 *type = list[i].type;
1360 return AL_TRUE;
1364 return AL_FALSE;
1367 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1369 switch(type)
1371 case ALC_BYTE_SOFT:
1372 case ALC_UNSIGNED_BYTE_SOFT:
1373 case ALC_SHORT_SOFT:
1374 case ALC_UNSIGNED_SHORT_SOFT:
1375 case ALC_INT_SOFT:
1376 case ALC_UNSIGNED_INT_SOFT:
1377 case ALC_FLOAT_SOFT:
1378 return ALC_TRUE;
1380 return ALC_FALSE;
1383 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1385 switch(channels)
1387 case ALC_MONO_SOFT:
1388 case ALC_STEREO_SOFT:
1389 case ALC_QUAD_SOFT:
1390 case ALC_5POINT1_SOFT:
1391 case ALC_6POINT1_SOFT:
1392 case ALC_7POINT1_SOFT:
1393 return ALC_TRUE;
1395 return ALC_FALSE;
1399 /************************************************
1400 * Miscellaneous ALC helpers
1401 ************************************************/
1403 extern inline void LockContext(ALCcontext *context);
1404 extern inline void UnlockContext(ALCcontext *context);
1406 void ALCdevice_Lock(ALCdevice *device)
1408 V0(device->Backend,lock)();
1411 void ALCdevice_Unlock(ALCdevice *device)
1413 V0(device->Backend,unlock)();
1417 /* SetDefaultWFXChannelOrder
1419 * Sets the default channel order used by WaveFormatEx.
1421 void SetDefaultWFXChannelOrder(ALCdevice *device)
1423 ALuint i;
1425 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1426 device->RealOut.ChannelName[i] = InvalidChannel;
1428 switch(device->FmtChans)
1430 case DevFmtMono:
1431 device->RealOut.ChannelName[0] = FrontCenter;
1432 break;
1433 case DevFmtStereo:
1434 device->RealOut.ChannelName[0] = FrontLeft;
1435 device->RealOut.ChannelName[1] = FrontRight;
1436 break;
1437 case DevFmtQuad:
1438 device->RealOut.ChannelName[0] = FrontLeft;
1439 device->RealOut.ChannelName[1] = FrontRight;
1440 device->RealOut.ChannelName[2] = BackLeft;
1441 device->RealOut.ChannelName[3] = BackRight;
1442 break;
1443 case DevFmtX51:
1444 device->RealOut.ChannelName[0] = FrontLeft;
1445 device->RealOut.ChannelName[1] = FrontRight;
1446 device->RealOut.ChannelName[2] = FrontCenter;
1447 device->RealOut.ChannelName[3] = LFE;
1448 device->RealOut.ChannelName[4] = SideLeft;
1449 device->RealOut.ChannelName[5] = SideRight;
1450 break;
1451 case DevFmtX51Rear:
1452 device->RealOut.ChannelName[0] = FrontLeft;
1453 device->RealOut.ChannelName[1] = FrontRight;
1454 device->RealOut.ChannelName[2] = FrontCenter;
1455 device->RealOut.ChannelName[3] = LFE;
1456 device->RealOut.ChannelName[4] = BackLeft;
1457 device->RealOut.ChannelName[5] = BackRight;
1458 break;
1459 case DevFmtX61:
1460 device->RealOut.ChannelName[0] = FrontLeft;
1461 device->RealOut.ChannelName[1] = FrontRight;
1462 device->RealOut.ChannelName[2] = FrontCenter;
1463 device->RealOut.ChannelName[3] = LFE;
1464 device->RealOut.ChannelName[4] = BackCenter;
1465 device->RealOut.ChannelName[5] = SideLeft;
1466 device->RealOut.ChannelName[6] = SideRight;
1467 break;
1468 case DevFmtX71:
1469 device->RealOut.ChannelName[0] = FrontLeft;
1470 device->RealOut.ChannelName[1] = FrontRight;
1471 device->RealOut.ChannelName[2] = FrontCenter;
1472 device->RealOut.ChannelName[3] = LFE;
1473 device->RealOut.ChannelName[4] = BackLeft;
1474 device->RealOut.ChannelName[5] = BackRight;
1475 device->RealOut.ChannelName[6] = SideLeft;
1476 device->RealOut.ChannelName[7] = SideRight;
1477 break;
1478 case DevFmtBFormat3D:
1479 device->RealOut.ChannelName[0] = Aux0;
1480 device->RealOut.ChannelName[1] = Aux1;
1481 device->RealOut.ChannelName[2] = Aux2;
1482 device->RealOut.ChannelName[3] = Aux3;
1483 break;
1487 /* SetDefaultChannelOrder
1489 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1491 void SetDefaultChannelOrder(ALCdevice *device)
1493 ALuint i;
1495 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1496 device->RealOut.ChannelName[i] = InvalidChannel;
1498 switch(device->FmtChans)
1500 case DevFmtX51Rear:
1501 device->RealOut.ChannelName[0] = FrontLeft;
1502 device->RealOut.ChannelName[1] = FrontRight;
1503 device->RealOut.ChannelName[2] = BackLeft;
1504 device->RealOut.ChannelName[3] = BackRight;
1505 device->RealOut.ChannelName[4] = FrontCenter;
1506 device->RealOut.ChannelName[5] = LFE;
1507 return;
1508 case DevFmtX71:
1509 device->RealOut.ChannelName[0] = FrontLeft;
1510 device->RealOut.ChannelName[1] = FrontRight;
1511 device->RealOut.ChannelName[2] = BackLeft;
1512 device->RealOut.ChannelName[3] = BackRight;
1513 device->RealOut.ChannelName[4] = FrontCenter;
1514 device->RealOut.ChannelName[5] = LFE;
1515 device->RealOut.ChannelName[6] = SideLeft;
1516 device->RealOut.ChannelName[7] = SideRight;
1517 return;
1519 /* Same as WFX order */
1520 case DevFmtMono:
1521 case DevFmtStereo:
1522 case DevFmtQuad:
1523 case DevFmtX51:
1524 case DevFmtX61:
1525 case DevFmtBFormat3D:
1526 SetDefaultWFXChannelOrder(device);
1527 break;
1531 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1534 /* ALCcontext_DeferUpdates
1536 * Defers/suspends updates for the given context's listener and sources. This
1537 * does *NOT* stop mixing, but rather prevents certain property changes from
1538 * taking effect.
1540 void ALCcontext_DeferUpdates(ALCcontext *context)
1542 ALCdevice *device = context->Device;
1543 FPUCtl oldMode;
1545 SetMixerFPUMode(&oldMode);
1547 V0(device->Backend,lock)();
1548 if(!context->DeferUpdates)
1550 context->DeferUpdates = AL_TRUE;
1552 /* Make sure all pending updates are performed */
1553 UpdateContextSources(context);
1554 #define UPDATE_SLOT(iter) do { \
1555 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1556 V((*iter)->EffectState,update)(device, *iter); \
1557 } while(0)
1558 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1559 #undef UPDATE_SLOT
1561 V0(device->Backend,unlock)();
1563 RestoreFPUMode(&oldMode);
1566 /* ALCcontext_ProcessUpdates
1568 * Resumes update processing after being deferred.
1570 void ALCcontext_ProcessUpdates(ALCcontext *context)
1572 ALCdevice *device = context->Device;
1574 V0(device->Backend,lock)();
1575 if(context->DeferUpdates)
1577 ALsizei pos;
1579 context->DeferUpdates = AL_FALSE;
1581 LockUIntMapRead(&context->SourceMap);
1582 for(pos = 0;pos < context->SourceMap.size;pos++)
1584 ALsource *Source = context->SourceMap.array[pos].value;
1585 ALenum new_state;
1587 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1588 Source->Offset >= 0.0)
1590 WriteLock(&Source->queue_lock);
1591 ApplyOffset(Source);
1592 WriteUnlock(&Source->queue_lock);
1595 new_state = Source->new_state;
1596 Source->new_state = AL_NONE;
1597 if(new_state)
1598 SetSourceState(Source, context, new_state);
1600 UnlockUIntMapRead(&context->SourceMap);
1602 V0(device->Backend,unlock)();
1606 /* alcSetError
1608 * Stores the latest ALC device error
1610 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1612 if(TrapALCError)
1614 #ifdef _WIN32
1615 /* DebugBreak() will cause an exception if there is no debugger */
1616 if(IsDebuggerPresent())
1617 DebugBreak();
1618 #elif defined(SIGTRAP)
1619 raise(SIGTRAP);
1620 #endif
1623 if(device)
1624 ATOMIC_STORE(&device->LastError, errorCode);
1625 else
1626 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1630 /* UpdateClockBase
1632 * Updates the device's base clock time with however many samples have been
1633 * done. This is used so frequency changes on the device don't cause the time
1634 * to jump forward or back.
1636 static inline void UpdateClockBase(ALCdevice *device)
1638 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1639 device->SamplesDone = 0;
1642 /* UpdateDeviceParams
1644 * Updates device parameters according to the attribute list (caller is
1645 * responsible for holding the list lock).
1647 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1649 ALCcontext *context;
1650 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1651 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1652 enum DevFmtChannels oldChans;
1653 enum DevFmtType oldType;
1654 ALCuint oldFreq;
1655 FPUCtl oldMode;
1656 ALCsizei hrtf_id = -1;
1657 size_t size;
1659 // Check for attributes
1660 if(device->Type == Loopback)
1662 enum {
1663 GotFreq = 1<<0,
1664 GotChans = 1<<1,
1665 GotType = 1<<2,
1666 GotAll = GotFreq|GotChans|GotType
1668 ALCuint freq, numMono, numStereo, numSends;
1669 enum DevFmtChannels schans;
1670 enum DevFmtType stype;
1671 ALCuint attrIdx = 0;
1672 ALCint gotFmt = 0;
1674 if(!attrList)
1676 WARN("Missing attributes for loopback device\n");
1677 return ALC_INVALID_VALUE;
1680 numMono = device->NumMonoSources;
1681 numStereo = device->NumStereoSources;
1682 numSends = device->NumAuxSends;
1683 schans = device->FmtChans;
1684 stype = device->FmtType;
1685 freq = device->Frequency;
1687 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1688 while(attrList[attrIdx])
1690 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1692 ALCint val = attrList[attrIdx + 1];
1693 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, val);
1694 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1695 return ALC_INVALID_VALUE;
1696 schans = val;
1697 gotFmt |= GotChans;
1700 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1702 ALCint val = attrList[attrIdx + 1];
1703 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, val);
1704 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1705 return ALC_INVALID_VALUE;
1706 stype = val;
1707 gotFmt |= GotType;
1710 if(attrList[attrIdx] == ALC_FREQUENCY)
1712 freq = attrList[attrIdx + 1];
1713 TRACE_ATTR(ALC_FREQUENCY, freq);
1714 if(freq < MIN_OUTPUT_RATE)
1715 return ALC_INVALID_VALUE;
1716 gotFmt |= GotFreq;
1719 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1721 numStereo = attrList[attrIdx + 1];
1722 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1723 if(numStereo > device->MaxNoOfSources)
1724 numStereo = device->MaxNoOfSources;
1726 numMono = device->MaxNoOfSources - numStereo;
1729 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1731 numSends = attrList[attrIdx + 1];
1732 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1735 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1737 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1738 if(attrList[attrIdx + 1] == ALC_FALSE)
1739 hrtf_appreq = Hrtf_Disable;
1740 else if(attrList[attrIdx + 1] == ALC_TRUE)
1741 hrtf_appreq = Hrtf_Enable;
1742 else
1743 hrtf_appreq = Hrtf_Default;
1746 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1748 hrtf_id = attrList[attrIdx + 1];
1749 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1752 attrIdx += 2;
1754 #undef TRACE_ATTR
1756 if(gotFmt != GotAll)
1758 WARN("Missing format for loopback device\n");
1759 return ALC_INVALID_VALUE;
1762 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1763 numSends = minu(MAX_SENDS, numSends);
1765 if((device->Flags&DEVICE_RUNNING))
1766 V0(device->Backend,stop)();
1767 device->Flags &= ~DEVICE_RUNNING;
1769 UpdateClockBase(device);
1771 device->Frequency = freq;
1772 device->FmtChans = schans;
1773 device->FmtType = stype;
1774 device->NumMonoSources = numMono;
1775 device->NumStereoSources = numStereo;
1776 device->NumAuxSends = numSends;
1778 else if(attrList && attrList[0])
1780 ALCuint freq, numMono, numStereo, numSends;
1781 ALCuint attrIdx = 0;
1783 /* If a context is already running on the device, stop playback so the
1784 * device attributes can be updated. */
1785 if((device->Flags&DEVICE_RUNNING))
1786 V0(device->Backend,stop)();
1787 device->Flags &= ~DEVICE_RUNNING;
1789 freq = device->Frequency;
1790 numMono = device->NumMonoSources;
1791 numStereo = device->NumStereoSources;
1792 numSends = device->NumAuxSends;
1794 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1795 while(attrList[attrIdx])
1797 if(attrList[attrIdx] == ALC_FREQUENCY)
1799 freq = attrList[attrIdx + 1];
1800 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1801 TRACE_ATTR(ALC_FREQUENCY, freq);
1804 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1806 numStereo = attrList[attrIdx + 1];
1807 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1808 if(numStereo > device->MaxNoOfSources)
1809 numStereo = device->MaxNoOfSources;
1811 numMono = device->MaxNoOfSources - numStereo;
1814 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1816 numSends = attrList[attrIdx + 1];
1817 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1820 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1822 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1823 if(attrList[attrIdx + 1] == ALC_FALSE)
1824 hrtf_appreq = Hrtf_Disable;
1825 else if(attrList[attrIdx + 1] == ALC_TRUE)
1826 hrtf_appreq = Hrtf_Enable;
1827 else
1828 hrtf_appreq = Hrtf_Default;
1831 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1833 hrtf_id = attrList[attrIdx + 1];
1834 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1837 attrIdx += 2;
1839 #undef TRACE_ATTR
1841 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1842 freq = maxu(freq, MIN_OUTPUT_RATE);
1844 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1845 numSends = minu(MAX_SENDS, numSends);
1847 UpdateClockBase(device);
1849 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1850 device->Frequency;
1851 /* SSE and Neon do best with the update size being a multiple of 4 */
1852 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1853 device->UpdateSize = (device->UpdateSize+3)&~3;
1855 device->Frequency = freq;
1856 device->NumMonoSources = numMono;
1857 device->NumStereoSources = numStereo;
1858 device->NumAuxSends = numSends;
1861 if((device->Flags&DEVICE_RUNNING))
1862 return ALC_NO_ERROR;
1864 al_free(device->Uhj_Encoder);
1865 device->Uhj_Encoder = NULL;
1867 al_free(device->Bs2b);
1868 device->Bs2b = NULL;
1870 al_free(device->Dry.Buffer);
1871 device->Dry.Buffer = NULL;
1872 device->Dry.NumChannels = 0;
1873 device->VirtOut.Buffer = NULL;
1874 device->VirtOut.NumChannels = 0;
1875 device->RealOut.Buffer = NULL;
1876 device->RealOut.NumChannels = 0;
1878 UpdateClockBase(device);
1880 /*************************************************************************
1881 * Update device format request if HRTF is requested
1883 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1884 if(device->Type != Loopback)
1886 const char *hrtf;
1887 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1889 if(strcasecmp(hrtf, "true") == 0)
1890 hrtf_userreq = Hrtf_Enable;
1891 else if(strcasecmp(hrtf, "false") == 0)
1892 hrtf_userreq = Hrtf_Disable;
1893 else if(strcasecmp(hrtf, "auto") != 0)
1894 ERR("Unexpected hrtf value: %s\n", hrtf);
1897 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1899 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1901 VECTOR_DEINIT(device->Hrtf_List);
1902 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1904 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1906 device->FmtChans = DevFmtStereo;
1907 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1908 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1909 else
1910 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1911 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1913 else
1915 hrtf_userreq = Hrtf_Default;
1916 hrtf_appreq = Hrtf_Disable;
1917 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1921 else if(hrtf_appreq == Hrtf_Enable)
1923 size_t i = VECTOR_SIZE(device->Hrtf_List);
1924 /* Loopback device. We don't need to match to a specific HRTF entry
1925 * here. If the requested ID matches, we'll pick that later, if not,
1926 * we'll try to auto-select one anyway. Just make sure one exists
1927 * that'll work.
1929 if(device->FmtChans == DevFmtStereo)
1931 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1933 VECTOR_DEINIT(device->Hrtf_List);
1934 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1936 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1938 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1939 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1940 break;
1943 if(i == VECTOR_SIZE(device->Hrtf_List))
1945 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1946 DevFmtChannelsString(device->FmtChans), device->Frequency);
1947 hrtf_appreq = Hrtf_Disable;
1948 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1952 oldFreq = device->Frequency;
1953 oldChans = device->FmtChans;
1954 oldType = device->FmtType;
1956 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1957 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1958 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1959 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1960 device->UpdateSize, device->NumUpdates
1963 if(V0(device->Backend,reset)() == ALC_FALSE)
1964 return ALC_INVALID_DEVICE;
1966 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1968 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1969 DevFmtChannelsString(device->FmtChans));
1970 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1972 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1974 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1975 DevFmtTypeString(device->FmtType));
1976 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1978 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1980 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1981 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1984 if((device->UpdateSize&3) != 0)
1986 if((CPUCapFlags&CPU_CAP_SSE))
1987 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1988 if((CPUCapFlags&CPU_CAP_NEON))
1989 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1992 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1993 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1994 device->Frequency, device->UpdateSize, device->NumUpdates
1997 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
1999 /* Allocate extra channels for any post-filter output. */
2000 size = device->Dry.NumChannels * sizeof(device->Dry.Buffer[0]);
2001 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2002 size += (ChannelsFromDevFmt(device->FmtChans)+4) * sizeof(device->Dry.Buffer[0]);
2003 else if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2004 size += ChannelsFromDevFmt(device->FmtChans) * sizeof(device->Dry.Buffer[0]);
2005 device->Dry.Buffer = al_calloc(16, size);
2006 if(!device->Dry.Buffer)
2008 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2009 return ALC_INVALID_DEVICE;
2012 if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2014 device->VirtOut.Buffer = device->Dry.Buffer;
2015 device->VirtOut.NumChannels = device->Dry.NumChannels;
2016 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2017 device->RealOut.NumChannels = ChannelsFromDevFmt(device->FmtChans);
2019 else
2021 device->VirtOut.Buffer = NULL;
2022 device->VirtOut.NumChannels = 0;
2023 device->RealOut.Buffer = device->Dry.Buffer;
2024 device->RealOut.NumChannels = device->Dry.NumChannels;
2027 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2029 /* Higher-order high quality decoding requires upsampling first-order
2030 * content, so make sure to mix it separately.
2032 device->FOAOut.Buffer = device->RealOut.Buffer + device->RealOut.NumChannels;
2033 device->FOAOut.NumChannels = 4;
2035 else
2037 device->FOAOut.Buffer = device->Dry.Buffer;
2038 device->FOAOut.NumChannels = device->Dry.NumChannels;
2041 SetMixerFPUMode(&oldMode);
2042 V0(device->Backend,lock)();
2043 context = ATOMIC_LOAD(&device->ContextList);
2044 while(context)
2046 ALsizei pos;
2048 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2049 LockUIntMapRead(&context->EffectSlotMap);
2050 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2052 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2054 slot->EffectState->OutBuffer = device->Dry.Buffer;
2055 slot->EffectState->OutChannels = device->Dry.NumChannels;
2056 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2058 UnlockUIntMapRead(&context->EffectSlotMap);
2059 V0(device->Backend,unlock)();
2060 RestoreFPUMode(&oldMode);
2061 return ALC_INVALID_DEVICE;
2063 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2064 V(slot->EffectState,update)(device, slot);
2066 UnlockUIntMapRead(&context->EffectSlotMap);
2068 LockUIntMapRead(&context->SourceMap);
2069 for(pos = 0;pos < context->SourceMap.size;pos++)
2071 ALsource *source = context->SourceMap.array[pos].value;
2072 ALuint s = device->NumAuxSends;
2073 while(s < MAX_SENDS)
2075 if(source->Send[s].Slot)
2076 DecrementRef(&source->Send[s].Slot->ref);
2077 source->Send[s].Slot = NULL;
2078 source->Send[s].Gain = 1.0f;
2079 source->Send[s].GainHF = 1.0f;
2080 s++;
2082 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2084 UnlockUIntMapRead(&context->SourceMap);
2086 for(pos = 0;pos < context->VoiceCount;pos++)
2088 ALvoice *voice = &context->Voices[pos];
2089 ALsource *source = voice->Source;
2091 if(source)
2093 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2094 voice->Update(voice, source, context);
2098 context = context->next;
2100 if(device->DefaultSlot)
2102 ALeffectslot *slot = device->DefaultSlot;
2103 ALeffectState *state = slot->EffectState;
2105 state->OutBuffer = device->Dry.Buffer;
2106 state->OutChannels = device->Dry.NumChannels;
2107 if(V(state,deviceUpdate)(device) == AL_FALSE)
2109 V0(device->Backend,unlock)();
2110 RestoreFPUMode(&oldMode);
2111 return ALC_INVALID_DEVICE;
2113 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2114 V(slot->EffectState,update)(device, slot);
2116 V0(device->Backend,unlock)();
2117 RestoreFPUMode(&oldMode);
2119 if(!(device->Flags&DEVICE_PAUSED))
2121 if(V0(device->Backend,start)() == ALC_FALSE)
2122 return ALC_INVALID_DEVICE;
2123 device->Flags |= DEVICE_RUNNING;
2126 return ALC_NO_ERROR;
2129 /* FreeDevice
2131 * Frees the device structure, and destroys any objects the app failed to
2132 * delete. Called once there's no more references on the device.
2134 static ALCvoid FreeDevice(ALCdevice *device)
2136 TRACE("%p\n", device);
2138 V0(device->Backend,close)();
2139 DELETE_OBJ(device->Backend);
2140 device->Backend = NULL;
2142 if(device->DefaultSlot)
2144 ALeffectState *state = device->DefaultSlot->EffectState;
2145 device->DefaultSlot = NULL;
2146 DELETE_OBJ(state);
2149 if(device->BufferMap.size > 0)
2151 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2152 ReleaseALBuffers(device);
2154 ResetUIntMap(&device->BufferMap);
2156 if(device->EffectMap.size > 0)
2158 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2159 ReleaseALEffects(device);
2161 ResetUIntMap(&device->EffectMap);
2163 if(device->FilterMap.size > 0)
2165 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2166 ReleaseALFilters(device);
2168 ResetUIntMap(&device->FilterMap);
2170 AL_STRING_DEINIT(device->Hrtf_Name);
2171 FreeHrtfList(&device->Hrtf_List);
2173 al_free(device->Bs2b);
2174 device->Bs2b = NULL;
2176 al_free(device->Uhj_Encoder);
2177 device->Uhj_Encoder = NULL;
2179 bformatdec_free(device->AmbiDecoder);
2180 device->AmbiDecoder = NULL;
2182 AL_STRING_DEINIT(device->DeviceName);
2184 al_free(device->Dry.Buffer);
2185 device->Dry.Buffer = NULL;
2186 device->Dry.NumChannels = 0;
2187 device->VirtOut.Buffer = NULL;
2188 device->VirtOut.NumChannels = 0;
2189 device->RealOut.Buffer = NULL;
2190 device->RealOut.NumChannels = 0;
2192 al_free(device);
2196 void ALCdevice_IncRef(ALCdevice *device)
2198 uint ref;
2199 ref = IncrementRef(&device->ref);
2200 TRACEREF("%p increasing refcount to %u\n", device, ref);
2203 void ALCdevice_DecRef(ALCdevice *device)
2205 uint ref;
2206 ref = DecrementRef(&device->ref);
2207 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2208 if(ref == 0) FreeDevice(device);
2211 /* VerifyDevice
2213 * Checks if the device handle is valid, and increments its ref count if so.
2215 static ALCboolean VerifyDevice(ALCdevice **device)
2217 ALCdevice *tmpDevice;
2219 LockLists();
2220 tmpDevice = ATOMIC_LOAD(&DeviceList);
2221 while(tmpDevice)
2223 if(tmpDevice == *device)
2225 ALCdevice_IncRef(tmpDevice);
2226 UnlockLists();
2227 return ALC_TRUE;
2229 tmpDevice = tmpDevice->next;
2231 UnlockLists();
2233 *device = NULL;
2234 return ALC_FALSE;
2238 /* InitContext
2240 * Initializes context fields
2242 static ALvoid InitContext(ALCcontext *Context)
2244 ALlistener *listener = Context->Listener;
2245 //Initialise listener
2246 listener->Gain = 1.0f;
2247 listener->MetersPerUnit = 1.0f;
2248 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2249 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2250 listener->Forward[0] = 0.0f;
2251 listener->Forward[1] = 0.0f;
2252 listener->Forward[2] = -1.0f;
2253 listener->Up[0] = 0.0f;
2254 listener->Up[1] = 1.0f;
2255 listener->Up[2] = 0.0f;
2256 aluMatrixdSet(&listener->Params.Matrix,
2257 1.0, 0.0, 0.0, 0.0,
2258 0.0, 1.0, 0.0, 0.0,
2259 0.0, 0.0, 1.0, 0.0,
2260 0.0, 0.0, 0.0, 1.0
2262 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2264 //Validate Context
2265 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2266 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2267 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2268 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2270 //Set globals
2271 Context->DistanceModel = DefaultDistanceModel;
2272 Context->SourceDistanceModel = AL_FALSE;
2273 Context->DopplerFactor = 1.0f;
2274 Context->DopplerVelocity = 1.0f;
2275 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2276 Context->DeferUpdates = AL_FALSE;
2278 Context->ExtensionList = alExtList;
2282 /* FreeContext
2284 * Cleans up the context, and destroys any remaining objects the app failed to
2285 * delete. Called once there's no more references on the context.
2287 static void FreeContext(ALCcontext *context)
2289 TRACE("%p\n", context);
2291 if(context->SourceMap.size > 0)
2293 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2294 ReleaseALSources(context);
2296 ResetUIntMap(&context->SourceMap);
2298 if(context->EffectSlotMap.size > 0)
2300 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2301 ReleaseALAuxiliaryEffectSlots(context);
2303 ResetUIntMap(&context->EffectSlotMap);
2305 al_free(context->Voices);
2306 context->Voices = NULL;
2307 context->VoiceCount = 0;
2308 context->MaxVoices = 0;
2310 VECTOR_DEINIT(context->ActiveAuxSlots);
2312 ALCdevice_DecRef(context->Device);
2313 context->Device = NULL;
2315 //Invalidate context
2316 memset(context, 0, sizeof(ALCcontext));
2317 al_free(context);
2320 /* ReleaseContext
2322 * Removes the context reference from the given device and removes it from
2323 * being current on the running thread or globally.
2325 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2327 ALCcontext *nextctx;
2328 ALCcontext *origctx;
2330 if(altss_get(LocalContext) == context)
2332 WARN("%p released while current on thread\n", context);
2333 altss_set(LocalContext, NULL);
2334 ALCcontext_DecRef(context);
2337 origctx = context;
2338 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2339 ALCcontext_DecRef(context);
2341 ALCdevice_Lock(device);
2342 origctx = context;
2343 nextctx = context->next;
2344 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2346 ALCcontext *list;
2347 do {
2348 list = origctx;
2349 origctx = context;
2350 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2352 ALCdevice_Unlock(device);
2354 ALCcontext_DecRef(context);
2357 void ALCcontext_IncRef(ALCcontext *context)
2359 uint ref;
2360 ref = IncrementRef(&context->ref);
2361 TRACEREF("%p increasing refcount to %u\n", context, ref);
2364 void ALCcontext_DecRef(ALCcontext *context)
2366 uint ref;
2367 ref = DecrementRef(&context->ref);
2368 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2369 if(ref == 0) FreeContext(context);
2372 static void ReleaseThreadCtx(void *ptr)
2374 WARN("%p current for thread being destroyed\n", ptr);
2375 ALCcontext_DecRef(ptr);
2378 /* VerifyContext
2380 * Checks that the given context is valid, and increments its reference count.
2382 static ALCboolean VerifyContext(ALCcontext **context)
2384 ALCdevice *dev;
2386 LockLists();
2387 dev = ATOMIC_LOAD(&DeviceList);
2388 while(dev)
2390 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2391 while(ctx)
2393 if(ctx == *context)
2395 ALCcontext_IncRef(ctx);
2396 UnlockLists();
2397 return ALC_TRUE;
2399 ctx = ctx->next;
2401 dev = dev->next;
2403 UnlockLists();
2405 *context = NULL;
2406 return ALC_FALSE;
2410 /* GetContextRef
2412 * Returns the currently active context for this thread, and adds a reference
2413 * without locking it.
2415 ALCcontext *GetContextRef(void)
2417 ALCcontext *context;
2419 context = altss_get(LocalContext);
2420 if(context)
2421 ALCcontext_IncRef(context);
2422 else
2424 LockLists();
2425 context = ATOMIC_LOAD(&GlobalContext);
2426 if(context)
2427 ALCcontext_IncRef(context);
2428 UnlockLists();
2431 return context;
2435 /************************************************
2436 * Standard ALC functions
2437 ************************************************/
2439 /* alcGetError
2441 * Return last ALC generated error code for the given device
2443 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2445 ALCenum errorCode;
2447 if(VerifyDevice(&device))
2449 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2450 ALCdevice_DecRef(device);
2452 else
2453 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2455 return errorCode;
2459 /* alcSuspendContext
2461 * Suspends updates for the given context
2463 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2465 if(!SuspendDefers)
2466 return;
2468 if(!VerifyContext(&context))
2469 alcSetError(NULL, ALC_INVALID_CONTEXT);
2470 else
2472 ALCcontext_DeferUpdates(context);
2473 ALCcontext_DecRef(context);
2477 /* alcProcessContext
2479 * Resumes processing updates for the given context
2481 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2483 if(!SuspendDefers)
2484 return;
2486 if(!VerifyContext(&context))
2487 alcSetError(NULL, ALC_INVALID_CONTEXT);
2488 else
2490 ALCcontext_ProcessUpdates(context);
2491 ALCcontext_DecRef(context);
2496 /* alcGetString
2498 * Returns information about the device, and error strings
2500 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2502 const ALCchar *value = NULL;
2504 switch(param)
2506 case ALC_NO_ERROR:
2507 value = alcNoError;
2508 break;
2510 case ALC_INVALID_ENUM:
2511 value = alcErrInvalidEnum;
2512 break;
2514 case ALC_INVALID_VALUE:
2515 value = alcErrInvalidValue;
2516 break;
2518 case ALC_INVALID_DEVICE:
2519 value = alcErrInvalidDevice;
2520 break;
2522 case ALC_INVALID_CONTEXT:
2523 value = alcErrInvalidContext;
2524 break;
2526 case ALC_OUT_OF_MEMORY:
2527 value = alcErrOutOfMemory;
2528 break;
2530 case ALC_DEVICE_SPECIFIER:
2531 value = alcDefaultName;
2532 break;
2534 case ALC_ALL_DEVICES_SPECIFIER:
2535 if(VerifyDevice(&Device))
2537 value = al_string_get_cstr(Device->DeviceName);
2538 ALCdevice_DecRef(Device);
2540 else
2542 ProbeAllDevicesList();
2543 value = al_string_get_cstr(alcAllDevicesList);
2545 break;
2547 case ALC_CAPTURE_DEVICE_SPECIFIER:
2548 if(VerifyDevice(&Device))
2550 value = al_string_get_cstr(Device->DeviceName);
2551 ALCdevice_DecRef(Device);
2553 else
2555 ProbeCaptureDeviceList();
2556 value = al_string_get_cstr(alcCaptureDeviceList);
2558 break;
2560 /* Default devices are always first in the list */
2561 case ALC_DEFAULT_DEVICE_SPECIFIER:
2562 value = alcDefaultName;
2563 break;
2565 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2566 if(al_string_empty(alcAllDevicesList))
2567 ProbeAllDevicesList();
2569 VerifyDevice(&Device);
2571 free(alcDefaultAllDevicesSpecifier);
2572 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2573 if(!alcDefaultAllDevicesSpecifier)
2574 alcSetError(Device, ALC_OUT_OF_MEMORY);
2576 value = alcDefaultAllDevicesSpecifier;
2577 if(Device) ALCdevice_DecRef(Device);
2578 break;
2580 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2581 if(al_string_empty(alcCaptureDeviceList))
2582 ProbeCaptureDeviceList();
2584 VerifyDevice(&Device);
2586 free(alcCaptureDefaultDeviceSpecifier);
2587 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2588 if(!alcCaptureDefaultDeviceSpecifier)
2589 alcSetError(Device, ALC_OUT_OF_MEMORY);
2591 value = alcCaptureDefaultDeviceSpecifier;
2592 if(Device) ALCdevice_DecRef(Device);
2593 break;
2595 case ALC_EXTENSIONS:
2596 if(!VerifyDevice(&Device))
2597 value = alcNoDeviceExtList;
2598 else
2600 value = alcExtensionList;
2601 ALCdevice_DecRef(Device);
2603 break;
2605 case ALC_HRTF_SPECIFIER_SOFT:
2606 if(!VerifyDevice(&Device))
2607 alcSetError(NULL, ALC_INVALID_DEVICE);
2608 else
2610 LockLists();
2611 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2612 UnlockLists();
2613 ALCdevice_DecRef(Device);
2615 break;
2617 default:
2618 VerifyDevice(&Device);
2619 alcSetError(Device, ALC_INVALID_ENUM);
2620 if(Device) ALCdevice_DecRef(Device);
2621 break;
2624 return value;
2628 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2630 ALCsizei i;
2632 if(size <= 0 || values == NULL)
2634 alcSetError(device, ALC_INVALID_VALUE);
2635 return 0;
2638 if(!device)
2640 switch(param)
2642 case ALC_MAJOR_VERSION:
2643 values[0] = alcMajorVersion;
2644 return 1;
2645 case ALC_MINOR_VERSION:
2646 values[0] = alcMinorVersion;
2647 return 1;
2649 case ALC_ATTRIBUTES_SIZE:
2650 case ALC_ALL_ATTRIBUTES:
2651 case ALC_FREQUENCY:
2652 case ALC_REFRESH:
2653 case ALC_SYNC:
2654 case ALC_MONO_SOURCES:
2655 case ALC_STEREO_SOURCES:
2656 case ALC_CAPTURE_SAMPLES:
2657 case ALC_FORMAT_CHANNELS_SOFT:
2658 case ALC_FORMAT_TYPE_SOFT:
2659 alcSetError(NULL, ALC_INVALID_DEVICE);
2660 return 0;
2662 default:
2663 alcSetError(NULL, ALC_INVALID_ENUM);
2664 return 0;
2666 return 0;
2669 if(device->Type == Capture)
2671 switch(param)
2673 case ALC_CAPTURE_SAMPLES:
2674 V0(device->Backend,lock)();
2675 values[0] = V0(device->Backend,availableSamples)();
2676 V0(device->Backend,unlock)();
2677 return 1;
2679 case ALC_CONNECTED:
2680 values[0] = device->Connected;
2681 return 1;
2683 default:
2684 alcSetError(device, ALC_INVALID_ENUM);
2685 return 0;
2687 return 0;
2690 /* render device */
2691 switch(param)
2693 case ALC_MAJOR_VERSION:
2694 values[0] = alcMajorVersion;
2695 return 1;
2697 case ALC_MINOR_VERSION:
2698 values[0] = alcMinorVersion;
2699 return 1;
2701 case ALC_EFX_MAJOR_VERSION:
2702 values[0] = alcEFXMajorVersion;
2703 return 1;
2705 case ALC_EFX_MINOR_VERSION:
2706 values[0] = alcEFXMinorVersion;
2707 return 1;
2709 case ALC_ATTRIBUTES_SIZE:
2710 values[0] = 17;
2711 return 1;
2713 case ALC_ALL_ATTRIBUTES:
2714 if(size < 17)
2716 alcSetError(device, ALC_INVALID_VALUE);
2717 return 0;
2720 i = 0;
2721 values[i++] = ALC_FREQUENCY;
2722 values[i++] = device->Frequency;
2724 if(device->Type != Loopback)
2726 values[i++] = ALC_REFRESH;
2727 values[i++] = device->Frequency / device->UpdateSize;
2729 values[i++] = ALC_SYNC;
2730 values[i++] = ALC_FALSE;
2732 else
2734 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2735 values[i++] = device->FmtChans;
2737 values[i++] = ALC_FORMAT_TYPE_SOFT;
2738 values[i++] = device->FmtType;
2741 values[i++] = ALC_MONO_SOURCES;
2742 values[i++] = device->NumMonoSources;
2744 values[i++] = ALC_STEREO_SOURCES;
2745 values[i++] = device->NumStereoSources;
2747 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2748 values[i++] = device->NumAuxSends;
2750 values[i++] = ALC_HRTF_SOFT;
2751 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2753 values[i++] = ALC_HRTF_STATUS_SOFT;
2754 values[i++] = device->Hrtf_Status;
2756 values[i++] = 0;
2757 return i;
2759 case ALC_FREQUENCY:
2760 values[0] = device->Frequency;
2761 return 1;
2763 case ALC_REFRESH:
2764 if(device->Type == Loopback)
2766 alcSetError(device, ALC_INVALID_DEVICE);
2767 return 0;
2769 values[0] = device->Frequency / device->UpdateSize;
2770 return 1;
2772 case ALC_SYNC:
2773 if(device->Type == Loopback)
2775 alcSetError(device, ALC_INVALID_DEVICE);
2776 return 0;
2778 values[0] = ALC_FALSE;
2779 return 1;
2781 case ALC_FORMAT_CHANNELS_SOFT:
2782 if(device->Type != Loopback)
2784 alcSetError(device, ALC_INVALID_DEVICE);
2785 return 0;
2787 values[0] = device->FmtChans;
2788 return 1;
2790 case ALC_FORMAT_TYPE_SOFT:
2791 if(device->Type != Loopback)
2793 alcSetError(device, ALC_INVALID_DEVICE);
2794 return 0;
2796 values[0] = device->FmtType;
2797 return 1;
2799 case ALC_MONO_SOURCES:
2800 values[0] = device->NumMonoSources;
2801 return 1;
2803 case ALC_STEREO_SOURCES:
2804 values[0] = device->NumStereoSources;
2805 return 1;
2807 case ALC_MAX_AUXILIARY_SENDS:
2808 values[0] = device->NumAuxSends;
2809 return 1;
2811 case ALC_CONNECTED:
2812 values[0] = device->Connected;
2813 return 1;
2815 case ALC_HRTF_SOFT:
2816 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2817 return 1;
2819 case ALC_HRTF_STATUS_SOFT:
2820 values[0] = device->Hrtf_Status;
2821 return 1;
2823 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2824 FreeHrtfList(&device->Hrtf_List);
2825 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2826 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2827 return 1;
2829 default:
2830 alcSetError(device, ALC_INVALID_ENUM);
2831 return 0;
2833 return 0;
2836 /* alcGetIntegerv
2838 * Returns information about the device and the version of OpenAL
2840 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2842 VerifyDevice(&device);
2843 if(size <= 0 || values == NULL)
2844 alcSetError(device, ALC_INVALID_VALUE);
2845 else
2846 GetIntegerv(device, param, size, values);
2847 if(device) ALCdevice_DecRef(device);
2850 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2852 ALCint *ivals;
2853 ALsizei i;
2855 VerifyDevice(&device);
2856 if(size <= 0 || values == NULL)
2857 alcSetError(device, ALC_INVALID_VALUE);
2858 else if(!device || device->Type == Capture)
2860 ivals = malloc(size * sizeof(ALCint));
2861 size = GetIntegerv(device, pname, size, ivals);
2862 for(i = 0;i < size;i++)
2863 values[i] = ivals[i];
2864 free(ivals);
2866 else /* render device */
2868 switch(pname)
2870 case ALC_ATTRIBUTES_SIZE:
2871 *values = 19;
2872 break;
2874 case ALC_ALL_ATTRIBUTES:
2875 if(size < 19)
2876 alcSetError(device, ALC_INVALID_VALUE);
2877 else
2879 int i = 0;
2881 V0(device->Backend,lock)();
2882 values[i++] = ALC_FREQUENCY;
2883 values[i++] = device->Frequency;
2885 if(device->Type != Loopback)
2887 values[i++] = ALC_REFRESH;
2888 values[i++] = device->Frequency / device->UpdateSize;
2890 values[i++] = ALC_SYNC;
2891 values[i++] = ALC_FALSE;
2893 else
2895 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2896 values[i++] = device->FmtChans;
2898 values[i++] = ALC_FORMAT_TYPE_SOFT;
2899 values[i++] = device->FmtType;
2902 values[i++] = ALC_MONO_SOURCES;
2903 values[i++] = device->NumMonoSources;
2905 values[i++] = ALC_STEREO_SOURCES;
2906 values[i++] = device->NumStereoSources;
2908 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2909 values[i++] = device->NumAuxSends;
2911 values[i++] = ALC_HRTF_SOFT;
2912 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2914 values[i++] = ALC_HRTF_STATUS_SOFT;
2915 values[i++] = device->Hrtf_Status;
2917 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2918 values[i++] = device->ClockBase +
2919 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2921 values[i++] = 0;
2922 V0(device->Backend,unlock)();
2924 break;
2926 case ALC_DEVICE_CLOCK_SOFT:
2927 V0(device->Backend,lock)();
2928 *values = device->ClockBase +
2929 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2930 V0(device->Backend,unlock)();
2931 break;
2933 default:
2934 ivals = malloc(size * sizeof(ALCint));
2935 size = GetIntegerv(device, pname, size, ivals);
2936 for(i = 0;i < size;i++)
2937 values[i] = ivals[i];
2938 free(ivals);
2939 break;
2942 if(device)
2943 ALCdevice_DecRef(device);
2947 /* alcIsExtensionPresent
2949 * Determines if there is support for a particular extension
2951 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2953 ALCboolean bResult = ALC_FALSE;
2955 VerifyDevice(&device);
2957 if(!extName)
2958 alcSetError(device, ALC_INVALID_VALUE);
2959 else
2961 size_t len = strlen(extName);
2962 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2963 while(ptr && *ptr)
2965 if(strncasecmp(ptr, extName, len) == 0 &&
2966 (ptr[len] == '\0' || isspace(ptr[len])))
2968 bResult = ALC_TRUE;
2969 break;
2971 if((ptr=strchr(ptr, ' ')) != NULL)
2973 do {
2974 ++ptr;
2975 } while(isspace(*ptr));
2979 if(device)
2980 ALCdevice_DecRef(device);
2981 return bResult;
2985 /* alcGetProcAddress
2987 * Retrieves the function address for a particular extension function
2989 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2991 ALCvoid *ptr = NULL;
2993 if(!funcName)
2995 VerifyDevice(&device);
2996 alcSetError(device, ALC_INVALID_VALUE);
2997 if(device) ALCdevice_DecRef(device);
2999 else
3001 ALsizei i = 0;
3002 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3003 i++;
3004 ptr = alcFunctions[i].address;
3007 return ptr;
3011 /* alcGetEnumValue
3013 * Get the value for a particular ALC enumeration name
3015 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3017 ALCenum val = 0;
3019 if(!enumName)
3021 VerifyDevice(&device);
3022 alcSetError(device, ALC_INVALID_VALUE);
3023 if(device) ALCdevice_DecRef(device);
3025 else
3027 ALsizei i = 0;
3028 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3029 i++;
3030 val = enumeration[i].value;
3033 return val;
3037 /* alcCreateContext
3039 * Create and attach a context to the given device.
3041 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3043 ALCcontext *ALContext;
3044 ALCenum err;
3046 LockLists();
3047 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3049 UnlockLists();
3050 alcSetError(device, ALC_INVALID_DEVICE);
3051 if(device) ALCdevice_DecRef(device);
3052 return NULL;
3055 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3057 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3059 UnlockLists();
3060 alcSetError(device, err);
3061 if(err == ALC_INVALID_DEVICE)
3063 V0(device->Backend,lock)();
3064 aluHandleDisconnect(device);
3065 V0(device->Backend,unlock)();
3067 ALCdevice_DecRef(device);
3068 return NULL;
3071 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3072 if(ALContext)
3074 InitRef(&ALContext->ref, 1);
3075 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3077 VECTOR_INIT(ALContext->ActiveAuxSlots);
3079 ALContext->VoiceCount = 0;
3080 ALContext->MaxVoices = 256;
3081 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3083 if(!ALContext || !ALContext->Voices)
3085 if(!ATOMIC_LOAD(&device->ContextList))
3087 V0(device->Backend,stop)();
3088 device->Flags &= ~DEVICE_RUNNING;
3090 UnlockLists();
3092 if(ALContext)
3094 al_free(ALContext->Voices);
3095 ALContext->Voices = NULL;
3097 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3099 al_free(ALContext);
3100 ALContext = NULL;
3103 alcSetError(device, ALC_OUT_OF_MEMORY);
3104 ALCdevice_DecRef(device);
3105 return NULL;
3108 ALContext->Device = device;
3109 ALCdevice_IncRef(device);
3110 InitContext(ALContext);
3113 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3114 do {
3115 ALContext->next = head;
3116 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3118 UnlockLists();
3120 ALCdevice_DecRef(device);
3122 TRACE("Created context %p\n", ALContext);
3123 return ALContext;
3126 /* alcDestroyContext
3128 * Remove a context from its device
3130 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3132 ALCdevice *Device;
3134 LockLists();
3135 /* alcGetContextsDevice sets an error for invalid contexts */
3136 Device = alcGetContextsDevice(context);
3137 if(Device)
3139 ReleaseContext(context, Device);
3140 if(!ATOMIC_LOAD(&Device->ContextList))
3142 V0(Device->Backend,stop)();
3143 Device->Flags &= ~DEVICE_RUNNING;
3146 UnlockLists();
3150 /* alcGetCurrentContext
3152 * Returns the currently active context on the calling thread
3154 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3156 ALCcontext *Context = altss_get(LocalContext);
3157 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3158 return Context;
3161 /* alcGetThreadContext
3163 * Returns the currently active thread-local context
3165 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3167 return altss_get(LocalContext);
3171 /* alcMakeContextCurrent
3173 * Makes the given context the active process-wide context, and removes the
3174 * thread-local context for the calling thread.
3176 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3178 /* context must be valid or NULL */
3179 if(context && !VerifyContext(&context))
3181 alcSetError(NULL, ALC_INVALID_CONTEXT);
3182 return ALC_FALSE;
3184 /* context's reference count is already incremented */
3185 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3186 if(context) ALCcontext_DecRef(context);
3188 if((context=altss_get(LocalContext)) != NULL)
3190 altss_set(LocalContext, NULL);
3191 ALCcontext_DecRef(context);
3194 return ALC_TRUE;
3197 /* alcSetThreadContext
3199 * Makes the given context the active context for the current thread
3201 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3203 ALCcontext *old;
3205 /* context must be valid or NULL */
3206 if(context && !VerifyContext(&context))
3208 alcSetError(NULL, ALC_INVALID_CONTEXT);
3209 return ALC_FALSE;
3211 /* context's reference count is already incremented */
3212 old = altss_get(LocalContext);
3213 altss_set(LocalContext, context);
3214 if(old) ALCcontext_DecRef(old);
3216 return ALC_TRUE;
3220 /* alcGetContextsDevice
3222 * Returns the device that a particular context is attached to
3224 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3226 ALCdevice *Device;
3228 if(!VerifyContext(&Context))
3230 alcSetError(NULL, ALC_INVALID_CONTEXT);
3231 return NULL;
3233 Device = Context->Device;
3234 ALCcontext_DecRef(Context);
3236 return Device;
3240 /* alcOpenDevice
3242 * Opens the named device.
3244 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3246 const ALCchar *fmt;
3247 ALCdevice *device;
3248 ALCenum err;
3250 DO_INITCONFIG();
3252 if(!PlaybackBackend.name)
3254 alcSetError(NULL, ALC_INVALID_VALUE);
3255 return NULL;
3258 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3259 #ifdef _WIN32
3260 /* Some old Windows apps hardcode these expecting OpenAL to use a
3261 * specific audio API, even when they're not enumerated. Creative's
3262 * router effectively ignores them too.
3264 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3265 || strcasecmp(deviceName, "MMSYSTEM") == 0
3266 #endif
3268 deviceName = NULL;
3270 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3271 if(!device)
3273 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3274 return NULL;
3277 //Validate device
3278 InitRef(&device->ref, 1);
3279 device->Connected = ALC_TRUE;
3280 device->Type = Playback;
3281 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3283 device->Flags = 0;
3284 device->Bs2b = NULL;
3285 device->Uhj_Encoder = NULL;
3286 VECTOR_INIT(device->Hrtf_List);
3287 AL_STRING_INIT(device->Hrtf_Name);
3288 device->Render_Mode = NormalRender;
3289 AL_STRING_INIT(device->DeviceName);
3290 device->Dry.Buffer = NULL;
3291 device->Dry.NumChannels = 0;
3292 device->VirtOut.Buffer = NULL;
3293 device->VirtOut.NumChannels = 0;
3294 device->RealOut.Buffer = NULL;
3295 device->RealOut.NumChannels = 0;
3297 ATOMIC_INIT(&device->ContextList, NULL);
3299 device->ClockBase = 0;
3300 device->SamplesDone = 0;
3302 device->MaxNoOfSources = 256;
3303 device->AuxiliaryEffectSlotMax = 4;
3304 device->NumAuxSends = MAX_SENDS;
3306 InitUIntMap(&device->BufferMap, ~0);
3307 InitUIntMap(&device->EffectMap, ~0);
3308 InitUIntMap(&device->FilterMap, ~0);
3310 //Set output format
3311 device->FmtChans = DevFmtChannelsDefault;
3312 device->FmtType = DevFmtTypeDefault;
3313 device->Frequency = DEFAULT_OUTPUT_RATE;
3314 device->IsHeadphones = AL_FALSE;
3315 device->NumUpdates = 4;
3316 device->UpdateSize = 1024;
3318 if(!PlaybackBackend.getFactory)
3319 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3320 ALCbackend_Playback);
3321 else
3323 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3324 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3326 if(!device->Backend)
3328 al_free(device);
3329 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3330 return NULL;
3334 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3336 static const struct {
3337 const char name[16];
3338 enum DevFmtChannels chans;
3339 } chanlist[] = {
3340 { "mono", DevFmtMono },
3341 { "stereo", DevFmtStereo },
3342 { "quad", DevFmtQuad },
3343 { "surround51", DevFmtX51 },
3344 { "surround61", DevFmtX61 },
3345 { "surround71", DevFmtX71 },
3346 { "surround51rear", DevFmtX51Rear },
3348 size_t i;
3350 for(i = 0;i < COUNTOF(chanlist);i++)
3352 if(strcasecmp(chanlist[i].name, fmt) == 0)
3354 device->FmtChans = chanlist[i].chans;
3355 device->Flags |= DEVICE_CHANNELS_REQUEST;
3356 break;
3359 if(i == COUNTOF(chanlist))
3360 ERR("Unsupported channels: %s\n", fmt);
3362 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3364 static const struct {
3365 const char name[16];
3366 enum DevFmtType type;
3367 } typelist[] = {
3368 { "int8", DevFmtByte },
3369 { "uint8", DevFmtUByte },
3370 { "int16", DevFmtShort },
3371 { "uint16", DevFmtUShort },
3372 { "int32", DevFmtInt },
3373 { "uint32", DevFmtUInt },
3374 { "float32", DevFmtFloat },
3376 size_t i;
3378 for(i = 0;i < COUNTOF(typelist);i++)
3380 if(strcasecmp(typelist[i].name, fmt) == 0)
3382 device->FmtType = typelist[i].type;
3383 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3384 break;
3387 if(i == COUNTOF(typelist))
3388 ERR("Unsupported sample-type: %s\n", fmt);
3391 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3393 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3394 if(device->Frequency < MIN_OUTPUT_RATE)
3395 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3396 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3399 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3400 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3402 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3403 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3404 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3405 device->UpdateSize = (device->UpdateSize+3)&~3;
3407 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3408 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3410 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3411 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3413 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3414 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3416 device->NumStereoSources = 1;
3417 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3419 // Find a playback device to open
3420 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3422 DELETE_OBJ(device->Backend);
3423 al_free(device);
3424 alcSetError(NULL, err);
3425 return NULL;
3428 if(DefaultEffect.type != AL_EFFECT_NULL)
3430 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3431 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3433 device->DefaultSlot = NULL;
3434 ERR("Failed to initialize the default effect slot\n");
3436 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3438 ALeffectState *state = device->DefaultSlot->EffectState;
3439 device->DefaultSlot = NULL;
3440 DELETE_OBJ(state);
3441 ERR("Failed to initialize the default effect\n");
3443 else
3444 aluInitEffectPanning(device->DefaultSlot);
3448 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3449 do {
3450 device->next = head;
3451 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3454 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3455 return device;
3458 /* alcCloseDevice
3460 * Closes the given device.
3462 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3464 ALCdevice *list, *origdev, *nextdev;
3465 ALCcontext *ctx;
3467 LockLists();
3468 list = ATOMIC_LOAD(&DeviceList);
3469 do {
3470 if(list == device)
3471 break;
3472 } while((list=list->next) != NULL);
3473 if(!list || list->Type == Capture)
3475 alcSetError(list, ALC_INVALID_DEVICE);
3476 UnlockLists();
3477 return ALC_FALSE;
3480 origdev = device;
3481 nextdev = device->next;
3482 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3484 do {
3485 list = origdev;
3486 origdev = device;
3487 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3489 UnlockLists();
3491 ctx = ATOMIC_LOAD(&device->ContextList);
3492 while(ctx != NULL)
3494 ALCcontext *next = ctx->next;
3495 WARN("Releasing context %p\n", ctx);
3496 ReleaseContext(ctx, device);
3497 ctx = next;
3499 if((device->Flags&DEVICE_RUNNING))
3500 V0(device->Backend,stop)();
3501 device->Flags &= ~DEVICE_RUNNING;
3503 ALCdevice_DecRef(device);
3505 return ALC_TRUE;
3509 /************************************************
3510 * ALC capture functions
3511 ************************************************/
3512 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3514 ALCdevice *device = NULL;
3515 ALCenum err;
3517 DO_INITCONFIG();
3519 if(!CaptureBackend.name)
3521 alcSetError(NULL, ALC_INVALID_VALUE);
3522 return NULL;
3525 if(samples <= 0)
3527 alcSetError(NULL, ALC_INVALID_VALUE);
3528 return NULL;
3531 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3532 deviceName = NULL;
3534 device = al_calloc(16, sizeof(ALCdevice));
3535 if(!device)
3537 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3538 return NULL;
3541 //Validate device
3542 InitRef(&device->ref, 1);
3543 device->Connected = ALC_TRUE;
3544 device->Type = Capture;
3546 VECTOR_INIT(device->Hrtf_List);
3547 AL_STRING_INIT(device->Hrtf_Name);
3549 AL_STRING_INIT(device->DeviceName);
3550 device->Dry.Buffer = NULL;
3551 device->Dry.NumChannels = 0;
3552 device->VirtOut.Buffer = NULL;
3553 device->VirtOut.NumChannels = 0;
3554 device->RealOut.Buffer = NULL;
3555 device->RealOut.NumChannels = 0;
3557 InitUIntMap(&device->BufferMap, ~0);
3558 InitUIntMap(&device->EffectMap, ~0);
3559 InitUIntMap(&device->FilterMap, ~0);
3561 if(!CaptureBackend.getFactory)
3562 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3563 ALCbackend_Capture);
3564 else
3566 ALCbackendFactory *factory = CaptureBackend.getFactory();
3567 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3569 if(!device->Backend)
3571 al_free(device);
3572 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3573 return NULL;
3576 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3577 device->Frequency = frequency;
3579 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3580 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3582 al_free(device);
3583 alcSetError(NULL, ALC_INVALID_ENUM);
3584 return NULL;
3586 device->IsHeadphones = AL_FALSE;
3588 device->UpdateSize = samples;
3589 device->NumUpdates = 1;
3591 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3593 al_free(device);
3594 alcSetError(NULL, err);
3595 return NULL;
3599 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3600 do {
3601 device->next = head;
3602 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3605 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3606 return device;
3609 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3611 ALCdevice *list, *next, *nextdev;
3613 LockLists();
3614 list = ATOMIC_LOAD(&DeviceList);
3615 do {
3616 if(list == device)
3617 break;
3618 } while((list=list->next) != NULL);
3619 if(!list || list->Type != Capture)
3621 alcSetError(list, ALC_INVALID_DEVICE);
3622 UnlockLists();
3623 return ALC_FALSE;
3626 next = device;
3627 nextdev = device->next;
3628 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3630 do {
3631 list = next;
3632 next = device;
3633 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3635 UnlockLists();
3637 ALCdevice_DecRef(device);
3639 return ALC_TRUE;
3642 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3644 if(!VerifyDevice(&device) || device->Type != Capture)
3645 alcSetError(device, ALC_INVALID_DEVICE);
3646 else
3648 V0(device->Backend,lock)();
3649 if(!device->Connected)
3650 alcSetError(device, ALC_INVALID_DEVICE);
3651 else if(!(device->Flags&DEVICE_RUNNING))
3653 if(V0(device->Backend,start)())
3654 device->Flags |= DEVICE_RUNNING;
3655 else
3657 aluHandleDisconnect(device);
3658 alcSetError(device, ALC_INVALID_DEVICE);
3661 V0(device->Backend,unlock)();
3664 if(device) ALCdevice_DecRef(device);
3667 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3669 if(!VerifyDevice(&device) || device->Type != Capture)
3670 alcSetError(device, ALC_INVALID_DEVICE);
3671 else
3673 V0(device->Backend,lock)();
3674 if((device->Flags&DEVICE_RUNNING))
3675 V0(device->Backend,stop)();
3676 device->Flags &= ~DEVICE_RUNNING;
3677 V0(device->Backend,unlock)();
3680 if(device) ALCdevice_DecRef(device);
3683 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3685 if(!VerifyDevice(&device) || device->Type != Capture)
3686 alcSetError(device, ALC_INVALID_DEVICE);
3687 else
3689 ALCenum err = ALC_INVALID_VALUE;
3691 V0(device->Backend,lock)();
3692 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3693 err = V(device->Backend,captureSamples)(buffer, samples);
3694 V0(device->Backend,unlock)();
3696 if(err != ALC_NO_ERROR)
3697 alcSetError(device, err);
3699 if(device) ALCdevice_DecRef(device);
3703 /************************************************
3704 * ALC loopback functions
3705 ************************************************/
3707 /* alcLoopbackOpenDeviceSOFT
3709 * Open a loopback device, for manual rendering.
3711 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3713 ALCbackendFactory *factory;
3714 ALCdevice *device;
3716 DO_INITCONFIG();
3718 /* Make sure the device name, if specified, is us. */
3719 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3721 alcSetError(NULL, ALC_INVALID_VALUE);
3722 return NULL;
3725 device = al_calloc(16, sizeof(ALCdevice));
3726 if(!device)
3728 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3729 return NULL;
3732 //Validate device
3733 InitRef(&device->ref, 1);
3734 device->Connected = ALC_TRUE;
3735 device->Type = Loopback;
3736 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3738 device->Flags = 0;
3739 VECTOR_INIT(device->Hrtf_List);
3740 AL_STRING_INIT(device->Hrtf_Name);
3741 device->Bs2b = NULL;
3742 device->Uhj_Encoder = NULL;
3743 device->Render_Mode = NormalRender;
3744 AL_STRING_INIT(device->DeviceName);
3745 device->Dry.Buffer = NULL;
3746 device->Dry.NumChannels = 0;
3747 device->VirtOut.Buffer = NULL;
3748 device->VirtOut.NumChannels = 0;
3749 device->RealOut.Buffer = NULL;
3750 device->RealOut.NumChannels = 0;
3752 ATOMIC_INIT(&device->ContextList, NULL);
3754 device->ClockBase = 0;
3755 device->SamplesDone = 0;
3757 device->MaxNoOfSources = 256;
3758 device->AuxiliaryEffectSlotMax = 4;
3759 device->NumAuxSends = MAX_SENDS;
3761 InitUIntMap(&device->BufferMap, ~0);
3762 InitUIntMap(&device->EffectMap, ~0);
3763 InitUIntMap(&device->FilterMap, ~0);
3765 factory = ALCloopbackFactory_getFactory();
3766 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3767 if(!device->Backend)
3769 al_free(device);
3770 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3771 return NULL;
3774 //Set output format
3775 device->NumUpdates = 0;
3776 device->UpdateSize = 0;
3778 device->Frequency = DEFAULT_OUTPUT_RATE;
3779 device->FmtChans = DevFmtChannelsDefault;
3780 device->FmtType = DevFmtTypeDefault;
3781 device->IsHeadphones = AL_FALSE;
3783 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3784 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3786 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3787 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3789 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3790 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3792 device->NumStereoSources = 1;
3793 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3795 // Open the "backend"
3796 V(device->Backend,open)("Loopback");
3799 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3800 do {
3801 device->next = head;
3802 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3805 TRACE("Created device %p\n", device);
3806 return device;
3809 /* alcIsRenderFormatSupportedSOFT
3811 * Determines if the loopback device supports the given format for rendering.
3813 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3815 ALCboolean ret = ALC_FALSE;
3817 if(!VerifyDevice(&device) || device->Type != Loopback)
3818 alcSetError(device, ALC_INVALID_DEVICE);
3819 else if(freq <= 0)
3820 alcSetError(device, ALC_INVALID_VALUE);
3821 else
3823 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3824 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3825 freq >= MIN_OUTPUT_RATE)
3826 ret = ALC_TRUE;
3828 if(device) ALCdevice_DecRef(device);
3830 return ret;
3833 /* alcRenderSamplesSOFT
3835 * Renders some samples into a buffer, using the format last set by the
3836 * attributes given to alcCreateContext.
3838 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3840 if(!VerifyDevice(&device) || device->Type != Loopback)
3841 alcSetError(device, ALC_INVALID_DEVICE);
3842 else if(samples < 0 || (samples > 0 && buffer == NULL))
3843 alcSetError(device, ALC_INVALID_VALUE);
3844 else
3845 aluMixData(device, buffer, samples);
3846 if(device) ALCdevice_DecRef(device);
3850 /************************************************
3851 * ALC DSP pause/resume functions
3852 ************************************************/
3854 /* alcDevicePauseSOFT
3856 * Pause the DSP to stop audio processing.
3858 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3860 if(!VerifyDevice(&device) || device->Type != Playback)
3861 alcSetError(device, ALC_INVALID_DEVICE);
3862 else
3864 LockLists();
3865 if((device->Flags&DEVICE_RUNNING))
3866 V0(device->Backend,stop)();
3867 device->Flags &= ~DEVICE_RUNNING;
3868 device->Flags |= DEVICE_PAUSED;
3869 UnlockLists();
3871 if(device) ALCdevice_DecRef(device);
3874 /* alcDeviceResumeSOFT
3876 * Resume the DSP to restart audio processing.
3878 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3880 if(!VerifyDevice(&device) || device->Type != Playback)
3881 alcSetError(device, ALC_INVALID_DEVICE);
3882 else
3884 LockLists();
3885 if((device->Flags&DEVICE_PAUSED))
3887 device->Flags &= ~DEVICE_PAUSED;
3888 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3890 if(V0(device->Backend,start)() != ALC_FALSE)
3891 device->Flags |= DEVICE_RUNNING;
3892 else
3894 alcSetError(device, ALC_INVALID_DEVICE);
3895 V0(device->Backend,lock)();
3896 aluHandleDisconnect(device);
3897 V0(device->Backend,unlock)();
3901 UnlockLists();
3903 if(device) ALCdevice_DecRef(device);
3907 /************************************************
3908 * ALC HRTF functions
3909 ************************************************/
3911 /* alcGetStringiSOFT
3913 * Gets a string parameter at the given index.
3915 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3917 const ALCchar *str = NULL;
3919 if(!VerifyDevice(&device) || device->Type == Capture)
3920 alcSetError(device, ALC_INVALID_DEVICE);
3921 else switch(paramName)
3923 case ALC_HRTF_SPECIFIER_SOFT:
3924 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
3925 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
3926 else
3927 alcSetError(device, ALC_INVALID_VALUE);
3928 break;
3930 default:
3931 alcSetError(device, ALC_INVALID_ENUM);
3932 break;
3934 if(device) ALCdevice_DecRef(device);
3936 return str;
3939 /* alcResetDeviceSOFT
3941 * Resets the given device output, using the specified attribute list.
3943 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
3945 ALCenum err;
3947 LockLists();
3948 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3950 UnlockLists();
3951 alcSetError(device, ALC_INVALID_DEVICE);
3952 if(device) ALCdevice_DecRef(device);
3953 return ALC_FALSE;
3956 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
3958 UnlockLists();
3959 alcSetError(device, err);
3960 if(err == ALC_INVALID_DEVICE)
3962 V0(device->Backend,lock)();
3963 aluHandleDisconnect(device);
3964 V0(device->Backend,unlock)();
3966 ALCdevice_DecRef(device);
3967 return ALC_FALSE;
3969 UnlockLists();
3970 ALCdevice_DecRef(device);
3972 return ALC_TRUE;