Drop support for AL_SOFT_buffer_samples and AL_SOFT_buffer_sub_data
[openal-soft.git] / Alc / ALc.c
blob12fc782ff33dc47461a1e02573e57f6ec29bf09c
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_STEREO_ANGLES),
517 DECL(AL_UNUSED),
518 DECL(AL_PENDING),
519 DECL(AL_PROCESSED),
521 DECL(AL_NO_ERROR),
522 DECL(AL_INVALID_NAME),
523 DECL(AL_INVALID_ENUM),
524 DECL(AL_INVALID_VALUE),
525 DECL(AL_INVALID_OPERATION),
526 DECL(AL_OUT_OF_MEMORY),
528 DECL(AL_VENDOR),
529 DECL(AL_VERSION),
530 DECL(AL_RENDERER),
531 DECL(AL_EXTENSIONS),
533 DECL(AL_DOPPLER_FACTOR),
534 DECL(AL_DOPPLER_VELOCITY),
535 DECL(AL_DISTANCE_MODEL),
536 DECL(AL_SPEED_OF_SOUND),
537 DECL(AL_SOURCE_DISTANCE_MODEL),
538 DECL(AL_DEFERRED_UPDATES_SOFT),
540 DECL(AL_INVERSE_DISTANCE),
541 DECL(AL_INVERSE_DISTANCE_CLAMPED),
542 DECL(AL_LINEAR_DISTANCE),
543 DECL(AL_LINEAR_DISTANCE_CLAMPED),
544 DECL(AL_EXPONENT_DISTANCE),
545 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
547 DECL(AL_FILTER_TYPE),
548 DECL(AL_FILTER_NULL),
549 DECL(AL_FILTER_LOWPASS),
550 DECL(AL_FILTER_HIGHPASS),
551 DECL(AL_FILTER_BANDPASS),
553 DECL(AL_LOWPASS_GAIN),
554 DECL(AL_LOWPASS_GAINHF),
556 DECL(AL_HIGHPASS_GAIN),
557 DECL(AL_HIGHPASS_GAINLF),
559 DECL(AL_BANDPASS_GAIN),
560 DECL(AL_BANDPASS_GAINHF),
561 DECL(AL_BANDPASS_GAINLF),
563 DECL(AL_EFFECT_TYPE),
564 DECL(AL_EFFECT_NULL),
565 DECL(AL_EFFECT_REVERB),
566 DECL(AL_EFFECT_EAXREVERB),
567 DECL(AL_EFFECT_CHORUS),
568 DECL(AL_EFFECT_DISTORTION),
569 DECL(AL_EFFECT_ECHO),
570 DECL(AL_EFFECT_FLANGER),
571 #if 0
572 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
573 DECL(AL_EFFECT_VOCAL_MORPHER),
574 DECL(AL_EFFECT_PITCH_SHIFTER),
575 #endif
576 DECL(AL_EFFECT_RING_MODULATOR),
577 #if 0
578 DECL(AL_EFFECT_AUTOWAH),
579 #endif
580 DECL(AL_EFFECT_COMPRESSOR),
581 DECL(AL_EFFECT_EQUALIZER),
582 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
583 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
585 DECL(AL_EAXREVERB_DENSITY),
586 DECL(AL_EAXREVERB_DIFFUSION),
587 DECL(AL_EAXREVERB_GAIN),
588 DECL(AL_EAXREVERB_GAINHF),
589 DECL(AL_EAXREVERB_GAINLF),
590 DECL(AL_EAXREVERB_DECAY_TIME),
591 DECL(AL_EAXREVERB_DECAY_HFRATIO),
592 DECL(AL_EAXREVERB_DECAY_LFRATIO),
593 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
594 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
595 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
596 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
597 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
598 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
599 DECL(AL_EAXREVERB_ECHO_TIME),
600 DECL(AL_EAXREVERB_ECHO_DEPTH),
601 DECL(AL_EAXREVERB_MODULATION_TIME),
602 DECL(AL_EAXREVERB_MODULATION_DEPTH),
603 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
604 DECL(AL_EAXREVERB_HFREFERENCE),
605 DECL(AL_EAXREVERB_LFREFERENCE),
606 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
607 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
609 DECL(AL_REVERB_DENSITY),
610 DECL(AL_REVERB_DIFFUSION),
611 DECL(AL_REVERB_GAIN),
612 DECL(AL_REVERB_GAINHF),
613 DECL(AL_REVERB_DECAY_TIME),
614 DECL(AL_REVERB_DECAY_HFRATIO),
615 DECL(AL_REVERB_REFLECTIONS_GAIN),
616 DECL(AL_REVERB_REFLECTIONS_DELAY),
617 DECL(AL_REVERB_LATE_REVERB_GAIN),
618 DECL(AL_REVERB_LATE_REVERB_DELAY),
619 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
620 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
621 DECL(AL_REVERB_DECAY_HFLIMIT),
623 DECL(AL_CHORUS_WAVEFORM),
624 DECL(AL_CHORUS_PHASE),
625 DECL(AL_CHORUS_RATE),
626 DECL(AL_CHORUS_DEPTH),
627 DECL(AL_CHORUS_FEEDBACK),
628 DECL(AL_CHORUS_DELAY),
630 DECL(AL_DISTORTION_EDGE),
631 DECL(AL_DISTORTION_GAIN),
632 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
633 DECL(AL_DISTORTION_EQCENTER),
634 DECL(AL_DISTORTION_EQBANDWIDTH),
636 DECL(AL_ECHO_DELAY),
637 DECL(AL_ECHO_LRDELAY),
638 DECL(AL_ECHO_DAMPING),
639 DECL(AL_ECHO_FEEDBACK),
640 DECL(AL_ECHO_SPREAD),
642 DECL(AL_FLANGER_WAVEFORM),
643 DECL(AL_FLANGER_PHASE),
644 DECL(AL_FLANGER_RATE),
645 DECL(AL_FLANGER_DEPTH),
646 DECL(AL_FLANGER_FEEDBACK),
647 DECL(AL_FLANGER_DELAY),
649 DECL(AL_RING_MODULATOR_FREQUENCY),
650 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
651 DECL(AL_RING_MODULATOR_WAVEFORM),
653 #if 0
654 DECL(AL_AUTOWAH_ATTACK_TIME),
655 DECL(AL_AUTOWAH_PEAK_GAIN),
656 DECL(AL_AUTOWAH_RELEASE_TIME),
657 DECL(AL_AUTOWAH_RESONANCE),
658 #endif
660 DECL(AL_COMPRESSOR_ONOFF),
662 DECL(AL_EQUALIZER_LOW_GAIN),
663 DECL(AL_EQUALIZER_LOW_CUTOFF),
664 DECL(AL_EQUALIZER_MID1_GAIN),
665 DECL(AL_EQUALIZER_MID1_CENTER),
666 DECL(AL_EQUALIZER_MID1_WIDTH),
667 DECL(AL_EQUALIZER_MID2_GAIN),
668 DECL(AL_EQUALIZER_MID2_CENTER),
669 DECL(AL_EQUALIZER_MID2_WIDTH),
670 DECL(AL_EQUALIZER_HIGH_GAIN),
671 DECL(AL_EQUALIZER_HIGH_CUTOFF),
673 DECL(AL_DEDICATED_GAIN),
675 { NULL, (ALCenum)0 }
677 #undef DECL
679 static const ALCchar alcNoError[] = "No Error";
680 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
681 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
682 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
683 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
684 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
687 /************************************************
688 * Global variables
689 ************************************************/
691 /* Enumerated device names */
692 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
694 static al_string alcAllDevicesList;
695 static al_string alcCaptureDeviceList;
697 /* Default is always the first in the list */
698 static ALCchar *alcDefaultAllDevicesSpecifier;
699 static ALCchar *alcCaptureDefaultDeviceSpecifier;
701 /* Default context extensions */
702 static const ALchar alExtList[] =
703 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
704 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
705 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
706 "AL_EXT_source_distance_model AL_EXT_STEREO_ANGLES AL_LOKI_quadriphonic "
707 "AL_SOFT_block_alignment AL_SOFT_deferred_updates AL_SOFT_direct_channels "
708 "AL_SOFT_loop_points AL_SOFT_MSADPCM AL_SOFT_source_latency "
709 "AL_SOFT_source_length";
711 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
713 /* Thread-local current context */
714 static altss_t LocalContext;
715 /* Process-wide current context */
716 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
718 /* Mixing thread piority level */
719 ALint RTPrioLevel;
721 FILE *LogFile;
722 #ifdef _DEBUG
723 enum LogLevel LogLevel = LogWarning;
724 #else
725 enum LogLevel LogLevel = LogError;
726 #endif
728 /* Flag to trap ALC device errors */
729 static ALCboolean TrapALCError = ALC_FALSE;
731 /* One-time configuration init control */
732 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
734 /* Default effect that applies to sources that don't have an effect on send 0 */
735 static ALeffect DefaultEffect;
737 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
738 * updates.
740 static ALCboolean SuspendDefers = ALC_TRUE;
743 /************************************************
744 * ALC information
745 ************************************************/
746 static const ALCchar alcNoDeviceExtList[] =
747 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
748 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
749 static const ALCchar alcExtensionList[] =
750 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
751 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
752 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
753 "ALC_SOFT_loopback ALC_SOFT_pause_device";
754 static const ALCint alcMajorVersion = 1;
755 static const ALCint alcMinorVersion = 1;
757 static const ALCint alcEFXMajorVersion = 1;
758 static const ALCint alcEFXMinorVersion = 0;
761 /************************************************
762 * Device lists
763 ************************************************/
764 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
766 static almtx_t ListLock;
767 static inline void LockLists(void)
769 int lockret = almtx_lock(&ListLock);
770 assert(lockret == althrd_success);
772 static inline void UnlockLists(void)
774 int unlockret = almtx_unlock(&ListLock);
775 assert(unlockret == althrd_success);
778 /************************************************
779 * Library initialization
780 ************************************************/
781 #if defined(_WIN32)
782 static void alc_init(void);
783 static void alc_deinit(void);
784 static void alc_deinit_safe(void);
786 #ifndef AL_LIBTYPE_STATIC
787 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
789 switch(reason)
791 case DLL_PROCESS_ATTACH:
792 /* Pin the DLL so we won't get unloaded until the process terminates */
793 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
794 (WCHAR*)hModule, &hModule);
795 alc_init();
796 break;
798 case DLL_THREAD_DETACH:
799 break;
801 case DLL_PROCESS_DETACH:
802 if(!lpReserved)
803 alc_deinit();
804 else
805 alc_deinit_safe();
806 break;
808 return TRUE;
810 #elif defined(_MSC_VER)
811 #pragma section(".CRT$XCU",read)
812 static void alc_constructor(void);
813 static void alc_destructor(void);
814 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
816 static void alc_constructor(void)
818 atexit(alc_destructor);
819 alc_init();
822 static void alc_destructor(void)
824 alc_deinit();
826 #elif defined(HAVE_GCC_DESTRUCTOR)
827 static void alc_init(void) __attribute__((constructor));
828 static void alc_deinit(void) __attribute__((destructor));
829 #else
830 #error "No static initialization available on this platform!"
831 #endif
833 #elif defined(HAVE_GCC_DESTRUCTOR)
835 static void alc_init(void) __attribute__((constructor));
836 static void alc_deinit(void) __attribute__((destructor));
838 #else
839 #error "No global initialization available on this platform!"
840 #endif
842 static void ReleaseThreadCtx(void *ptr);
843 static void alc_init(void)
845 const char *str;
846 int ret;
848 LogFile = stderr;
850 AL_STRING_INIT(alcAllDevicesList);
851 AL_STRING_INIT(alcCaptureDeviceList);
853 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
854 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
855 ConeScale *= 0.5f;
857 str = getenv("__ALSOFT_REVERSE_Z");
858 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
859 ZScale *= -1.0f;
861 ret = altss_create(&LocalContext, ReleaseThreadCtx);
862 assert(ret == althrd_success);
864 ret = almtx_init(&ListLock, almtx_recursive);
865 assert(ret == althrd_success);
867 ThunkInit();
870 static void alc_initconfig(void)
872 const char *devs, *str;
873 ALuint capfilter;
874 float valf;
875 int i, n;
877 str = getenv("ALSOFT_LOGLEVEL");
878 if(str)
880 long lvl = strtol(str, NULL, 0);
881 if(lvl >= NoLog && lvl <= LogRef)
882 LogLevel = lvl;
885 str = getenv("ALSOFT_LOGFILE");
886 if(str && str[0])
888 FILE *logfile = al_fopen(str, "wt");
889 if(logfile) LogFile = logfile;
890 else ERR("Failed to open log file '%s'\n", str);
894 char buf[1024] = "";
895 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
896 for(i = 1;BackendList[i].name;i++)
897 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
898 TRACE("Supported backends: %s\n", buf);
900 ReadALConfig();
902 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
903 if(str && *str)
905 if(strcasecmp(str, "ignore") == 0)
907 SuspendDefers = ALC_FALSE;
908 TRACE("Selected context suspend behavior, \"ignore\"\n");
910 else
911 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
914 capfilter = 0;
915 #if defined(HAVE_SSE4_1)
916 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
917 #elif defined(HAVE_SSE3)
918 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
919 #elif defined(HAVE_SSE2)
920 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
921 #elif defined(HAVE_SSE)
922 capfilter |= CPU_CAP_SSE;
923 #endif
924 #ifdef HAVE_NEON
925 capfilter |= CPU_CAP_NEON;
926 #endif
927 if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
929 if(strcasecmp(str, "all") == 0)
930 capfilter = 0;
931 else
933 size_t len;
934 const char *next = str;
936 do {
937 str = next;
938 while(isspace(str[0]))
939 str++;
940 next = strchr(str, ',');
942 if(!str[0] || str[0] == ',')
943 continue;
945 len = (next ? ((size_t)(next-str)) : strlen(str));
946 while(len > 0 && isspace(str[len-1]))
947 len--;
948 if(len == 3 && strncasecmp(str, "sse", len) == 0)
949 capfilter &= ~CPU_CAP_SSE;
950 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
951 capfilter &= ~CPU_CAP_SSE2;
952 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
953 capfilter &= ~CPU_CAP_SSE3;
954 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
955 capfilter &= ~CPU_CAP_SSE4_1;
956 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
957 capfilter &= ~CPU_CAP_NEON;
958 else
959 WARN("Invalid CPU extension \"%s\"\n", str);
960 } while(next++);
963 FillCPUCaps(capfilter);
965 #ifdef _WIN32
966 RTPrioLevel = 1;
967 #else
968 RTPrioLevel = 0;
969 #endif
970 ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
972 aluInitMixer();
974 str = getenv("ALSOFT_TRAP_ERROR");
975 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
977 TrapALError = AL_TRUE;
978 TrapALCError = AL_TRUE;
980 else
982 str = getenv("ALSOFT_TRAP_AL_ERROR");
983 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
984 TrapALError = AL_TRUE;
985 TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
987 str = getenv("ALSOFT_TRAP_ALC_ERROR");
988 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
989 TrapALCError = ALC_TRUE;
990 TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
993 if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
994 ReverbBoost *= powf(10.0f, valf / 20.0f);
996 EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
998 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
999 ConfigValueStr(NULL, NULL, "drivers", &devs))
1001 int n;
1002 size_t len;
1003 const char *next = devs;
1004 int endlist, delitem;
1006 i = 0;
1007 do {
1008 devs = next;
1009 while(isspace(devs[0]))
1010 devs++;
1011 next = strchr(devs, ',');
1013 delitem = (devs[0] == '-');
1014 if(devs[0] == '-') devs++;
1016 if(!devs[0] || devs[0] == ',')
1018 endlist = 0;
1019 continue;
1021 endlist = 1;
1023 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1024 while(len > 0 && isspace(devs[len-1]))
1025 len--;
1026 for(n = i;BackendList[n].name;n++)
1028 if(len == strlen(BackendList[n].name) &&
1029 strncmp(BackendList[n].name, devs, len) == 0)
1031 if(delitem)
1033 do {
1034 BackendList[n] = BackendList[n+1];
1035 ++n;
1036 } while(BackendList[n].name);
1038 else
1040 struct BackendInfo Bkp = BackendList[n];
1041 while(n > i)
1043 BackendList[n] = BackendList[n-1];
1044 --n;
1046 BackendList[n] = Bkp;
1048 i++;
1050 break;
1053 } while(next++);
1055 if(endlist)
1057 BackendList[i].name = NULL;
1058 BackendList[i].getFactory = NULL;
1059 BackendList[i].Init = NULL;
1060 BackendList[i].Deinit = NULL;
1061 BackendList[i].Probe = NULL;
1065 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1067 if(BackendList[i].getFactory)
1069 ALCbackendFactory *factory = BackendList[i].getFactory();
1070 if(!V0(factory,init)())
1072 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1073 continue;
1076 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1077 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1079 PlaybackBackend = BackendList[i];
1080 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1082 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1084 CaptureBackend = BackendList[i];
1085 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1088 continue;
1091 if(!BackendList[i].Init(&BackendList[i].Funcs))
1093 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1094 continue;
1097 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1098 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1100 PlaybackBackend = BackendList[i];
1101 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1103 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1105 CaptureBackend = BackendList[i];
1106 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1110 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1111 V0(factory,init)();
1114 if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1116 size_t len;
1117 const char *next = str;
1119 do {
1120 str = next;
1121 next = strchr(str, ',');
1123 if(!str[0] || next == str)
1124 continue;
1126 len = (next ? ((size_t)(next-str)) : strlen(str));
1127 for(n = 0;EffectList[n].name;n++)
1129 if(len == strlen(EffectList[n].name) &&
1130 strncmp(EffectList[n].name, str, len) == 0)
1131 DisabledEffects[EffectList[n].type] = AL_TRUE;
1133 } while(next++);
1136 InitEffectFactoryMap();
1138 InitEffect(&DefaultEffect);
1139 str = getenv("ALSOFT_DEFAULT_REVERB");
1140 if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1141 LoadReverbPreset(str, &DefaultEffect);
1143 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1146 /************************************************
1147 * Library deinitialization
1148 ************************************************/
1149 static void alc_cleanup(void)
1151 ALCdevice *dev;
1153 AL_STRING_DEINIT(alcAllDevicesList);
1154 AL_STRING_DEINIT(alcCaptureDeviceList);
1156 free(alcDefaultAllDevicesSpecifier);
1157 alcDefaultAllDevicesSpecifier = NULL;
1158 free(alcCaptureDefaultDeviceSpecifier);
1159 alcCaptureDefaultDeviceSpecifier = NULL;
1161 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1163 ALCuint num = 0;
1164 do {
1165 num++;
1166 } while((dev=dev->next) != NULL);
1167 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1170 DeinitEffectFactoryMap();
1173 static void alc_deinit_safe(void)
1175 alc_cleanup();
1177 FreeHrtfs();
1178 FreeALConfig();
1180 ThunkExit();
1181 almtx_destroy(&ListLock);
1182 altss_delete(LocalContext);
1184 if(LogFile != stderr)
1185 fclose(LogFile);
1186 LogFile = NULL;
1189 static void alc_deinit(void)
1191 int i;
1193 alc_cleanup();
1195 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1196 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1198 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1200 if(!BackendList[i].getFactory)
1201 BackendList[i].Deinit();
1202 else
1204 ALCbackendFactory *factory = BackendList[i].getFactory();
1205 V0(factory,deinit)();
1209 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1210 V0(factory,deinit)();
1213 alc_deinit_safe();
1217 /************************************************
1218 * Device enumeration
1219 ************************************************/
1220 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1222 DO_INITCONFIG();
1224 LockLists();
1225 al_string_clear(list);
1227 if(!backendinfo->getFactory)
1228 backendinfo->Probe(type);
1229 else
1231 ALCbackendFactory *factory = backendinfo->getFactory();
1232 V(factory,probe)(type);
1235 UnlockLists();
1237 static void ProbeAllDevicesList(void)
1238 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1239 static void ProbeCaptureDeviceList(void)
1240 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1242 static void AppendDevice(const ALCchar *name, al_string *devnames)
1244 size_t len = strlen(name);
1245 if(len > 0)
1246 al_string_append_range(devnames, name, name+len+1);
1248 void AppendAllDevicesList(const ALCchar *name)
1249 { AppendDevice(name, &alcAllDevicesList); }
1250 void AppendCaptureDeviceList(const ALCchar *name)
1251 { AppendDevice(name, &alcCaptureDeviceList); }
1254 /************************************************
1255 * Device format information
1256 ************************************************/
1257 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1259 switch(type)
1261 case DevFmtByte: return "Signed Byte";
1262 case DevFmtUByte: return "Unsigned Byte";
1263 case DevFmtShort: return "Signed Short";
1264 case DevFmtUShort: return "Unsigned Short";
1265 case DevFmtInt: return "Signed Int";
1266 case DevFmtUInt: return "Unsigned Int";
1267 case DevFmtFloat: return "Float";
1269 return "(unknown type)";
1271 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1273 switch(chans)
1275 case DevFmtMono: return "Mono";
1276 case DevFmtStereo: return "Stereo";
1277 case DevFmtQuad: return "Quadraphonic";
1278 case DevFmtX51: return "5.1 Surround";
1279 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1280 case DevFmtX61: return "6.1 Surround";
1281 case DevFmtX71: return "7.1 Surround";
1282 case DevFmtBFormat3D: return "B-Format 3D";
1284 return "(unknown channels)";
1287 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1288 ALuint BytesFromDevFmt(enum DevFmtType type)
1290 switch(type)
1292 case DevFmtByte: return sizeof(ALbyte);
1293 case DevFmtUByte: return sizeof(ALubyte);
1294 case DevFmtShort: return sizeof(ALshort);
1295 case DevFmtUShort: return sizeof(ALushort);
1296 case DevFmtInt: return sizeof(ALint);
1297 case DevFmtUInt: return sizeof(ALuint);
1298 case DevFmtFloat: return sizeof(ALfloat);
1300 return 0;
1302 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1304 switch(chans)
1306 case DevFmtMono: return 1;
1307 case DevFmtStereo: return 2;
1308 case DevFmtQuad: return 4;
1309 case DevFmtX51: return 6;
1310 case DevFmtX51Rear: return 6;
1311 case DevFmtX61: return 7;
1312 case DevFmtX71: return 8;
1313 case DevFmtBFormat3D: return 4;
1315 return 0;
1318 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1319 enum DevFmtChannels *chans, enum DevFmtType *type)
1321 static const struct {
1322 ALenum format;
1323 enum DevFmtChannels channels;
1324 enum DevFmtType type;
1325 } list[] = {
1326 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1327 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1328 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1330 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1331 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1332 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1334 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1335 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1336 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1338 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1339 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1340 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1342 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1343 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1344 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1346 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1347 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1348 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1350 ALuint i;
1352 for(i = 0;i < COUNTOF(list);i++)
1354 if(list[i].format == format)
1356 *chans = list[i].channels;
1357 *type = list[i].type;
1358 return AL_TRUE;
1362 return AL_FALSE;
1365 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1367 switch(type)
1369 case ALC_BYTE_SOFT:
1370 case ALC_UNSIGNED_BYTE_SOFT:
1371 case ALC_SHORT_SOFT:
1372 case ALC_UNSIGNED_SHORT_SOFT:
1373 case ALC_INT_SOFT:
1374 case ALC_UNSIGNED_INT_SOFT:
1375 case ALC_FLOAT_SOFT:
1376 return ALC_TRUE;
1378 return ALC_FALSE;
1381 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1383 switch(channels)
1385 case ALC_MONO_SOFT:
1386 case ALC_STEREO_SOFT:
1387 case ALC_QUAD_SOFT:
1388 case ALC_5POINT1_SOFT:
1389 case ALC_6POINT1_SOFT:
1390 case ALC_7POINT1_SOFT:
1391 return ALC_TRUE;
1393 return ALC_FALSE;
1397 /************************************************
1398 * Miscellaneous ALC helpers
1399 ************************************************/
1401 extern inline void LockContext(ALCcontext *context);
1402 extern inline void UnlockContext(ALCcontext *context);
1404 void ALCdevice_Lock(ALCdevice *device)
1406 V0(device->Backend,lock)();
1409 void ALCdevice_Unlock(ALCdevice *device)
1411 V0(device->Backend,unlock)();
1415 /* SetDefaultWFXChannelOrder
1417 * Sets the default channel order used by WaveFormatEx.
1419 void SetDefaultWFXChannelOrder(ALCdevice *device)
1421 ALuint i;
1423 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1424 device->RealOut.ChannelName[i] = InvalidChannel;
1426 switch(device->FmtChans)
1428 case DevFmtMono:
1429 device->RealOut.ChannelName[0] = FrontCenter;
1430 break;
1431 case DevFmtStereo:
1432 device->RealOut.ChannelName[0] = FrontLeft;
1433 device->RealOut.ChannelName[1] = FrontRight;
1434 break;
1435 case DevFmtQuad:
1436 device->RealOut.ChannelName[0] = FrontLeft;
1437 device->RealOut.ChannelName[1] = FrontRight;
1438 device->RealOut.ChannelName[2] = BackLeft;
1439 device->RealOut.ChannelName[3] = BackRight;
1440 break;
1441 case DevFmtX51:
1442 device->RealOut.ChannelName[0] = FrontLeft;
1443 device->RealOut.ChannelName[1] = FrontRight;
1444 device->RealOut.ChannelName[2] = FrontCenter;
1445 device->RealOut.ChannelName[3] = LFE;
1446 device->RealOut.ChannelName[4] = SideLeft;
1447 device->RealOut.ChannelName[5] = SideRight;
1448 break;
1449 case DevFmtX51Rear:
1450 device->RealOut.ChannelName[0] = FrontLeft;
1451 device->RealOut.ChannelName[1] = FrontRight;
1452 device->RealOut.ChannelName[2] = FrontCenter;
1453 device->RealOut.ChannelName[3] = LFE;
1454 device->RealOut.ChannelName[4] = BackLeft;
1455 device->RealOut.ChannelName[5] = BackRight;
1456 break;
1457 case DevFmtX61:
1458 device->RealOut.ChannelName[0] = FrontLeft;
1459 device->RealOut.ChannelName[1] = FrontRight;
1460 device->RealOut.ChannelName[2] = FrontCenter;
1461 device->RealOut.ChannelName[3] = LFE;
1462 device->RealOut.ChannelName[4] = BackCenter;
1463 device->RealOut.ChannelName[5] = SideLeft;
1464 device->RealOut.ChannelName[6] = SideRight;
1465 break;
1466 case DevFmtX71:
1467 device->RealOut.ChannelName[0] = FrontLeft;
1468 device->RealOut.ChannelName[1] = FrontRight;
1469 device->RealOut.ChannelName[2] = FrontCenter;
1470 device->RealOut.ChannelName[3] = LFE;
1471 device->RealOut.ChannelName[4] = BackLeft;
1472 device->RealOut.ChannelName[5] = BackRight;
1473 device->RealOut.ChannelName[6] = SideLeft;
1474 device->RealOut.ChannelName[7] = SideRight;
1475 break;
1476 case DevFmtBFormat3D:
1477 device->RealOut.ChannelName[0] = Aux0;
1478 device->RealOut.ChannelName[1] = Aux1;
1479 device->RealOut.ChannelName[2] = Aux2;
1480 device->RealOut.ChannelName[3] = Aux3;
1481 break;
1485 /* SetDefaultChannelOrder
1487 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1489 void SetDefaultChannelOrder(ALCdevice *device)
1491 ALuint i;
1493 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1494 device->RealOut.ChannelName[i] = InvalidChannel;
1496 switch(device->FmtChans)
1498 case DevFmtX51Rear:
1499 device->RealOut.ChannelName[0] = FrontLeft;
1500 device->RealOut.ChannelName[1] = FrontRight;
1501 device->RealOut.ChannelName[2] = BackLeft;
1502 device->RealOut.ChannelName[3] = BackRight;
1503 device->RealOut.ChannelName[4] = FrontCenter;
1504 device->RealOut.ChannelName[5] = LFE;
1505 return;
1506 case DevFmtX71:
1507 device->RealOut.ChannelName[0] = FrontLeft;
1508 device->RealOut.ChannelName[1] = FrontRight;
1509 device->RealOut.ChannelName[2] = BackLeft;
1510 device->RealOut.ChannelName[3] = BackRight;
1511 device->RealOut.ChannelName[4] = FrontCenter;
1512 device->RealOut.ChannelName[5] = LFE;
1513 device->RealOut.ChannelName[6] = SideLeft;
1514 device->RealOut.ChannelName[7] = SideRight;
1515 return;
1517 /* Same as WFX order */
1518 case DevFmtMono:
1519 case DevFmtStereo:
1520 case DevFmtQuad:
1521 case DevFmtX51:
1522 case DevFmtX61:
1523 case DevFmtBFormat3D:
1524 SetDefaultWFXChannelOrder(device);
1525 break;
1529 extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan);
1532 /* ALCcontext_DeferUpdates
1534 * Defers/suspends updates for the given context's listener and sources. This
1535 * does *NOT* stop mixing, but rather prevents certain property changes from
1536 * taking effect.
1538 void ALCcontext_DeferUpdates(ALCcontext *context)
1540 ALCdevice *device = context->Device;
1541 FPUCtl oldMode;
1543 SetMixerFPUMode(&oldMode);
1545 V0(device->Backend,lock)();
1546 if(!context->DeferUpdates)
1548 context->DeferUpdates = AL_TRUE;
1550 /* Make sure all pending updates are performed */
1551 UpdateContextSources(context);
1552 #define UPDATE_SLOT(iter) do { \
1553 if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1554 V((*iter)->EffectState,update)(device, *iter); \
1555 } while(0)
1556 VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1557 #undef UPDATE_SLOT
1559 V0(device->Backend,unlock)();
1561 RestoreFPUMode(&oldMode);
1564 /* ALCcontext_ProcessUpdates
1566 * Resumes update processing after being deferred.
1568 void ALCcontext_ProcessUpdates(ALCcontext *context)
1570 ALCdevice *device = context->Device;
1572 V0(device->Backend,lock)();
1573 if(context->DeferUpdates)
1575 ALsizei pos;
1577 context->DeferUpdates = AL_FALSE;
1579 LockUIntMapRead(&context->SourceMap);
1580 for(pos = 0;pos < context->SourceMap.size;pos++)
1582 ALsource *Source = context->SourceMap.array[pos].value;
1583 ALenum new_state;
1585 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1586 Source->Offset >= 0.0)
1588 WriteLock(&Source->queue_lock);
1589 ApplyOffset(Source);
1590 WriteUnlock(&Source->queue_lock);
1593 new_state = Source->new_state;
1594 Source->new_state = AL_NONE;
1595 if(new_state)
1596 SetSourceState(Source, context, new_state);
1598 UnlockUIntMapRead(&context->SourceMap);
1600 V0(device->Backend,unlock)();
1604 /* alcSetError
1606 * Stores the latest ALC device error
1608 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1610 if(TrapALCError)
1612 #ifdef _WIN32
1613 /* DebugBreak() will cause an exception if there is no debugger */
1614 if(IsDebuggerPresent())
1615 DebugBreak();
1616 #elif defined(SIGTRAP)
1617 raise(SIGTRAP);
1618 #endif
1621 if(device)
1622 ATOMIC_STORE(&device->LastError, errorCode);
1623 else
1624 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1628 /* UpdateClockBase
1630 * Updates the device's base clock time with however many samples have been
1631 * done. This is used so frequency changes on the device don't cause the time
1632 * to jump forward or back.
1634 static inline void UpdateClockBase(ALCdevice *device)
1636 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1637 device->SamplesDone = 0;
1640 /* UpdateDeviceParams
1642 * Updates device parameters according to the attribute list (caller is
1643 * responsible for holding the list lock).
1645 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1647 ALCcontext *context;
1648 enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1649 enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1650 enum DevFmtChannels oldChans;
1651 enum DevFmtType oldType;
1652 ALCuint oldFreq;
1653 FPUCtl oldMode;
1654 ALCsizei hrtf_id = -1;
1655 size_t size;
1657 // Check for attributes
1658 if(device->Type == Loopback)
1660 enum {
1661 GotFreq = 1<<0,
1662 GotChans = 1<<1,
1663 GotType = 1<<2,
1664 GotAll = GotFreq|GotChans|GotType
1666 ALCuint freq, numMono, numStereo, numSends;
1667 enum DevFmtChannels schans;
1668 enum DevFmtType stype;
1669 ALCuint attrIdx = 0;
1670 ALCint gotFmt = 0;
1672 if(!attrList)
1674 WARN("Missing attributes for loopback device\n");
1675 return ALC_INVALID_VALUE;
1678 numMono = device->NumMonoSources;
1679 numStereo = device->NumStereoSources;
1680 numSends = device->NumAuxSends;
1681 schans = device->FmtChans;
1682 stype = device->FmtType;
1683 freq = device->Frequency;
1685 #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v)
1686 while(attrList[attrIdx])
1688 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1690 ALCint val = attrList[attrIdx + 1];
1691 TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, val);
1692 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1693 return ALC_INVALID_VALUE;
1694 schans = val;
1695 gotFmt |= GotChans;
1698 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1700 ALCint val = attrList[attrIdx + 1];
1701 TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, val);
1702 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1703 return ALC_INVALID_VALUE;
1704 stype = val;
1705 gotFmt |= GotType;
1708 if(attrList[attrIdx] == ALC_FREQUENCY)
1710 freq = attrList[attrIdx + 1];
1711 TRACE_ATTR(ALC_FREQUENCY, freq);
1712 if(freq < MIN_OUTPUT_RATE)
1713 return ALC_INVALID_VALUE;
1714 gotFmt |= GotFreq;
1717 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1719 numStereo = attrList[attrIdx + 1];
1720 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1721 if(numStereo > device->MaxNoOfSources)
1722 numStereo = device->MaxNoOfSources;
1724 numMono = device->MaxNoOfSources - numStereo;
1727 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1729 numSends = attrList[attrIdx + 1];
1730 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1733 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1735 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1736 if(attrList[attrIdx + 1] == ALC_FALSE)
1737 hrtf_appreq = Hrtf_Disable;
1738 else if(attrList[attrIdx + 1] == ALC_TRUE)
1739 hrtf_appreq = Hrtf_Enable;
1740 else
1741 hrtf_appreq = Hrtf_Default;
1744 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1746 hrtf_id = attrList[attrIdx + 1];
1747 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1750 attrIdx += 2;
1752 #undef TRACE_ATTR
1754 if(gotFmt != GotAll)
1756 WARN("Missing format for loopback device\n");
1757 return ALC_INVALID_VALUE;
1760 ConfigValueUInt(NULL, NULL, "sends", &numSends);
1761 numSends = minu(MAX_SENDS, numSends);
1763 if((device->Flags&DEVICE_RUNNING))
1764 V0(device->Backend,stop)();
1765 device->Flags &= ~DEVICE_RUNNING;
1767 UpdateClockBase(device);
1769 device->Frequency = freq;
1770 device->FmtChans = schans;
1771 device->FmtType = stype;
1772 device->NumMonoSources = numMono;
1773 device->NumStereoSources = numStereo;
1774 device->NumAuxSends = numSends;
1776 else if(attrList && attrList[0])
1778 ALCuint freq, numMono, numStereo, numSends;
1779 ALCuint attrIdx = 0;
1781 /* If a context is already running on the device, stop playback so the
1782 * device attributes can be updated. */
1783 if((device->Flags&DEVICE_RUNNING))
1784 V0(device->Backend,stop)();
1785 device->Flags &= ~DEVICE_RUNNING;
1787 freq = device->Frequency;
1788 numMono = device->NumMonoSources;
1789 numStereo = device->NumStereoSources;
1790 numSends = device->NumAuxSends;
1792 #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v)
1793 while(attrList[attrIdx])
1795 if(attrList[attrIdx] == ALC_FREQUENCY)
1797 freq = attrList[attrIdx + 1];
1798 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1799 TRACE_ATTR(ALC_FREQUENCY, freq);
1802 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1804 numStereo = attrList[attrIdx + 1];
1805 TRACE_ATTR(ALC_STEREO_SOURCES, numStereo);
1806 if(numStereo > device->MaxNoOfSources)
1807 numStereo = device->MaxNoOfSources;
1809 numMono = device->MaxNoOfSources - numStereo;
1812 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1814 numSends = attrList[attrIdx + 1];
1815 TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends);
1818 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1820 TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]);
1821 if(attrList[attrIdx + 1] == ALC_FALSE)
1822 hrtf_appreq = Hrtf_Disable;
1823 else if(attrList[attrIdx + 1] == ALC_TRUE)
1824 hrtf_appreq = Hrtf_Enable;
1825 else
1826 hrtf_appreq = Hrtf_Default;
1829 if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1831 hrtf_id = attrList[attrIdx + 1];
1832 TRACE_ATTR(ALC_HRTF_ID_SOFT, hrtf_id);
1835 attrIdx += 2;
1837 #undef TRACE_ATTR
1839 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1840 freq = maxu(freq, MIN_OUTPUT_RATE);
1842 ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1843 numSends = minu(MAX_SENDS, numSends);
1845 UpdateClockBase(device);
1847 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1848 device->Frequency;
1849 /* SSE and Neon do best with the update size being a multiple of 4 */
1850 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1851 device->UpdateSize = (device->UpdateSize+3)&~3;
1853 device->Frequency = freq;
1854 device->NumMonoSources = numMono;
1855 device->NumStereoSources = numStereo;
1856 device->NumAuxSends = numSends;
1859 if((device->Flags&DEVICE_RUNNING))
1860 return ALC_NO_ERROR;
1862 al_free(device->Uhj_Encoder);
1863 device->Uhj_Encoder = NULL;
1865 al_free(device->Bs2b);
1866 device->Bs2b = NULL;
1868 al_free(device->Dry.Buffer);
1869 device->Dry.Buffer = NULL;
1870 device->Dry.NumChannels = 0;
1871 device->VirtOut.Buffer = NULL;
1872 device->VirtOut.NumChannels = 0;
1873 device->RealOut.Buffer = NULL;
1874 device->RealOut.NumChannels = 0;
1876 UpdateClockBase(device);
1878 /*************************************************************************
1879 * Update device format request if HRTF is requested
1881 device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1882 if(device->Type != Loopback)
1884 const char *hrtf;
1885 if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1887 if(strcasecmp(hrtf, "true") == 0)
1888 hrtf_userreq = Hrtf_Enable;
1889 else if(strcasecmp(hrtf, "false") == 0)
1890 hrtf_userreq = Hrtf_Disable;
1891 else if(strcasecmp(hrtf, "auto") != 0)
1892 ERR("Unexpected hrtf value: %s\n", hrtf);
1895 if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1897 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1899 VECTOR_DEINIT(device->Hrtf_List);
1900 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1902 if(VECTOR_SIZE(device->Hrtf_List) > 0)
1904 device->FmtChans = DevFmtStereo;
1905 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1906 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1907 else
1908 device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1909 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1911 else
1913 hrtf_userreq = Hrtf_Default;
1914 hrtf_appreq = Hrtf_Disable;
1915 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1919 else if(hrtf_appreq == Hrtf_Enable)
1921 size_t i = VECTOR_SIZE(device->Hrtf_List);
1922 /* Loopback device. We don't need to match to a specific HRTF entry
1923 * here. If the requested ID matches, we'll pick that later, if not,
1924 * we'll try to auto-select one anyway. Just make sure one exists
1925 * that'll work.
1927 if(device->FmtChans == DevFmtStereo)
1929 if(VECTOR_SIZE(device->Hrtf_List) == 0)
1931 VECTOR_DEINIT(device->Hrtf_List);
1932 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1934 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1936 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1937 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1938 break;
1941 if(i == VECTOR_SIZE(device->Hrtf_List))
1943 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1944 DevFmtChannelsString(device->FmtChans), device->Frequency);
1945 hrtf_appreq = Hrtf_Disable;
1946 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1950 oldFreq = device->Frequency;
1951 oldChans = device->FmtChans;
1952 oldType = device->FmtType;
1954 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1955 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1956 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1957 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1958 device->UpdateSize, device->NumUpdates
1961 if(V0(device->Backend,reset)() == ALC_FALSE)
1962 return ALC_INVALID_DEVICE;
1964 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1966 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1967 DevFmtChannelsString(device->FmtChans));
1968 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1970 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1972 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1973 DevFmtTypeString(device->FmtType));
1974 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1976 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1978 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1979 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1982 if((device->UpdateSize&3) != 0)
1984 if((CPUCapFlags&CPU_CAP_SSE))
1985 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1986 if((CPUCapFlags&CPU_CAP_NEON))
1987 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1990 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1991 DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1992 device->Frequency, device->UpdateSize, device->NumUpdates
1995 aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
1997 /* Allocate extra channels for any post-filter output. */
1998 size = device->Dry.NumChannels * sizeof(device->Dry.Buffer[0]);
1999 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2000 size += (ChannelsFromDevFmt(device->FmtChans)+4) * sizeof(device->Dry.Buffer[0]);
2001 else if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2002 size += ChannelsFromDevFmt(device->FmtChans) * sizeof(device->Dry.Buffer[0]);
2003 device->Dry.Buffer = al_calloc(16, size);
2004 if(!device->Dry.Buffer)
2006 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2007 return ALC_INVALID_DEVICE;
2010 if(device->Hrtf || device->Uhj_Encoder || device->AmbiDecoder)
2012 device->VirtOut.Buffer = device->Dry.Buffer;
2013 device->VirtOut.NumChannels = device->Dry.NumChannels;
2014 device->RealOut.Buffer = device->Dry.Buffer + device->Dry.NumChannels;
2015 device->RealOut.NumChannels = ChannelsFromDevFmt(device->FmtChans);
2017 else
2019 device->VirtOut.Buffer = NULL;
2020 device->VirtOut.NumChannels = 0;
2021 device->RealOut.Buffer = device->Dry.Buffer;
2022 device->RealOut.NumChannels = device->Dry.NumChannels;
2025 if(device->AmbiDecoder && bformatdec_getOrder(device->AmbiDecoder) >= 2)
2027 /* Higher-order high quality decoding requires upsampling first-order
2028 * content, so make sure to mix it separately.
2030 device->FOAOut.Buffer = device->RealOut.Buffer + device->RealOut.NumChannels;
2031 device->FOAOut.NumChannels = 4;
2033 else
2035 device->FOAOut.Buffer = device->Dry.Buffer;
2036 device->FOAOut.NumChannels = device->Dry.NumChannels;
2039 SetMixerFPUMode(&oldMode);
2040 V0(device->Backend,lock)();
2041 context = ATOMIC_LOAD(&device->ContextList);
2042 while(context)
2044 ALsizei pos;
2046 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2047 LockUIntMapRead(&context->EffectSlotMap);
2048 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2050 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2052 slot->EffectState->OutBuffer = device->Dry.Buffer;
2053 slot->EffectState->OutChannels = device->Dry.NumChannels;
2054 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2056 UnlockUIntMapRead(&context->EffectSlotMap);
2057 V0(device->Backend,unlock)();
2058 RestoreFPUMode(&oldMode);
2059 return ALC_INVALID_DEVICE;
2061 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2062 V(slot->EffectState,update)(device, slot);
2064 UnlockUIntMapRead(&context->EffectSlotMap);
2066 LockUIntMapRead(&context->SourceMap);
2067 for(pos = 0;pos < context->SourceMap.size;pos++)
2069 ALsource *source = context->SourceMap.array[pos].value;
2070 ALuint s = device->NumAuxSends;
2071 while(s < MAX_SENDS)
2073 if(source->Send[s].Slot)
2074 DecrementRef(&source->Send[s].Slot->ref);
2075 source->Send[s].Slot = NULL;
2076 source->Send[s].Gain = 1.0f;
2077 source->Send[s].GainHF = 1.0f;
2078 s++;
2080 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2082 UnlockUIntMapRead(&context->SourceMap);
2084 for(pos = 0;pos < context->VoiceCount;pos++)
2086 ALvoice *voice = &context->Voices[pos];
2087 ALsource *source = voice->Source;
2089 if(source)
2091 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2092 voice->Update(voice, source, context);
2096 context = context->next;
2098 if(device->DefaultSlot)
2100 ALeffectslot *slot = device->DefaultSlot;
2101 ALeffectState *state = slot->EffectState;
2103 state->OutBuffer = device->Dry.Buffer;
2104 state->OutChannels = device->Dry.NumChannels;
2105 if(V(state,deviceUpdate)(device) == AL_FALSE)
2107 V0(device->Backend,unlock)();
2108 RestoreFPUMode(&oldMode);
2109 return ALC_INVALID_DEVICE;
2111 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2112 V(slot->EffectState,update)(device, slot);
2114 V0(device->Backend,unlock)();
2115 RestoreFPUMode(&oldMode);
2117 if(!(device->Flags&DEVICE_PAUSED))
2119 if(V0(device->Backend,start)() == ALC_FALSE)
2120 return ALC_INVALID_DEVICE;
2121 device->Flags |= DEVICE_RUNNING;
2124 return ALC_NO_ERROR;
2127 /* FreeDevice
2129 * Frees the device structure, and destroys any objects the app failed to
2130 * delete. Called once there's no more references on the device.
2132 static ALCvoid FreeDevice(ALCdevice *device)
2134 TRACE("%p\n", device);
2136 V0(device->Backend,close)();
2137 DELETE_OBJ(device->Backend);
2138 device->Backend = NULL;
2140 if(device->DefaultSlot)
2142 ALeffectState *state = device->DefaultSlot->EffectState;
2143 device->DefaultSlot = NULL;
2144 DELETE_OBJ(state);
2147 if(device->BufferMap.size > 0)
2149 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2150 ReleaseALBuffers(device);
2152 ResetUIntMap(&device->BufferMap);
2154 if(device->EffectMap.size > 0)
2156 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2157 ReleaseALEffects(device);
2159 ResetUIntMap(&device->EffectMap);
2161 if(device->FilterMap.size > 0)
2163 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2164 ReleaseALFilters(device);
2166 ResetUIntMap(&device->FilterMap);
2168 AL_STRING_DEINIT(device->Hrtf_Name);
2169 FreeHrtfList(&device->Hrtf_List);
2171 al_free(device->Bs2b);
2172 device->Bs2b = NULL;
2174 al_free(device->Uhj_Encoder);
2175 device->Uhj_Encoder = NULL;
2177 bformatdec_free(device->AmbiDecoder);
2178 device->AmbiDecoder = NULL;
2180 AL_STRING_DEINIT(device->DeviceName);
2182 al_free(device->Dry.Buffer);
2183 device->Dry.Buffer = NULL;
2184 device->Dry.NumChannels = 0;
2185 device->VirtOut.Buffer = NULL;
2186 device->VirtOut.NumChannels = 0;
2187 device->RealOut.Buffer = NULL;
2188 device->RealOut.NumChannels = 0;
2190 al_free(device);
2194 void ALCdevice_IncRef(ALCdevice *device)
2196 uint ref;
2197 ref = IncrementRef(&device->ref);
2198 TRACEREF("%p increasing refcount to %u\n", device, ref);
2201 void ALCdevice_DecRef(ALCdevice *device)
2203 uint ref;
2204 ref = DecrementRef(&device->ref);
2205 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2206 if(ref == 0) FreeDevice(device);
2209 /* VerifyDevice
2211 * Checks if the device handle is valid, and increments its ref count if so.
2213 static ALCboolean VerifyDevice(ALCdevice **device)
2215 ALCdevice *tmpDevice;
2217 LockLists();
2218 tmpDevice = ATOMIC_LOAD(&DeviceList);
2219 while(tmpDevice)
2221 if(tmpDevice == *device)
2223 ALCdevice_IncRef(tmpDevice);
2224 UnlockLists();
2225 return ALC_TRUE;
2227 tmpDevice = tmpDevice->next;
2229 UnlockLists();
2231 *device = NULL;
2232 return ALC_FALSE;
2236 /* InitContext
2238 * Initializes context fields
2240 static ALvoid InitContext(ALCcontext *Context)
2242 ALlistener *listener = Context->Listener;
2243 //Initialise listener
2244 listener->Gain = 1.0f;
2245 listener->MetersPerUnit = 1.0f;
2246 aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2247 aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2248 listener->Forward[0] = 0.0f;
2249 listener->Forward[1] = 0.0f;
2250 listener->Forward[2] = -1.0f;
2251 listener->Up[0] = 0.0f;
2252 listener->Up[1] = 1.0f;
2253 listener->Up[2] = 0.0f;
2254 aluMatrixdSet(&listener->Params.Matrix,
2255 1.0, 0.0, 0.0, 0.0,
2256 0.0, 1.0, 0.0, 0.0,
2257 0.0, 0.0, 1.0, 0.0,
2258 0.0, 0.0, 0.0, 1.0
2260 aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2262 //Validate Context
2263 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2264 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2265 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2266 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2268 //Set globals
2269 Context->DistanceModel = DefaultDistanceModel;
2270 Context->SourceDistanceModel = AL_FALSE;
2271 Context->DopplerFactor = 1.0f;
2272 Context->DopplerVelocity = 1.0f;
2273 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2274 Context->DeferUpdates = AL_FALSE;
2276 Context->ExtensionList = alExtList;
2280 /* FreeContext
2282 * Cleans up the context, and destroys any remaining objects the app failed to
2283 * delete. Called once there's no more references on the context.
2285 static void FreeContext(ALCcontext *context)
2287 TRACE("%p\n", context);
2289 if(context->SourceMap.size > 0)
2291 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2292 ReleaseALSources(context);
2294 ResetUIntMap(&context->SourceMap);
2296 if(context->EffectSlotMap.size > 0)
2298 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2299 ReleaseALAuxiliaryEffectSlots(context);
2301 ResetUIntMap(&context->EffectSlotMap);
2303 al_free(context->Voices);
2304 context->Voices = NULL;
2305 context->VoiceCount = 0;
2306 context->MaxVoices = 0;
2308 VECTOR_DEINIT(context->ActiveAuxSlots);
2310 ALCdevice_DecRef(context->Device);
2311 context->Device = NULL;
2313 //Invalidate context
2314 memset(context, 0, sizeof(ALCcontext));
2315 al_free(context);
2318 /* ReleaseContext
2320 * Removes the context reference from the given device and removes it from
2321 * being current on the running thread or globally.
2323 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2325 ALCcontext *nextctx;
2326 ALCcontext *origctx;
2328 if(altss_get(LocalContext) == context)
2330 WARN("%p released while current on thread\n", context);
2331 altss_set(LocalContext, NULL);
2332 ALCcontext_DecRef(context);
2335 origctx = context;
2336 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2337 ALCcontext_DecRef(context);
2339 ALCdevice_Lock(device);
2340 origctx = context;
2341 nextctx = context->next;
2342 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2344 ALCcontext *list;
2345 do {
2346 list = origctx;
2347 origctx = context;
2348 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2350 ALCdevice_Unlock(device);
2352 ALCcontext_DecRef(context);
2355 void ALCcontext_IncRef(ALCcontext *context)
2357 uint ref;
2358 ref = IncrementRef(&context->ref);
2359 TRACEREF("%p increasing refcount to %u\n", context, ref);
2362 void ALCcontext_DecRef(ALCcontext *context)
2364 uint ref;
2365 ref = DecrementRef(&context->ref);
2366 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2367 if(ref == 0) FreeContext(context);
2370 static void ReleaseThreadCtx(void *ptr)
2372 WARN("%p current for thread being destroyed\n", ptr);
2373 ALCcontext_DecRef(ptr);
2376 /* VerifyContext
2378 * Checks that the given context is valid, and increments its reference count.
2380 static ALCboolean VerifyContext(ALCcontext **context)
2382 ALCdevice *dev;
2384 LockLists();
2385 dev = ATOMIC_LOAD(&DeviceList);
2386 while(dev)
2388 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2389 while(ctx)
2391 if(ctx == *context)
2393 ALCcontext_IncRef(ctx);
2394 UnlockLists();
2395 return ALC_TRUE;
2397 ctx = ctx->next;
2399 dev = dev->next;
2401 UnlockLists();
2403 *context = NULL;
2404 return ALC_FALSE;
2408 /* GetContextRef
2410 * Returns the currently active context for this thread, and adds a reference
2411 * without locking it.
2413 ALCcontext *GetContextRef(void)
2415 ALCcontext *context;
2417 context = altss_get(LocalContext);
2418 if(context)
2419 ALCcontext_IncRef(context);
2420 else
2422 LockLists();
2423 context = ATOMIC_LOAD(&GlobalContext);
2424 if(context)
2425 ALCcontext_IncRef(context);
2426 UnlockLists();
2429 return context;
2433 /************************************************
2434 * Standard ALC functions
2435 ************************************************/
2437 /* alcGetError
2439 * Return last ALC generated error code for the given device
2441 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2443 ALCenum errorCode;
2445 if(VerifyDevice(&device))
2447 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2448 ALCdevice_DecRef(device);
2450 else
2451 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2453 return errorCode;
2457 /* alcSuspendContext
2459 * Suspends updates for the given context
2461 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2463 if(!SuspendDefers)
2464 return;
2466 if(!VerifyContext(&context))
2467 alcSetError(NULL, ALC_INVALID_CONTEXT);
2468 else
2470 ALCcontext_DeferUpdates(context);
2471 ALCcontext_DecRef(context);
2475 /* alcProcessContext
2477 * Resumes processing updates for the given context
2479 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2481 if(!SuspendDefers)
2482 return;
2484 if(!VerifyContext(&context))
2485 alcSetError(NULL, ALC_INVALID_CONTEXT);
2486 else
2488 ALCcontext_ProcessUpdates(context);
2489 ALCcontext_DecRef(context);
2494 /* alcGetString
2496 * Returns information about the device, and error strings
2498 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2500 const ALCchar *value = NULL;
2502 switch(param)
2504 case ALC_NO_ERROR:
2505 value = alcNoError;
2506 break;
2508 case ALC_INVALID_ENUM:
2509 value = alcErrInvalidEnum;
2510 break;
2512 case ALC_INVALID_VALUE:
2513 value = alcErrInvalidValue;
2514 break;
2516 case ALC_INVALID_DEVICE:
2517 value = alcErrInvalidDevice;
2518 break;
2520 case ALC_INVALID_CONTEXT:
2521 value = alcErrInvalidContext;
2522 break;
2524 case ALC_OUT_OF_MEMORY:
2525 value = alcErrOutOfMemory;
2526 break;
2528 case ALC_DEVICE_SPECIFIER:
2529 value = alcDefaultName;
2530 break;
2532 case ALC_ALL_DEVICES_SPECIFIER:
2533 if(VerifyDevice(&Device))
2535 value = al_string_get_cstr(Device->DeviceName);
2536 ALCdevice_DecRef(Device);
2538 else
2540 ProbeAllDevicesList();
2541 value = al_string_get_cstr(alcAllDevicesList);
2543 break;
2545 case ALC_CAPTURE_DEVICE_SPECIFIER:
2546 if(VerifyDevice(&Device))
2548 value = al_string_get_cstr(Device->DeviceName);
2549 ALCdevice_DecRef(Device);
2551 else
2553 ProbeCaptureDeviceList();
2554 value = al_string_get_cstr(alcCaptureDeviceList);
2556 break;
2558 /* Default devices are always first in the list */
2559 case ALC_DEFAULT_DEVICE_SPECIFIER:
2560 value = alcDefaultName;
2561 break;
2563 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2564 if(al_string_empty(alcAllDevicesList))
2565 ProbeAllDevicesList();
2567 VerifyDevice(&Device);
2569 free(alcDefaultAllDevicesSpecifier);
2570 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2571 if(!alcDefaultAllDevicesSpecifier)
2572 alcSetError(Device, ALC_OUT_OF_MEMORY);
2574 value = alcDefaultAllDevicesSpecifier;
2575 if(Device) ALCdevice_DecRef(Device);
2576 break;
2578 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2579 if(al_string_empty(alcCaptureDeviceList))
2580 ProbeCaptureDeviceList();
2582 VerifyDevice(&Device);
2584 free(alcCaptureDefaultDeviceSpecifier);
2585 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2586 if(!alcCaptureDefaultDeviceSpecifier)
2587 alcSetError(Device, ALC_OUT_OF_MEMORY);
2589 value = alcCaptureDefaultDeviceSpecifier;
2590 if(Device) ALCdevice_DecRef(Device);
2591 break;
2593 case ALC_EXTENSIONS:
2594 if(!VerifyDevice(&Device))
2595 value = alcNoDeviceExtList;
2596 else
2598 value = alcExtensionList;
2599 ALCdevice_DecRef(Device);
2601 break;
2603 case ALC_HRTF_SPECIFIER_SOFT:
2604 if(!VerifyDevice(&Device))
2605 alcSetError(NULL, ALC_INVALID_DEVICE);
2606 else
2608 LockLists();
2609 value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2610 UnlockLists();
2611 ALCdevice_DecRef(Device);
2613 break;
2615 default:
2616 VerifyDevice(&Device);
2617 alcSetError(Device, ALC_INVALID_ENUM);
2618 if(Device) ALCdevice_DecRef(Device);
2619 break;
2622 return value;
2626 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2628 ALCsizei i;
2630 if(size <= 0 || values == NULL)
2632 alcSetError(device, ALC_INVALID_VALUE);
2633 return 0;
2636 if(!device)
2638 switch(param)
2640 case ALC_MAJOR_VERSION:
2641 values[0] = alcMajorVersion;
2642 return 1;
2643 case ALC_MINOR_VERSION:
2644 values[0] = alcMinorVersion;
2645 return 1;
2647 case ALC_ATTRIBUTES_SIZE:
2648 case ALC_ALL_ATTRIBUTES:
2649 case ALC_FREQUENCY:
2650 case ALC_REFRESH:
2651 case ALC_SYNC:
2652 case ALC_MONO_SOURCES:
2653 case ALC_STEREO_SOURCES:
2654 case ALC_CAPTURE_SAMPLES:
2655 case ALC_FORMAT_CHANNELS_SOFT:
2656 case ALC_FORMAT_TYPE_SOFT:
2657 alcSetError(NULL, ALC_INVALID_DEVICE);
2658 return 0;
2660 default:
2661 alcSetError(NULL, ALC_INVALID_ENUM);
2662 return 0;
2664 return 0;
2667 if(device->Type == Capture)
2669 switch(param)
2671 case ALC_CAPTURE_SAMPLES:
2672 V0(device->Backend,lock)();
2673 values[0] = V0(device->Backend,availableSamples)();
2674 V0(device->Backend,unlock)();
2675 return 1;
2677 case ALC_CONNECTED:
2678 values[0] = device->Connected;
2679 return 1;
2681 default:
2682 alcSetError(device, ALC_INVALID_ENUM);
2683 return 0;
2685 return 0;
2688 /* render device */
2689 switch(param)
2691 case ALC_MAJOR_VERSION:
2692 values[0] = alcMajorVersion;
2693 return 1;
2695 case ALC_MINOR_VERSION:
2696 values[0] = alcMinorVersion;
2697 return 1;
2699 case ALC_EFX_MAJOR_VERSION:
2700 values[0] = alcEFXMajorVersion;
2701 return 1;
2703 case ALC_EFX_MINOR_VERSION:
2704 values[0] = alcEFXMinorVersion;
2705 return 1;
2707 case ALC_ATTRIBUTES_SIZE:
2708 values[0] = 17;
2709 return 1;
2711 case ALC_ALL_ATTRIBUTES:
2712 if(size < 17)
2714 alcSetError(device, ALC_INVALID_VALUE);
2715 return 0;
2718 i = 0;
2719 values[i++] = ALC_FREQUENCY;
2720 values[i++] = device->Frequency;
2722 if(device->Type != Loopback)
2724 values[i++] = ALC_REFRESH;
2725 values[i++] = device->Frequency / device->UpdateSize;
2727 values[i++] = ALC_SYNC;
2728 values[i++] = ALC_FALSE;
2730 else
2732 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2733 values[i++] = device->FmtChans;
2735 values[i++] = ALC_FORMAT_TYPE_SOFT;
2736 values[i++] = device->FmtType;
2739 values[i++] = ALC_MONO_SOURCES;
2740 values[i++] = device->NumMonoSources;
2742 values[i++] = ALC_STEREO_SOURCES;
2743 values[i++] = device->NumStereoSources;
2745 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2746 values[i++] = device->NumAuxSends;
2748 values[i++] = ALC_HRTF_SOFT;
2749 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2751 values[i++] = ALC_HRTF_STATUS_SOFT;
2752 values[i++] = device->Hrtf_Status;
2754 values[i++] = 0;
2755 return i;
2757 case ALC_FREQUENCY:
2758 values[0] = device->Frequency;
2759 return 1;
2761 case ALC_REFRESH:
2762 if(device->Type == Loopback)
2764 alcSetError(device, ALC_INVALID_DEVICE);
2765 return 0;
2767 values[0] = device->Frequency / device->UpdateSize;
2768 return 1;
2770 case ALC_SYNC:
2771 if(device->Type == Loopback)
2773 alcSetError(device, ALC_INVALID_DEVICE);
2774 return 0;
2776 values[0] = ALC_FALSE;
2777 return 1;
2779 case ALC_FORMAT_CHANNELS_SOFT:
2780 if(device->Type != Loopback)
2782 alcSetError(device, ALC_INVALID_DEVICE);
2783 return 0;
2785 values[0] = device->FmtChans;
2786 return 1;
2788 case ALC_FORMAT_TYPE_SOFT:
2789 if(device->Type != Loopback)
2791 alcSetError(device, ALC_INVALID_DEVICE);
2792 return 0;
2794 values[0] = device->FmtType;
2795 return 1;
2797 case ALC_MONO_SOURCES:
2798 values[0] = device->NumMonoSources;
2799 return 1;
2801 case ALC_STEREO_SOURCES:
2802 values[0] = device->NumStereoSources;
2803 return 1;
2805 case ALC_MAX_AUXILIARY_SENDS:
2806 values[0] = device->NumAuxSends;
2807 return 1;
2809 case ALC_CONNECTED:
2810 values[0] = device->Connected;
2811 return 1;
2813 case ALC_HRTF_SOFT:
2814 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2815 return 1;
2817 case ALC_HRTF_STATUS_SOFT:
2818 values[0] = device->Hrtf_Status;
2819 return 1;
2821 case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2822 FreeHrtfList(&device->Hrtf_List);
2823 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2824 values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2825 return 1;
2827 default:
2828 alcSetError(device, ALC_INVALID_ENUM);
2829 return 0;
2831 return 0;
2834 /* alcGetIntegerv
2836 * Returns information about the device and the version of OpenAL
2838 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2840 VerifyDevice(&device);
2841 if(size <= 0 || values == NULL)
2842 alcSetError(device, ALC_INVALID_VALUE);
2843 else
2844 GetIntegerv(device, param, size, values);
2845 if(device) ALCdevice_DecRef(device);
2848 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2850 ALCint *ivals;
2851 ALsizei i;
2853 VerifyDevice(&device);
2854 if(size <= 0 || values == NULL)
2855 alcSetError(device, ALC_INVALID_VALUE);
2856 else if(!device || device->Type == Capture)
2858 ivals = malloc(size * sizeof(ALCint));
2859 size = GetIntegerv(device, pname, size, ivals);
2860 for(i = 0;i < size;i++)
2861 values[i] = ivals[i];
2862 free(ivals);
2864 else /* render device */
2866 switch(pname)
2868 case ALC_ATTRIBUTES_SIZE:
2869 *values = 19;
2870 break;
2872 case ALC_ALL_ATTRIBUTES:
2873 if(size < 19)
2874 alcSetError(device, ALC_INVALID_VALUE);
2875 else
2877 int i = 0;
2879 V0(device->Backend,lock)();
2880 values[i++] = ALC_FREQUENCY;
2881 values[i++] = device->Frequency;
2883 if(device->Type != Loopback)
2885 values[i++] = ALC_REFRESH;
2886 values[i++] = device->Frequency / device->UpdateSize;
2888 values[i++] = ALC_SYNC;
2889 values[i++] = ALC_FALSE;
2891 else
2893 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2894 values[i++] = device->FmtChans;
2896 values[i++] = ALC_FORMAT_TYPE_SOFT;
2897 values[i++] = device->FmtType;
2900 values[i++] = ALC_MONO_SOURCES;
2901 values[i++] = device->NumMonoSources;
2903 values[i++] = ALC_STEREO_SOURCES;
2904 values[i++] = device->NumStereoSources;
2906 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2907 values[i++] = device->NumAuxSends;
2909 values[i++] = ALC_HRTF_SOFT;
2910 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2912 values[i++] = ALC_HRTF_STATUS_SOFT;
2913 values[i++] = device->Hrtf_Status;
2915 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2916 values[i++] = device->ClockBase +
2917 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2919 values[i++] = 0;
2920 V0(device->Backend,unlock)();
2922 break;
2924 case ALC_DEVICE_CLOCK_SOFT:
2925 V0(device->Backend,lock)();
2926 *values = device->ClockBase +
2927 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2928 V0(device->Backend,unlock)();
2929 break;
2931 default:
2932 ivals = malloc(size * sizeof(ALCint));
2933 size = GetIntegerv(device, pname, size, ivals);
2934 for(i = 0;i < size;i++)
2935 values[i] = ivals[i];
2936 free(ivals);
2937 break;
2940 if(device)
2941 ALCdevice_DecRef(device);
2945 /* alcIsExtensionPresent
2947 * Determines if there is support for a particular extension
2949 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2951 ALCboolean bResult = ALC_FALSE;
2953 VerifyDevice(&device);
2955 if(!extName)
2956 alcSetError(device, ALC_INVALID_VALUE);
2957 else
2959 size_t len = strlen(extName);
2960 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2961 while(ptr && *ptr)
2963 if(strncasecmp(ptr, extName, len) == 0 &&
2964 (ptr[len] == '\0' || isspace(ptr[len])))
2966 bResult = ALC_TRUE;
2967 break;
2969 if((ptr=strchr(ptr, ' ')) != NULL)
2971 do {
2972 ++ptr;
2973 } while(isspace(*ptr));
2977 if(device)
2978 ALCdevice_DecRef(device);
2979 return bResult;
2983 /* alcGetProcAddress
2985 * Retrieves the function address for a particular extension function
2987 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2989 ALCvoid *ptr = NULL;
2991 if(!funcName)
2993 VerifyDevice(&device);
2994 alcSetError(device, ALC_INVALID_VALUE);
2995 if(device) ALCdevice_DecRef(device);
2997 else
2999 ALsizei i = 0;
3000 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3001 i++;
3002 ptr = alcFunctions[i].address;
3005 return ptr;
3009 /* alcGetEnumValue
3011 * Get the value for a particular ALC enumeration name
3013 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3015 ALCenum val = 0;
3017 if(!enumName)
3019 VerifyDevice(&device);
3020 alcSetError(device, ALC_INVALID_VALUE);
3021 if(device) ALCdevice_DecRef(device);
3023 else
3025 ALsizei i = 0;
3026 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3027 i++;
3028 val = enumeration[i].value;
3031 return val;
3035 /* alcCreateContext
3037 * Create and attach a context to the given device.
3039 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3041 ALCcontext *ALContext;
3042 ALCenum err;
3044 LockLists();
3045 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3047 UnlockLists();
3048 alcSetError(device, ALC_INVALID_DEVICE);
3049 if(device) ALCdevice_DecRef(device);
3050 return NULL;
3053 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3055 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3057 UnlockLists();
3058 alcSetError(device, err);
3059 if(err == ALC_INVALID_DEVICE)
3061 V0(device->Backend,lock)();
3062 aluHandleDisconnect(device);
3063 V0(device->Backend,unlock)();
3065 ALCdevice_DecRef(device);
3066 return NULL;
3069 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3070 if(ALContext)
3072 InitRef(&ALContext->ref, 1);
3073 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3075 VECTOR_INIT(ALContext->ActiveAuxSlots);
3077 ALContext->VoiceCount = 0;
3078 ALContext->MaxVoices = 256;
3079 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3081 if(!ALContext || !ALContext->Voices)
3083 if(!ATOMIC_LOAD(&device->ContextList))
3085 V0(device->Backend,stop)();
3086 device->Flags &= ~DEVICE_RUNNING;
3088 UnlockLists();
3090 if(ALContext)
3092 al_free(ALContext->Voices);
3093 ALContext->Voices = NULL;
3095 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3097 al_free(ALContext);
3098 ALContext = NULL;
3101 alcSetError(device, ALC_OUT_OF_MEMORY);
3102 ALCdevice_DecRef(device);
3103 return NULL;
3106 ALContext->Device = device;
3107 ALCdevice_IncRef(device);
3108 InitContext(ALContext);
3111 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3112 do {
3113 ALContext->next = head;
3114 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3116 UnlockLists();
3118 ALCdevice_DecRef(device);
3120 TRACE("Created context %p\n", ALContext);
3121 return ALContext;
3124 /* alcDestroyContext
3126 * Remove a context from its device
3128 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3130 ALCdevice *Device;
3132 LockLists();
3133 /* alcGetContextsDevice sets an error for invalid contexts */
3134 Device = alcGetContextsDevice(context);
3135 if(Device)
3137 ReleaseContext(context, Device);
3138 if(!ATOMIC_LOAD(&Device->ContextList))
3140 V0(Device->Backend,stop)();
3141 Device->Flags &= ~DEVICE_RUNNING;
3144 UnlockLists();
3148 /* alcGetCurrentContext
3150 * Returns the currently active context on the calling thread
3152 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3154 ALCcontext *Context = altss_get(LocalContext);
3155 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3156 return Context;
3159 /* alcGetThreadContext
3161 * Returns the currently active thread-local context
3163 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3165 return altss_get(LocalContext);
3169 /* alcMakeContextCurrent
3171 * Makes the given context the active process-wide context, and removes the
3172 * thread-local context for the calling thread.
3174 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3176 /* context must be valid or NULL */
3177 if(context && !VerifyContext(&context))
3179 alcSetError(NULL, ALC_INVALID_CONTEXT);
3180 return ALC_FALSE;
3182 /* context's reference count is already incremented */
3183 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3184 if(context) ALCcontext_DecRef(context);
3186 if((context=altss_get(LocalContext)) != NULL)
3188 altss_set(LocalContext, NULL);
3189 ALCcontext_DecRef(context);
3192 return ALC_TRUE;
3195 /* alcSetThreadContext
3197 * Makes the given context the active context for the current thread
3199 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3201 ALCcontext *old;
3203 /* context must be valid or NULL */
3204 if(context && !VerifyContext(&context))
3206 alcSetError(NULL, ALC_INVALID_CONTEXT);
3207 return ALC_FALSE;
3209 /* context's reference count is already incremented */
3210 old = altss_get(LocalContext);
3211 altss_set(LocalContext, context);
3212 if(old) ALCcontext_DecRef(old);
3214 return ALC_TRUE;
3218 /* alcGetContextsDevice
3220 * Returns the device that a particular context is attached to
3222 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3224 ALCdevice *Device;
3226 if(!VerifyContext(&Context))
3228 alcSetError(NULL, ALC_INVALID_CONTEXT);
3229 return NULL;
3231 Device = Context->Device;
3232 ALCcontext_DecRef(Context);
3234 return Device;
3238 /* alcOpenDevice
3240 * Opens the named device.
3242 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3244 const ALCchar *fmt;
3245 ALCdevice *device;
3246 ALCenum err;
3248 DO_INITCONFIG();
3250 if(!PlaybackBackend.name)
3252 alcSetError(NULL, ALC_INVALID_VALUE);
3253 return NULL;
3256 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3257 #ifdef _WIN32
3258 /* Some old Windows apps hardcode these expecting OpenAL to use a
3259 * specific audio API, even when they're not enumerated. Creative's
3260 * router effectively ignores them too.
3262 || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3263 || strcasecmp(deviceName, "MMSYSTEM") == 0
3264 #endif
3266 deviceName = NULL;
3268 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3269 if(!device)
3271 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3272 return NULL;
3275 //Validate device
3276 InitRef(&device->ref, 1);
3277 device->Connected = ALC_TRUE;
3278 device->Type = Playback;
3279 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3281 device->Flags = 0;
3282 device->Bs2b = NULL;
3283 device->Uhj_Encoder = NULL;
3284 VECTOR_INIT(device->Hrtf_List);
3285 AL_STRING_INIT(device->Hrtf_Name);
3286 device->Render_Mode = NormalRender;
3287 AL_STRING_INIT(device->DeviceName);
3288 device->Dry.Buffer = NULL;
3289 device->Dry.NumChannels = 0;
3290 device->VirtOut.Buffer = NULL;
3291 device->VirtOut.NumChannels = 0;
3292 device->RealOut.Buffer = NULL;
3293 device->RealOut.NumChannels = 0;
3295 ATOMIC_INIT(&device->ContextList, NULL);
3297 device->ClockBase = 0;
3298 device->SamplesDone = 0;
3300 device->MaxNoOfSources = 256;
3301 device->AuxiliaryEffectSlotMax = 4;
3302 device->NumAuxSends = MAX_SENDS;
3304 InitUIntMap(&device->BufferMap, ~0);
3305 InitUIntMap(&device->EffectMap, ~0);
3306 InitUIntMap(&device->FilterMap, ~0);
3308 //Set output format
3309 device->FmtChans = DevFmtChannelsDefault;
3310 device->FmtType = DevFmtTypeDefault;
3311 device->Frequency = DEFAULT_OUTPUT_RATE;
3312 device->IsHeadphones = AL_FALSE;
3313 device->NumUpdates = 4;
3314 device->UpdateSize = 1024;
3316 if(!PlaybackBackend.getFactory)
3317 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3318 ALCbackend_Playback);
3319 else
3321 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3322 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3324 if(!device->Backend)
3326 al_free(device);
3327 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3328 return NULL;
3332 if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3334 static const struct {
3335 const char name[16];
3336 enum DevFmtChannels chans;
3337 } chanlist[] = {
3338 { "mono", DevFmtMono },
3339 { "stereo", DevFmtStereo },
3340 { "quad", DevFmtQuad },
3341 { "surround51", DevFmtX51 },
3342 { "surround61", DevFmtX61 },
3343 { "surround71", DevFmtX71 },
3344 { "surround51rear", DevFmtX51Rear },
3346 size_t i;
3348 for(i = 0;i < COUNTOF(chanlist);i++)
3350 if(strcasecmp(chanlist[i].name, fmt) == 0)
3352 device->FmtChans = chanlist[i].chans;
3353 device->Flags |= DEVICE_CHANNELS_REQUEST;
3354 break;
3357 if(i == COUNTOF(chanlist))
3358 ERR("Unsupported channels: %s\n", fmt);
3360 if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3362 static const struct {
3363 const char name[16];
3364 enum DevFmtType type;
3365 } typelist[] = {
3366 { "int8", DevFmtByte },
3367 { "uint8", DevFmtUByte },
3368 { "int16", DevFmtShort },
3369 { "uint16", DevFmtUShort },
3370 { "int32", DevFmtInt },
3371 { "uint32", DevFmtUInt },
3372 { "float32", DevFmtFloat },
3374 size_t i;
3376 for(i = 0;i < COUNTOF(typelist);i++)
3378 if(strcasecmp(typelist[i].name, fmt) == 0)
3380 device->FmtType = typelist[i].type;
3381 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3382 break;
3385 if(i == COUNTOF(typelist))
3386 ERR("Unsupported sample-type: %s\n", fmt);
3389 if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3391 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3392 if(device->Frequency < MIN_OUTPUT_RATE)
3393 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3394 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3397 ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3398 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3400 ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3401 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3402 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3403 device->UpdateSize = (device->UpdateSize+3)&~3;
3405 ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3406 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3408 ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3409 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3411 ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3412 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3414 device->NumStereoSources = 1;
3415 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3417 // Find a playback device to open
3418 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3420 DELETE_OBJ(device->Backend);
3421 al_free(device);
3422 alcSetError(NULL, err);
3423 return NULL;
3426 if(DefaultEffect.type != AL_EFFECT_NULL)
3428 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3429 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3431 device->DefaultSlot = NULL;
3432 ERR("Failed to initialize the default effect slot\n");
3434 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3436 ALeffectState *state = device->DefaultSlot->EffectState;
3437 device->DefaultSlot = NULL;
3438 DELETE_OBJ(state);
3439 ERR("Failed to initialize the default effect\n");
3441 else
3442 aluInitEffectPanning(device->DefaultSlot);
3446 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3447 do {
3448 device->next = head;
3449 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3452 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3453 return device;
3456 /* alcCloseDevice
3458 * Closes the given device.
3460 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3462 ALCdevice *list, *origdev, *nextdev;
3463 ALCcontext *ctx;
3465 LockLists();
3466 list = ATOMIC_LOAD(&DeviceList);
3467 do {
3468 if(list == device)
3469 break;
3470 } while((list=list->next) != NULL);
3471 if(!list || list->Type == Capture)
3473 alcSetError(list, ALC_INVALID_DEVICE);
3474 UnlockLists();
3475 return ALC_FALSE;
3478 origdev = device;
3479 nextdev = device->next;
3480 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3482 do {
3483 list = origdev;
3484 origdev = device;
3485 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3487 UnlockLists();
3489 ctx = ATOMIC_LOAD(&device->ContextList);
3490 while(ctx != NULL)
3492 ALCcontext *next = ctx->next;
3493 WARN("Releasing context %p\n", ctx);
3494 ReleaseContext(ctx, device);
3495 ctx = next;
3497 if((device->Flags&DEVICE_RUNNING))
3498 V0(device->Backend,stop)();
3499 device->Flags &= ~DEVICE_RUNNING;
3501 ALCdevice_DecRef(device);
3503 return ALC_TRUE;
3507 /************************************************
3508 * ALC capture functions
3509 ************************************************/
3510 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3512 ALCdevice *device = NULL;
3513 ALCenum err;
3515 DO_INITCONFIG();
3517 if(!CaptureBackend.name)
3519 alcSetError(NULL, ALC_INVALID_VALUE);
3520 return NULL;
3523 if(samples <= 0)
3525 alcSetError(NULL, ALC_INVALID_VALUE);
3526 return NULL;
3529 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3530 deviceName = NULL;
3532 device = al_calloc(16, sizeof(ALCdevice));
3533 if(!device)
3535 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3536 return NULL;
3539 //Validate device
3540 InitRef(&device->ref, 1);
3541 device->Connected = ALC_TRUE;
3542 device->Type = Capture;
3544 VECTOR_INIT(device->Hrtf_List);
3545 AL_STRING_INIT(device->Hrtf_Name);
3547 AL_STRING_INIT(device->DeviceName);
3548 device->Dry.Buffer = NULL;
3549 device->Dry.NumChannels = 0;
3550 device->VirtOut.Buffer = NULL;
3551 device->VirtOut.NumChannels = 0;
3552 device->RealOut.Buffer = NULL;
3553 device->RealOut.NumChannels = 0;
3555 InitUIntMap(&device->BufferMap, ~0);
3556 InitUIntMap(&device->EffectMap, ~0);
3557 InitUIntMap(&device->FilterMap, ~0);
3559 if(!CaptureBackend.getFactory)
3560 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3561 ALCbackend_Capture);
3562 else
3564 ALCbackendFactory *factory = CaptureBackend.getFactory();
3565 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3567 if(!device->Backend)
3569 al_free(device);
3570 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3571 return NULL;
3574 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3575 device->Frequency = frequency;
3577 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3578 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3580 al_free(device);
3581 alcSetError(NULL, ALC_INVALID_ENUM);
3582 return NULL;
3584 device->IsHeadphones = AL_FALSE;
3586 device->UpdateSize = samples;
3587 device->NumUpdates = 1;
3589 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3591 al_free(device);
3592 alcSetError(NULL, err);
3593 return NULL;
3597 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3598 do {
3599 device->next = head;
3600 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3603 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3604 return device;
3607 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3609 ALCdevice *list, *next, *nextdev;
3611 LockLists();
3612 list = ATOMIC_LOAD(&DeviceList);
3613 do {
3614 if(list == device)
3615 break;
3616 } while((list=list->next) != NULL);
3617 if(!list || list->Type != Capture)
3619 alcSetError(list, ALC_INVALID_DEVICE);
3620 UnlockLists();
3621 return ALC_FALSE;
3624 next = device;
3625 nextdev = device->next;
3626 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3628 do {
3629 list = next;
3630 next = device;
3631 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3633 UnlockLists();
3635 ALCdevice_DecRef(device);
3637 return ALC_TRUE;
3640 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3642 if(!VerifyDevice(&device) || device->Type != Capture)
3643 alcSetError(device, ALC_INVALID_DEVICE);
3644 else
3646 V0(device->Backend,lock)();
3647 if(!device->Connected)
3648 alcSetError(device, ALC_INVALID_DEVICE);
3649 else if(!(device->Flags&DEVICE_RUNNING))
3651 if(V0(device->Backend,start)())
3652 device->Flags |= DEVICE_RUNNING;
3653 else
3655 aluHandleDisconnect(device);
3656 alcSetError(device, ALC_INVALID_DEVICE);
3659 V0(device->Backend,unlock)();
3662 if(device) ALCdevice_DecRef(device);
3665 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3667 if(!VerifyDevice(&device) || device->Type != Capture)
3668 alcSetError(device, ALC_INVALID_DEVICE);
3669 else
3671 V0(device->Backend,lock)();
3672 if((device->Flags&DEVICE_RUNNING))
3673 V0(device->Backend,stop)();
3674 device->Flags &= ~DEVICE_RUNNING;
3675 V0(device->Backend,unlock)();
3678 if(device) ALCdevice_DecRef(device);
3681 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3683 if(!VerifyDevice(&device) || device->Type != Capture)
3684 alcSetError(device, ALC_INVALID_DEVICE);
3685 else
3687 ALCenum err = ALC_INVALID_VALUE;
3689 V0(device->Backend,lock)();
3690 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3691 err = V(device->Backend,captureSamples)(buffer, samples);
3692 V0(device->Backend,unlock)();
3694 if(err != ALC_NO_ERROR)
3695 alcSetError(device, err);
3697 if(device) ALCdevice_DecRef(device);
3701 /************************************************
3702 * ALC loopback functions
3703 ************************************************/
3705 /* alcLoopbackOpenDeviceSOFT
3707 * Open a loopback device, for manual rendering.
3709 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3711 ALCbackendFactory *factory;
3712 ALCdevice *device;
3714 DO_INITCONFIG();
3716 /* Make sure the device name, if specified, is us. */
3717 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3719 alcSetError(NULL, ALC_INVALID_VALUE);
3720 return NULL;
3723 device = al_calloc(16, sizeof(ALCdevice));
3724 if(!device)
3726 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3727 return NULL;
3730 //Validate device
3731 InitRef(&device->ref, 1);
3732 device->Connected = ALC_TRUE;
3733 device->Type = Loopback;
3734 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3736 device->Flags = 0;
3737 VECTOR_INIT(device->Hrtf_List);
3738 AL_STRING_INIT(device->Hrtf_Name);
3739 device->Bs2b = NULL;
3740 device->Uhj_Encoder = NULL;
3741 device->Render_Mode = NormalRender;
3742 AL_STRING_INIT(device->DeviceName);
3743 device->Dry.Buffer = NULL;
3744 device->Dry.NumChannels = 0;
3745 device->VirtOut.Buffer = NULL;
3746 device->VirtOut.NumChannels = 0;
3747 device->RealOut.Buffer = NULL;
3748 device->RealOut.NumChannels = 0;
3750 ATOMIC_INIT(&device->ContextList, NULL);
3752 device->ClockBase = 0;
3753 device->SamplesDone = 0;
3755 device->MaxNoOfSources = 256;
3756 device->AuxiliaryEffectSlotMax = 4;
3757 device->NumAuxSends = MAX_SENDS;
3759 InitUIntMap(&device->BufferMap, ~0);
3760 InitUIntMap(&device->EffectMap, ~0);
3761 InitUIntMap(&device->FilterMap, ~0);
3763 factory = ALCloopbackFactory_getFactory();
3764 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3765 if(!device->Backend)
3767 al_free(device);
3768 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3769 return NULL;
3772 //Set output format
3773 device->NumUpdates = 0;
3774 device->UpdateSize = 0;
3776 device->Frequency = DEFAULT_OUTPUT_RATE;
3777 device->FmtChans = DevFmtChannelsDefault;
3778 device->FmtType = DevFmtTypeDefault;
3779 device->IsHeadphones = AL_FALSE;
3781 ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3782 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3784 ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3785 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3787 ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3788 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3790 device->NumStereoSources = 1;
3791 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3793 // Open the "backend"
3794 V(device->Backend,open)("Loopback");
3797 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3798 do {
3799 device->next = head;
3800 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3803 TRACE("Created device %p\n", device);
3804 return device;
3807 /* alcIsRenderFormatSupportedSOFT
3809 * Determines if the loopback device supports the given format for rendering.
3811 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3813 ALCboolean ret = ALC_FALSE;
3815 if(!VerifyDevice(&device) || device->Type != Loopback)
3816 alcSetError(device, ALC_INVALID_DEVICE);
3817 else if(freq <= 0)
3818 alcSetError(device, ALC_INVALID_VALUE);
3819 else
3821 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3822 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3823 freq >= MIN_OUTPUT_RATE)
3824 ret = ALC_TRUE;
3826 if(device) ALCdevice_DecRef(device);
3828 return ret;
3831 /* alcRenderSamplesSOFT
3833 * Renders some samples into a buffer, using the format last set by the
3834 * attributes given to alcCreateContext.
3836 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3838 if(!VerifyDevice(&device) || device->Type != Loopback)
3839 alcSetError(device, ALC_INVALID_DEVICE);
3840 else if(samples < 0 || (samples > 0 && buffer == NULL))
3841 alcSetError(device, ALC_INVALID_VALUE);
3842 else
3843 aluMixData(device, buffer, samples);
3844 if(device) ALCdevice_DecRef(device);
3848 /************************************************
3849 * ALC DSP pause/resume functions
3850 ************************************************/
3852 /* alcDevicePauseSOFT
3854 * Pause the DSP to stop audio processing.
3856 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3858 if(!VerifyDevice(&device) || device->Type != Playback)
3859 alcSetError(device, ALC_INVALID_DEVICE);
3860 else
3862 LockLists();
3863 if((device->Flags&DEVICE_RUNNING))
3864 V0(device->Backend,stop)();
3865 device->Flags &= ~DEVICE_RUNNING;
3866 device->Flags |= DEVICE_PAUSED;
3867 UnlockLists();
3869 if(device) ALCdevice_DecRef(device);
3872 /* alcDeviceResumeSOFT
3874 * Resume the DSP to restart audio processing.
3876 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3878 if(!VerifyDevice(&device) || device->Type != Playback)
3879 alcSetError(device, ALC_INVALID_DEVICE);
3880 else
3882 LockLists();
3883 if((device->Flags&DEVICE_PAUSED))
3885 device->Flags &= ~DEVICE_PAUSED;
3886 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3888 if(V0(device->Backend,start)() != ALC_FALSE)
3889 device->Flags |= DEVICE_RUNNING;
3890 else
3892 alcSetError(device, ALC_INVALID_DEVICE);
3893 V0(device->Backend,lock)();
3894 aluHandleDisconnect(device);
3895 V0(device->Backend,unlock)();
3899 UnlockLists();
3901 if(device) ALCdevice_DecRef(device);
3905 /************************************************
3906 * ALC HRTF functions
3907 ************************************************/
3909 /* alcGetStringiSOFT
3911 * Gets a string parameter at the given index.
3913 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3915 const ALCchar *str = NULL;
3917 if(!VerifyDevice(&device) || device->Type == Capture)
3918 alcSetError(device, ALC_INVALID_DEVICE);
3919 else switch(paramName)
3921 case ALC_HRTF_SPECIFIER_SOFT:
3922 if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
3923 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
3924 else
3925 alcSetError(device, ALC_INVALID_VALUE);
3926 break;
3928 default:
3929 alcSetError(device, ALC_INVALID_ENUM);
3930 break;
3932 if(device) ALCdevice_DecRef(device);
3934 return str;
3937 /* alcResetDeviceSOFT
3939 * Resets the given device output, using the specified attribute list.
3941 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
3943 ALCenum err;
3945 LockLists();
3946 if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3948 UnlockLists();
3949 alcSetError(device, ALC_INVALID_DEVICE);
3950 if(device) ALCdevice_DecRef(device);
3951 return ALC_FALSE;
3954 if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
3956 UnlockLists();
3957 alcSetError(device, err);
3958 if(err == ALC_INVALID_DEVICE)
3960 V0(device->Backend,lock)();
3961 aluHandleDisconnect(device);
3962 V0(device->Backend,unlock)();
3964 ALCdevice_DecRef(device);
3965 return ALC_FALSE;
3967 UnlockLists();
3968 ALCdevice_DecRef(device);
3970 return ALC_TRUE;