Use a helper macro for pi*2
[openal-soft.git] / Alc / ALc.c
blob8eb99e6362d0195dec48464a3177f67749c2c3bd
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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, 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 "bs2b.h"
39 #include "alu.h"
42 /************************************************
43 * Backends
44 ************************************************/
45 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
46 static struct BackendInfo BackendList[] = {
47 #ifdef HAVE_PULSEAUDIO
48 { "pulse", alc_pulse_init, alc_pulse_deinit, alc_pulse_probe, EmptyFuncs },
49 #endif
50 #ifdef HAVE_ALSA
51 { "alsa", alc_alsa_init, alc_alsa_deinit, alc_alsa_probe, EmptyFuncs },
52 #endif
53 #ifdef HAVE_COREAUDIO
54 { "core", alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
55 #endif
56 #ifdef HAVE_OSS
57 { "oss", alc_oss_init, alc_oss_deinit, alc_oss_probe, EmptyFuncs },
58 #endif
59 #ifdef HAVE_SOLARIS
60 { "solaris", alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs },
61 #endif
62 #ifdef HAVE_SNDIO
63 { "sndio", alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
64 #endif
65 #ifdef HAVE_QSA
66 { "qsa", alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
67 #endif
68 #ifdef HAVE_MMDEVAPI
69 { "mmdevapi", alcMMDevApiInit, alcMMDevApiDeinit, alcMMDevApiProbe, EmptyFuncs },
70 #endif
71 #ifdef HAVE_DSOUND
72 { "dsound", alcDSoundInit, alcDSoundDeinit, alcDSoundProbe, EmptyFuncs },
73 #endif
74 #ifdef HAVE_WINMM
75 { "winmm", alcWinMMInit, alcWinMMDeinit, alcWinMMProbe, EmptyFuncs },
76 #endif
77 #ifdef HAVE_PORTAUDIO
78 { "port", alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs },
79 #endif
80 #ifdef HAVE_OPENSL
81 { "opensl", alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
82 #endif
84 { "null", alc_null_init, alc_null_deinit, alc_null_probe, EmptyFuncs },
85 #ifdef HAVE_WAVE
86 { "wave", alc_wave_init, alc_wave_deinit, alc_wave_probe, EmptyFuncs },
87 #endif
89 { NULL, NULL, NULL, NULL, EmptyFuncs }
91 static struct BackendInfo BackendLoopback = {
92 "loopback", alc_loopback_init, alc_loopback_deinit, alc_loopback_probe, EmptyFuncs
94 #undef EmptyFuncs
96 static struct BackendInfo PlaybackBackend;
97 static struct BackendInfo CaptureBackend;
99 /************************************************
100 * Functions, enums, and errors
101 ************************************************/
102 typedef struct ALCfunction {
103 const ALCchar *funcName;
104 ALCvoid *address;
105 } ALCfunction;
107 typedef struct ALCenums {
108 const ALCchar *enumName;
109 ALCenum value;
110 } ALCenums;
112 #define DECL(x) { #x, (ALCvoid*)(x) }
113 static const ALCfunction alcFunctions[] = {
114 DECL(alcCreateContext),
115 DECL(alcMakeContextCurrent),
116 DECL(alcProcessContext),
117 DECL(alcSuspendContext),
118 DECL(alcDestroyContext),
119 DECL(alcGetCurrentContext),
120 DECL(alcGetContextsDevice),
121 DECL(alcOpenDevice),
122 DECL(alcCloseDevice),
123 DECL(alcGetError),
124 DECL(alcIsExtensionPresent),
125 DECL(alcGetProcAddress),
126 DECL(alcGetEnumValue),
127 DECL(alcGetString),
128 DECL(alcGetIntegerv),
129 DECL(alcCaptureOpenDevice),
130 DECL(alcCaptureCloseDevice),
131 DECL(alcCaptureStart),
132 DECL(alcCaptureStop),
133 DECL(alcCaptureSamples),
135 DECL(alcSetThreadContext),
136 DECL(alcGetThreadContext),
138 DECL(alcLoopbackOpenDeviceSOFT),
139 DECL(alcIsRenderFormatSupportedSOFT),
140 DECL(alcRenderSamplesSOFT),
142 DECL(alEnable),
143 DECL(alDisable),
144 DECL(alIsEnabled),
145 DECL(alGetString),
146 DECL(alGetBooleanv),
147 DECL(alGetIntegerv),
148 DECL(alGetFloatv),
149 DECL(alGetDoublev),
150 DECL(alGetBoolean),
151 DECL(alGetInteger),
152 DECL(alGetFloat),
153 DECL(alGetDouble),
154 DECL(alGetError),
155 DECL(alIsExtensionPresent),
156 DECL(alGetProcAddress),
157 DECL(alGetEnumValue),
158 DECL(alListenerf),
159 DECL(alListener3f),
160 DECL(alListenerfv),
161 DECL(alListeneri),
162 DECL(alListener3i),
163 DECL(alListeneriv),
164 DECL(alGetListenerf),
165 DECL(alGetListener3f),
166 DECL(alGetListenerfv),
167 DECL(alGetListeneri),
168 DECL(alGetListener3i),
169 DECL(alGetListeneriv),
170 DECL(alGenSources),
171 DECL(alDeleteSources),
172 DECL(alIsSource),
173 DECL(alSourcef),
174 DECL(alSource3f),
175 DECL(alSourcefv),
176 DECL(alSourcei),
177 DECL(alSource3i),
178 DECL(alSourceiv),
179 DECL(alGetSourcef),
180 DECL(alGetSource3f),
181 DECL(alGetSourcefv),
182 DECL(alGetSourcei),
183 DECL(alGetSource3i),
184 DECL(alGetSourceiv),
185 DECL(alSourcePlayv),
186 DECL(alSourceStopv),
187 DECL(alSourceRewindv),
188 DECL(alSourcePausev),
189 DECL(alSourcePlay),
190 DECL(alSourceStop),
191 DECL(alSourceRewind),
192 DECL(alSourcePause),
193 DECL(alSourceQueueBuffers),
194 DECL(alSourceUnqueueBuffers),
195 DECL(alGenBuffers),
196 DECL(alDeleteBuffers),
197 DECL(alIsBuffer),
198 DECL(alBufferData),
199 DECL(alBufferf),
200 DECL(alBuffer3f),
201 DECL(alBufferfv),
202 DECL(alBufferi),
203 DECL(alBuffer3i),
204 DECL(alBufferiv),
205 DECL(alGetBufferf),
206 DECL(alGetBuffer3f),
207 DECL(alGetBufferfv),
208 DECL(alGetBufferi),
209 DECL(alGetBuffer3i),
210 DECL(alGetBufferiv),
211 DECL(alDopplerFactor),
212 DECL(alDopplerVelocity),
213 DECL(alSpeedOfSound),
214 DECL(alDistanceModel),
216 DECL(alGenFilters),
217 DECL(alDeleteFilters),
218 DECL(alIsFilter),
219 DECL(alFilteri),
220 DECL(alFilteriv),
221 DECL(alFilterf),
222 DECL(alFilterfv),
223 DECL(alGetFilteri),
224 DECL(alGetFilteriv),
225 DECL(alGetFilterf),
226 DECL(alGetFilterfv),
227 DECL(alGenEffects),
228 DECL(alDeleteEffects),
229 DECL(alIsEffect),
230 DECL(alEffecti),
231 DECL(alEffectiv),
232 DECL(alEffectf),
233 DECL(alEffectfv),
234 DECL(alGetEffecti),
235 DECL(alGetEffectiv),
236 DECL(alGetEffectf),
237 DECL(alGetEffectfv),
238 DECL(alGenAuxiliaryEffectSlots),
239 DECL(alDeleteAuxiliaryEffectSlots),
240 DECL(alIsAuxiliaryEffectSlot),
241 DECL(alAuxiliaryEffectSloti),
242 DECL(alAuxiliaryEffectSlotiv),
243 DECL(alAuxiliaryEffectSlotf),
244 DECL(alAuxiliaryEffectSlotfv),
245 DECL(alGetAuxiliaryEffectSloti),
246 DECL(alGetAuxiliaryEffectSlotiv),
247 DECL(alGetAuxiliaryEffectSlotf),
248 DECL(alGetAuxiliaryEffectSlotfv),
250 DECL(alBufferSubDataSOFT),
252 DECL(alBufferSamplesSOFT),
253 DECL(alBufferSubSamplesSOFT),
254 DECL(alGetBufferSamplesSOFT),
255 DECL(alIsBufferFormatSupportedSOFT),
257 DECL(alDeferUpdatesSOFT),
258 DECL(alProcessUpdatesSOFT),
260 DECL(alSourcedSOFT),
261 DECL(alSource3dSOFT),
262 DECL(alSourcedvSOFT),
263 DECL(alGetSourcedSOFT),
264 DECL(alGetSource3dSOFT),
265 DECL(alGetSourcedvSOFT),
266 DECL(alSourcei64SOFT),
267 DECL(alSource3i64SOFT),
268 DECL(alSourcei64vSOFT),
269 DECL(alGetSourcei64SOFT),
270 DECL(alGetSource3i64SOFT),
271 DECL(alGetSourcei64vSOFT),
273 { NULL, NULL }
275 #undef DECL
277 #define DECL(x) { #x, (x) }
278 static const ALCenums enumeration[] = {
279 DECL(ALC_INVALID),
280 DECL(ALC_FALSE),
281 DECL(ALC_TRUE),
283 DECL(ALC_MAJOR_VERSION),
284 DECL(ALC_MINOR_VERSION),
285 DECL(ALC_ATTRIBUTES_SIZE),
286 DECL(ALC_ALL_ATTRIBUTES),
287 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
288 DECL(ALC_DEVICE_SPECIFIER),
289 DECL(ALC_ALL_DEVICES_SPECIFIER),
290 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
291 DECL(ALC_EXTENSIONS),
292 DECL(ALC_FREQUENCY),
293 DECL(ALC_REFRESH),
294 DECL(ALC_SYNC),
295 DECL(ALC_MONO_SOURCES),
296 DECL(ALC_STEREO_SOURCES),
297 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
298 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
299 DECL(ALC_CAPTURE_SAMPLES),
300 DECL(ALC_CONNECTED),
302 DECL(ALC_EFX_MAJOR_VERSION),
303 DECL(ALC_EFX_MINOR_VERSION),
304 DECL(ALC_MAX_AUXILIARY_SENDS),
306 DECL(ALC_FORMAT_CHANNELS_SOFT),
307 DECL(ALC_FORMAT_TYPE_SOFT),
309 DECL(ALC_MONO_SOFT),
310 DECL(ALC_STEREO_SOFT),
311 DECL(ALC_QUAD_SOFT),
312 DECL(ALC_5POINT1_SOFT),
313 DECL(ALC_6POINT1_SOFT),
314 DECL(ALC_7POINT1_SOFT),
316 DECL(ALC_BYTE_SOFT),
317 DECL(ALC_UNSIGNED_BYTE_SOFT),
318 DECL(ALC_SHORT_SOFT),
319 DECL(ALC_UNSIGNED_SHORT_SOFT),
320 DECL(ALC_INT_SOFT),
321 DECL(ALC_UNSIGNED_INT_SOFT),
322 DECL(ALC_FLOAT_SOFT),
324 DECL(ALC_NO_ERROR),
325 DECL(ALC_INVALID_DEVICE),
326 DECL(ALC_INVALID_CONTEXT),
327 DECL(ALC_INVALID_ENUM),
328 DECL(ALC_INVALID_VALUE),
329 DECL(ALC_OUT_OF_MEMORY),
332 DECL(AL_INVALID),
333 DECL(AL_NONE),
334 DECL(AL_FALSE),
335 DECL(AL_TRUE),
337 DECL(AL_SOURCE_RELATIVE),
338 DECL(AL_CONE_INNER_ANGLE),
339 DECL(AL_CONE_OUTER_ANGLE),
340 DECL(AL_PITCH),
341 DECL(AL_POSITION),
342 DECL(AL_DIRECTION),
343 DECL(AL_VELOCITY),
344 DECL(AL_LOOPING),
345 DECL(AL_BUFFER),
346 DECL(AL_GAIN),
347 DECL(AL_MIN_GAIN),
348 DECL(AL_MAX_GAIN),
349 DECL(AL_ORIENTATION),
350 DECL(AL_REFERENCE_DISTANCE),
351 DECL(AL_ROLLOFF_FACTOR),
352 DECL(AL_CONE_OUTER_GAIN),
353 DECL(AL_MAX_DISTANCE),
354 DECL(AL_SEC_OFFSET),
355 DECL(AL_SAMPLE_OFFSET),
356 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
357 DECL(AL_BYTE_OFFSET),
358 DECL(AL_BYTE_RW_OFFSETS_SOFT),
359 DECL(AL_SOURCE_TYPE),
360 DECL(AL_STATIC),
361 DECL(AL_STREAMING),
362 DECL(AL_UNDETERMINED),
363 DECL(AL_METERS_PER_UNIT),
364 DECL(AL_DIRECT_CHANNELS_SOFT),
366 DECL(AL_DIRECT_FILTER),
367 DECL(AL_AUXILIARY_SEND_FILTER),
368 DECL(AL_AIR_ABSORPTION_FACTOR),
369 DECL(AL_ROOM_ROLLOFF_FACTOR),
370 DECL(AL_CONE_OUTER_GAINHF),
371 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
372 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
373 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
375 DECL(AL_SOURCE_STATE),
376 DECL(AL_INITIAL),
377 DECL(AL_PLAYING),
378 DECL(AL_PAUSED),
379 DECL(AL_STOPPED),
381 DECL(AL_BUFFERS_QUEUED),
382 DECL(AL_BUFFERS_PROCESSED),
384 DECL(AL_FORMAT_MONO8),
385 DECL(AL_FORMAT_MONO16),
386 DECL(AL_FORMAT_MONO_FLOAT32),
387 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
388 DECL(AL_FORMAT_STEREO8),
389 DECL(AL_FORMAT_STEREO16),
390 DECL(AL_FORMAT_STEREO_FLOAT32),
391 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
392 DECL(AL_FORMAT_MONO_IMA4),
393 DECL(AL_FORMAT_STEREO_IMA4),
394 DECL(AL_FORMAT_QUAD8_LOKI),
395 DECL(AL_FORMAT_QUAD16_LOKI),
396 DECL(AL_FORMAT_QUAD8),
397 DECL(AL_FORMAT_QUAD16),
398 DECL(AL_FORMAT_QUAD32),
399 DECL(AL_FORMAT_51CHN8),
400 DECL(AL_FORMAT_51CHN16),
401 DECL(AL_FORMAT_51CHN32),
402 DECL(AL_FORMAT_61CHN8),
403 DECL(AL_FORMAT_61CHN16),
404 DECL(AL_FORMAT_61CHN32),
405 DECL(AL_FORMAT_71CHN8),
406 DECL(AL_FORMAT_71CHN16),
407 DECL(AL_FORMAT_71CHN32),
408 DECL(AL_FORMAT_REAR8),
409 DECL(AL_FORMAT_REAR16),
410 DECL(AL_FORMAT_REAR32),
411 DECL(AL_FORMAT_MONO_MULAW),
412 DECL(AL_FORMAT_MONO_MULAW_EXT),
413 DECL(AL_FORMAT_STEREO_MULAW),
414 DECL(AL_FORMAT_STEREO_MULAW_EXT),
415 DECL(AL_FORMAT_QUAD_MULAW),
416 DECL(AL_FORMAT_51CHN_MULAW),
417 DECL(AL_FORMAT_61CHN_MULAW),
418 DECL(AL_FORMAT_71CHN_MULAW),
419 DECL(AL_FORMAT_REAR_MULAW),
420 DECL(AL_FORMAT_MONO_ALAW_EXT),
421 DECL(AL_FORMAT_STEREO_ALAW_EXT),
423 DECL(AL_MONO8_SOFT),
424 DECL(AL_MONO16_SOFT),
425 DECL(AL_MONO32F_SOFT),
426 DECL(AL_STEREO8_SOFT),
427 DECL(AL_STEREO16_SOFT),
428 DECL(AL_STEREO32F_SOFT),
429 DECL(AL_QUAD8_SOFT),
430 DECL(AL_QUAD16_SOFT),
431 DECL(AL_QUAD32F_SOFT),
432 DECL(AL_REAR8_SOFT),
433 DECL(AL_REAR16_SOFT),
434 DECL(AL_REAR32F_SOFT),
435 DECL(AL_5POINT1_8_SOFT),
436 DECL(AL_5POINT1_16_SOFT),
437 DECL(AL_5POINT1_32F_SOFT),
438 DECL(AL_6POINT1_8_SOFT),
439 DECL(AL_6POINT1_16_SOFT),
440 DECL(AL_6POINT1_32F_SOFT),
441 DECL(AL_7POINT1_8_SOFT),
442 DECL(AL_7POINT1_16_SOFT),
443 DECL(AL_7POINT1_32F_SOFT),
445 DECL(AL_MONO_SOFT),
446 DECL(AL_STEREO_SOFT),
447 DECL(AL_QUAD_SOFT),
448 DECL(AL_REAR_SOFT),
449 DECL(AL_5POINT1_SOFT),
450 DECL(AL_6POINT1_SOFT),
451 DECL(AL_7POINT1_SOFT),
453 DECL(AL_BYTE_SOFT),
454 DECL(AL_UNSIGNED_BYTE_SOFT),
455 DECL(AL_SHORT_SOFT),
456 DECL(AL_UNSIGNED_SHORT_SOFT),
457 DECL(AL_INT_SOFT),
458 DECL(AL_UNSIGNED_INT_SOFT),
459 DECL(AL_FLOAT_SOFT),
460 DECL(AL_DOUBLE_SOFT),
461 DECL(AL_BYTE3_SOFT),
462 DECL(AL_UNSIGNED_BYTE3_SOFT),
464 DECL(AL_FREQUENCY),
465 DECL(AL_BITS),
466 DECL(AL_CHANNELS),
467 DECL(AL_SIZE),
468 DECL(AL_INTERNAL_FORMAT_SOFT),
469 DECL(AL_BYTE_LENGTH_SOFT),
470 DECL(AL_SAMPLE_LENGTH_SOFT),
471 DECL(AL_SEC_LENGTH_SOFT),
473 DECL(AL_UNUSED),
474 DECL(AL_PENDING),
475 DECL(AL_PROCESSED),
477 DECL(AL_NO_ERROR),
478 DECL(AL_INVALID_NAME),
479 DECL(AL_INVALID_ENUM),
480 DECL(AL_INVALID_VALUE),
481 DECL(AL_INVALID_OPERATION),
482 DECL(AL_OUT_OF_MEMORY),
484 DECL(AL_VENDOR),
485 DECL(AL_VERSION),
486 DECL(AL_RENDERER),
487 DECL(AL_EXTENSIONS),
489 DECL(AL_DOPPLER_FACTOR),
490 DECL(AL_DOPPLER_VELOCITY),
491 DECL(AL_DISTANCE_MODEL),
492 DECL(AL_SPEED_OF_SOUND),
493 DECL(AL_SOURCE_DISTANCE_MODEL),
494 DECL(AL_DEFERRED_UPDATES_SOFT),
496 DECL(AL_INVERSE_DISTANCE),
497 DECL(AL_INVERSE_DISTANCE_CLAMPED),
498 DECL(AL_LINEAR_DISTANCE),
499 DECL(AL_LINEAR_DISTANCE_CLAMPED),
500 DECL(AL_EXPONENT_DISTANCE),
501 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
503 DECL(AL_FILTER_TYPE),
504 DECL(AL_FILTER_NULL),
505 DECL(AL_FILTER_LOWPASS),
506 #if 0
507 DECL(AL_FILTER_HIGHPASS),
508 DECL(AL_FILTER_BANDPASS),
509 #endif
511 DECL(AL_LOWPASS_GAIN),
512 DECL(AL_LOWPASS_GAINHF),
514 DECL(AL_EFFECT_TYPE),
515 DECL(AL_EFFECT_NULL),
516 DECL(AL_EFFECT_REVERB),
517 DECL(AL_EFFECT_EAXREVERB),
518 DECL(AL_EFFECT_CHORUS),
519 DECL(AL_EFFECT_DISTORTION),
520 DECL(AL_EFFECT_ECHO),
521 DECL(AL_EFFECT_FLANGER),
522 #if 0
523 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
524 DECL(AL_EFFECT_VOCAL_MORPHER),
525 DECL(AL_EFFECT_PITCH_SHIFTER),
526 #endif
527 DECL(AL_EFFECT_RING_MODULATOR),
528 DECL(AL_EFFECT_AUTOWAH),
529 DECL(AL_EFFECT_COMPRESSOR),
530 DECL(AL_EFFECT_EQUALIZER),
531 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
532 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
534 DECL(AL_EAXREVERB_DENSITY),
535 DECL(AL_EAXREVERB_DIFFUSION),
536 DECL(AL_EAXREVERB_GAIN),
537 DECL(AL_EAXREVERB_GAINHF),
538 DECL(AL_EAXREVERB_GAINLF),
539 DECL(AL_EAXREVERB_DECAY_TIME),
540 DECL(AL_EAXREVERB_DECAY_HFRATIO),
541 DECL(AL_EAXREVERB_DECAY_LFRATIO),
542 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
543 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
544 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
545 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
546 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
547 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
548 DECL(AL_EAXREVERB_ECHO_TIME),
549 DECL(AL_EAXREVERB_ECHO_DEPTH),
550 DECL(AL_EAXREVERB_MODULATION_TIME),
551 DECL(AL_EAXREVERB_MODULATION_DEPTH),
552 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
553 DECL(AL_EAXREVERB_HFREFERENCE),
554 DECL(AL_EAXREVERB_LFREFERENCE),
555 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
556 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
558 DECL(AL_REVERB_DENSITY),
559 DECL(AL_REVERB_DIFFUSION),
560 DECL(AL_REVERB_GAIN),
561 DECL(AL_REVERB_GAINHF),
562 DECL(AL_REVERB_DECAY_TIME),
563 DECL(AL_REVERB_DECAY_HFRATIO),
564 DECL(AL_REVERB_REFLECTIONS_GAIN),
565 DECL(AL_REVERB_REFLECTIONS_DELAY),
566 DECL(AL_REVERB_LATE_REVERB_GAIN),
567 DECL(AL_REVERB_LATE_REVERB_DELAY),
568 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
569 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
570 DECL(AL_REVERB_DECAY_HFLIMIT),
572 DECL(AL_CHORUS_WAVEFORM),
573 DECL(AL_CHORUS_PHASE),
574 DECL(AL_CHORUS_RATE),
575 DECL(AL_CHORUS_DEPTH),
576 DECL(AL_CHORUS_FEEDBACK),
577 DECL(AL_CHORUS_DELAY),
579 DECL(AL_DISTORTION_EDGE),
580 DECL(AL_DISTORTION_GAIN),
581 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
582 DECL(AL_DISTORTION_EQCENTER),
583 DECL(AL_DISTORTION_EQBANDWIDTH),
585 DECL(AL_ECHO_DELAY),
586 DECL(AL_ECHO_LRDELAY),
587 DECL(AL_ECHO_DAMPING),
588 DECL(AL_ECHO_FEEDBACK),
589 DECL(AL_ECHO_SPREAD),
591 DECL(AL_FLANGER_WAVEFORM),
592 DECL(AL_FLANGER_PHASE),
593 DECL(AL_FLANGER_RATE),
594 DECL(AL_FLANGER_DEPTH),
595 DECL(AL_FLANGER_FEEDBACK),
596 DECL(AL_FLANGER_DELAY),
598 DECL(AL_RING_MODULATOR_FREQUENCY),
599 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
600 DECL(AL_RING_MODULATOR_WAVEFORM),
602 DECL(AL_AUTOWAH_ATTACK_TIME),
603 DECL(AL_AUTOWAH_PEAK_GAIN),
604 DECL(AL_AUTOWAH_RELEASE_TIME),
605 DECL(AL_AUTOWAH_RESONANCE),
607 DECL(AL_COMPRESSOR_ONOFF),
609 DECL(AL_EQUALIZER_LOW_GAIN),
610 DECL(AL_EQUALIZER_LOW_CUTOFF),
611 DECL(AL_EQUALIZER_MID1_GAIN),
612 DECL(AL_EQUALIZER_MID1_CENTER),
613 DECL(AL_EQUALIZER_MID1_WIDTH),
614 DECL(AL_EQUALIZER_MID2_GAIN),
615 DECL(AL_EQUALIZER_MID2_CENTER),
616 DECL(AL_EQUALIZER_MID2_WIDTH),
617 DECL(AL_EQUALIZER_HIGH_GAIN),
618 DECL(AL_EQUALIZER_HIGH_CUTOFF),
620 DECL(AL_DEDICATED_GAIN),
622 { NULL, (ALCenum)0 }
624 #undef DECL
626 static const ALCchar alcNoError[] = "No Error";
627 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
628 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
629 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
630 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
631 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
634 /************************************************
635 * Global variables
636 ************************************************/
638 /* Enumerated device names */
639 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
640 static ALCchar *alcAllDevicesList;
641 static ALCchar *alcCaptureDeviceList;
642 /* Sizes only include the first ending null character, not the second */
643 static size_t alcAllDevicesListSize;
644 static size_t alcCaptureDeviceListSize;
646 /* Default is always the first in the list */
647 static ALCchar *alcDefaultAllDevicesSpecifier;
648 static ALCchar *alcCaptureDefaultDeviceSpecifier;
650 /* Default context extensions */
651 static const ALchar alExtList[] =
652 "AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 "
653 "AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW "
654 "AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model "
655 "AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data "
656 "AL_SOFT_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points "
657 "AL_SOFT_source_latency";
659 static volatile ALCenum LastNullDeviceError = ALC_NO_ERROR;
661 /* Thread-local current context */
662 static pthread_key_t LocalContext;
663 /* Process-wide current context */
664 static ALCcontext *volatile GlobalContext = NULL;
666 /* Mixing thread piority level */
667 ALint RTPrioLevel;
669 FILE *LogFile;
670 #ifdef _DEBUG
671 enum LogLevel LogLevel = LogWarning;
672 #else
673 enum LogLevel LogLevel = LogError;
674 #endif
676 /* Flag to trap ALC device errors */
677 static ALCboolean TrapALCError = ALC_FALSE;
679 /* One-time configuration init control */
680 static pthread_once_t alc_config_once = PTHREAD_ONCE_INIT;
682 /* Default effect that applies to sources that don't have an effect on send 0 */
683 static ALeffect DefaultEffect;
686 /************************************************
687 * ALC information
688 ************************************************/
689 static const ALCchar alcNoDeviceExtList[] =
690 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
691 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
692 static const ALCchar alcExtensionList[] =
693 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
694 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
695 "ALC_EXT_thread_local_context ALC_SOFTX_HRTF ALC_SOFT_loopback";
696 static const ALCint alcMajorVersion = 1;
697 static const ALCint alcMinorVersion = 1;
699 static const ALCint alcEFXMajorVersion = 1;
700 static const ALCint alcEFXMinorVersion = 0;
703 /************************************************
704 * Device lists
705 ************************************************/
706 static ALCdevice *volatile DeviceList = NULL;
708 static CRITICAL_SECTION ListLock;
710 static void LockLists(void)
712 EnterCriticalSection(&ListLock);
714 static void UnlockLists(void)
716 LeaveCriticalSection(&ListLock);
719 /************************************************
720 * Library initialization
721 ************************************************/
722 #if defined(_WIN32)
723 static void alc_init(void);
724 static void alc_deinit(void);
725 static void alc_deinit_safe(void);
727 UIntMap TlsDestructor;
729 #ifndef AL_LIBTYPE_STATIC
730 BOOL APIENTRY DllMain(HINSTANCE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
732 ALsizei i;
734 // Perform actions based on the reason for calling.
735 switch(ul_reason_for_call)
737 case DLL_PROCESS_ATTACH:
738 /* Pin the DLL so we won't get unloaded until the process terminates */
739 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
740 (WCHAR*)hModule, &hModule);
741 InitUIntMap(&TlsDestructor, ~0);
742 alc_init();
743 break;
745 case DLL_THREAD_DETACH:
746 LockUIntMapRead(&TlsDestructor);
747 for(i = 0;i < TlsDestructor.size;i++)
749 void *ptr = pthread_getspecific(TlsDestructor.array[i].key);
750 void (*callback)(void*) = (void(*)(void*))TlsDestructor.array[i].value;
751 if(ptr && callback)
752 callback(ptr);
754 UnlockUIntMapRead(&TlsDestructor);
755 break;
757 case DLL_PROCESS_DETACH:
758 if(!lpReserved)
759 alc_deinit();
760 else
761 alc_deinit_safe();
762 ResetUIntMap(&TlsDestructor);
763 break;
765 return TRUE;
767 #elif defined(_MSC_VER)
768 #pragma section(".CRT$XCU",read)
769 static void alc_constructor(void);
770 static void alc_destructor(void);
771 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
773 static void alc_constructor(void)
775 atexit(alc_destructor);
776 alc_init();
779 static void alc_destructor(void)
781 alc_deinit();
783 #elif defined(HAVE_GCC_DESTRUCTOR)
784 static void alc_init(void) __attribute__((constructor));
785 static void alc_deinit(void) __attribute__((destructor));
786 #else
787 #error "No static initialization available on this platform!"
788 #endif
790 #elif defined(HAVE_GCC_DESTRUCTOR)
792 static void alc_init(void) __attribute__((constructor));
793 static void alc_deinit(void) __attribute__((destructor));
795 #else
796 #error "No global initialization available on this platform!"
797 #endif
799 static void ReleaseThreadCtx(void *ptr);
800 static void alc_init(void)
802 const char *str;
804 LogFile = stderr;
806 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
807 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
808 ConeScale *= 0.5f;
810 str = getenv("__ALSOFT_REVERSE_Z");
811 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
812 ZScale *= -1.0f;
814 pthread_key_create(&LocalContext, ReleaseThreadCtx);
815 InitializeCriticalSection(&ListLock);
816 ThunkInit();
819 static void alc_initconfig(void)
821 const char *devs, *str;
822 ALuint capfilter;
823 float valf;
824 int i, n;
826 str = getenv("ALSOFT_LOGLEVEL");
827 if(str)
829 long lvl = strtol(str, NULL, 0);
830 if(lvl >= NoLog && lvl <= LogRef)
831 LogLevel = lvl;
834 str = getenv("ALSOFT_LOGFILE");
835 if(str && str[0])
837 FILE *logfile = fopen(str, "wt");
838 if(logfile) LogFile = logfile;
839 else ERR("Failed to open log file '%s'\n", str);
843 char buf[1024] = "";
844 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
845 for(i = 1;BackendList[i].name;i++)
846 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
847 TRACE("Supported backends: %s\n", buf);
849 ReadALConfig();
851 capfilter = 0;
852 #ifdef HAVE_SSE
853 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
854 #endif
855 #ifdef HAVE_NEON
856 capfilter |= CPU_CAP_NEON;
857 #endif
858 if(ConfigValueStr(NULL, "disable-cpu-exts", &str))
860 if(strcasecmp(str, "all") == 0)
861 capfilter = 0;
862 else
864 size_t len;
865 const char *next = str;
867 do {
868 str = next;
869 while(isspace(str[0]))
870 str++;
871 next = strchr(str, ',');
873 if(!str[0] || str[0] == ',')
874 continue;
876 len = (next ? ((size_t)(next-str)) : strlen(str));
877 while(len > 0 && isspace(str[len-1]))
878 len--;
879 if(len == 3 && strncasecmp(str, "sse", len) == 0)
880 capfilter &= ~CPU_CAP_SSE;
881 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
882 capfilter &= ~CPU_CAP_SSE2;
883 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
884 capfilter &= ~CPU_CAP_NEON;
885 else
886 WARN("Invalid CPU extension \"%s\"\n", str);
887 } while(next++);
890 FillCPUCaps(capfilter);
892 #ifdef _WIN32
893 RTPrioLevel = 1;
894 #else
895 RTPrioLevel = 0;
896 #endif
897 ConfigValueInt(NULL, "rt-prio", &RTPrioLevel);
899 if(ConfigValueStr(NULL, "resampler", &str))
901 if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
902 DefaultResampler = PointResampler;
903 else if(strcasecmp(str, "linear") == 0)
904 DefaultResampler = LinearResampler;
905 else if(strcasecmp(str, "cubic") == 0)
906 DefaultResampler = CubicResampler;
907 else
909 char *end;
911 n = strtol(str, &end, 0);
912 if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == CubicResampler))
913 DefaultResampler = n;
914 else
915 WARN("Invalid resampler: %s\n", str);
919 str = getenv("ALSOFT_TRAP_ERROR");
920 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
922 TrapALError = AL_TRUE;
923 TrapALCError = AL_TRUE;
925 else
927 str = getenv("ALSOFT_TRAP_AL_ERROR");
928 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
929 TrapALError = AL_TRUE;
930 TrapALError = GetConfigValueBool(NULL, "trap-al-error", TrapALError);
932 str = getenv("ALSOFT_TRAP_ALC_ERROR");
933 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
934 TrapALCError = ALC_TRUE;
935 TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", TrapALCError);
938 if(ConfigValueFloat("reverb", "boost", &valf))
939 ReverbBoost *= powf(10.0f, valf / 20.0f);
941 EmulateEAXReverb = GetConfigValueBool("reverb", "emulate-eax", AL_FALSE);
943 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
944 ConfigValueStr(NULL, "drivers", &devs))
946 int n;
947 size_t len;
948 const char *next = devs;
949 int endlist, delitem;
951 i = 0;
952 do {
953 devs = next;
954 while(isspace(devs[0]))
955 devs++;
956 next = strchr(devs, ',');
958 delitem = (devs[0] == '-');
959 if(devs[0] == '-') devs++;
961 if(!devs[0] || devs[0] == ',')
963 endlist = 0;
964 continue;
966 endlist = 1;
968 len = (next ? ((size_t)(next-devs)) : strlen(devs));
969 while(len > 0 && isspace(devs[len-1]))
970 len--;
971 for(n = i;BackendList[n].Init;n++)
973 if(len == strlen(BackendList[n].name) &&
974 strncmp(BackendList[n].name, devs, len) == 0)
976 if(delitem)
978 do {
979 BackendList[n] = BackendList[n+1];
980 ++n;
981 } while(BackendList[n].Init);
983 else
985 struct BackendInfo Bkp = BackendList[n];
986 while(n > i)
988 BackendList[n] = BackendList[n-1];
989 --n;
991 BackendList[n] = Bkp;
993 i++;
995 break;
998 } while(next++);
1000 if(endlist)
1002 BackendList[i].name = NULL;
1003 BackendList[i].Init = NULL;
1004 BackendList[i].Deinit = NULL;
1005 BackendList[i].Probe = NULL;
1009 for(i = 0;BackendList[i].Init && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1011 if(!BackendList[i].Init(&BackendList[i].Funcs))
1013 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1014 continue;
1017 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1018 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1020 PlaybackBackend = BackendList[i];
1021 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1023 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1025 CaptureBackend = BackendList[i];
1026 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1029 BackendLoopback.Init(&BackendLoopback.Funcs);
1031 if(ConfigValueStr(NULL, "excludefx", &str))
1033 size_t len;
1034 const char *next = str;
1036 do {
1037 str = next;
1038 next = strchr(str, ',');
1040 if(!str[0] || next == str)
1041 continue;
1043 len = (next ? ((size_t)(next-str)) : strlen(str));
1044 for(n = 0;EffectList[n].name;n++)
1046 if(len == strlen(EffectList[n].name) &&
1047 strncmp(EffectList[n].name, str, len) == 0)
1048 DisabledEffects[EffectList[n].type] = AL_TRUE;
1050 } while(next++);
1053 InitEffectFactoryMap();
1055 InitEffect(&DefaultEffect);
1056 str = getenv("ALSOFT_DEFAULT_REVERB");
1057 if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str))
1058 LoadReverbPreset(str, &DefaultEffect);
1060 #define DO_INITCONFIG() pthread_once(&alc_config_once, alc_initconfig)
1063 /************************************************
1064 * Library deinitialization
1065 ************************************************/
1066 static void alc_cleanup(void)
1068 ALCdevice *dev;
1070 free(alcAllDevicesList); alcAllDevicesList = NULL;
1071 alcAllDevicesListSize = 0;
1072 free(alcCaptureDeviceList); alcCaptureDeviceList = NULL;
1073 alcCaptureDeviceListSize = 0;
1075 free(alcDefaultAllDevicesSpecifier);
1076 alcDefaultAllDevicesSpecifier = NULL;
1077 free(alcCaptureDefaultDeviceSpecifier);
1078 alcCaptureDefaultDeviceSpecifier = NULL;
1080 if((dev=ExchangePtr((XchgPtr*)&DeviceList, NULL)) != NULL)
1082 ALCuint num = 0;
1083 do {
1084 num++;
1085 } while((dev=dev->next) != NULL);
1086 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1089 DeinitEffectFactoryMap();
1092 static void alc_deinit_safe(void)
1094 alc_cleanup();
1096 FreeHrtfs();
1097 FreeALConfig();
1099 ThunkExit();
1100 DeleteCriticalSection(&ListLock);
1101 pthread_key_delete(LocalContext);
1103 if(LogFile != stderr)
1104 fclose(LogFile);
1105 LogFile = NULL;
1108 static void alc_deinit(void)
1110 int i;
1112 alc_cleanup();
1114 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1115 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1117 for(i = 0;BackendList[i].Deinit;i++)
1118 BackendList[i].Deinit();
1119 BackendLoopback.Deinit();
1121 alc_deinit_safe();
1125 /************************************************
1126 * Device enumeration
1127 ************************************************/
1128 static void ProbeList(ALCchar **list, size_t *listsize, enum DevProbe type)
1130 DO_INITCONFIG();
1132 LockLists();
1133 free(*list);
1134 *list = NULL;
1135 *listsize = 0;
1137 if(type == ALL_DEVICE_PROBE && PlaybackBackend.Probe)
1138 PlaybackBackend.Probe(type);
1139 else if(type == CAPTURE_DEVICE_PROBE && CaptureBackend.Probe)
1140 CaptureBackend.Probe(type);
1141 UnlockLists();
1144 static void ProbeAllDevicesList(void)
1145 { ProbeList(&alcAllDevicesList, &alcAllDevicesListSize, ALL_DEVICE_PROBE); }
1146 static void ProbeCaptureDeviceList(void)
1147 { ProbeList(&alcCaptureDeviceList, &alcCaptureDeviceListSize, CAPTURE_DEVICE_PROBE); }
1150 static void AppendList(const ALCchar *name, ALCchar **List, size_t *ListSize)
1152 size_t len = strlen(name);
1153 void *temp;
1155 if(len == 0)
1156 return;
1158 temp = realloc(*List, (*ListSize) + len + 2);
1159 if(!temp)
1161 ERR("Realloc failed to add %s!\n", name);
1162 return;
1164 *List = temp;
1166 memcpy((*List)+(*ListSize), name, len+1);
1167 *ListSize += len+1;
1168 (*List)[*ListSize] = 0;
1171 #define DECL_APPEND_LIST_FUNC(type) \
1172 void Append##type##List(const ALCchar *name) \
1173 { AppendList(name, &alc##type##List, &alc##type##ListSize); }
1175 DECL_APPEND_LIST_FUNC(AllDevices)
1176 DECL_APPEND_LIST_FUNC(CaptureDevice)
1178 #undef DECL_APPEND_LIST_FUNC
1181 /************************************************
1182 * Device format information
1183 ************************************************/
1184 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1186 switch(type)
1188 case DevFmtByte: return "Signed Byte";
1189 case DevFmtUByte: return "Unsigned Byte";
1190 case DevFmtShort: return "Signed Short";
1191 case DevFmtUShort: return "Unsigned Short";
1192 case DevFmtInt: return "Signed Int";
1193 case DevFmtUInt: return "Unsigned Int";
1194 case DevFmtFloat: return "Float";
1196 return "(unknown type)";
1198 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1200 switch(chans)
1202 case DevFmtMono: return "Mono";
1203 case DevFmtStereo: return "Stereo";
1204 case DevFmtQuad: return "Quadraphonic";
1205 case DevFmtX51: return "5.1 Surround";
1206 case DevFmtX51Side: return "5.1 Side";
1207 case DevFmtX61: return "6.1 Surround";
1208 case DevFmtX71: return "7.1 Surround";
1210 return "(unknown channels)";
1213 ALuint BytesFromDevFmt(enum DevFmtType type)
1215 switch(type)
1217 case DevFmtByte: return sizeof(ALbyte);
1218 case DevFmtUByte: return sizeof(ALubyte);
1219 case DevFmtShort: return sizeof(ALshort);
1220 case DevFmtUShort: return sizeof(ALushort);
1221 case DevFmtInt: return sizeof(ALint);
1222 case DevFmtUInt: return sizeof(ALuint);
1223 case DevFmtFloat: return sizeof(ALfloat);
1225 return 0;
1227 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1229 switch(chans)
1231 case DevFmtMono: return 1;
1232 case DevFmtStereo: return 2;
1233 case DevFmtQuad: return 4;
1234 case DevFmtX51: return 6;
1235 case DevFmtX51Side: return 6;
1236 case DevFmtX61: return 7;
1237 case DevFmtX71: return 8;
1239 return 0;
1242 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1243 enum DevFmtType *type)
1245 static const struct {
1246 ALenum format;
1247 enum DevFmtChannels channels;
1248 enum DevFmtType type;
1249 } list[] = {
1250 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1251 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1252 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1254 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1255 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1256 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1258 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1259 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1260 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1262 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1263 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1264 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1266 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1267 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1268 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1270 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1271 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1272 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1274 ALuint i;
1276 for(i = 0;i < COUNTOF(list);i++)
1278 if(list[i].format == format)
1280 *chans = list[i].channels;
1281 *type = list[i].type;
1282 return AL_TRUE;
1286 return AL_FALSE;
1289 static ALCboolean IsValidALCType(ALCenum type)
1291 switch(type)
1293 case ALC_BYTE_SOFT:
1294 case ALC_UNSIGNED_BYTE_SOFT:
1295 case ALC_SHORT_SOFT:
1296 case ALC_UNSIGNED_SHORT_SOFT:
1297 case ALC_INT_SOFT:
1298 case ALC_UNSIGNED_INT_SOFT:
1299 case ALC_FLOAT_SOFT:
1300 return ALC_TRUE;
1302 return ALC_FALSE;
1305 static ALCboolean IsValidALCChannels(ALCenum channels)
1307 switch(channels)
1309 case ALC_MONO_SOFT:
1310 case ALC_STEREO_SOFT:
1311 case ALC_QUAD_SOFT:
1312 case ALC_5POINT1_SOFT:
1313 case ALC_6POINT1_SOFT:
1314 case ALC_7POINT1_SOFT:
1315 return ALC_TRUE;
1317 return ALC_FALSE;
1321 /************************************************
1322 * Miscellaneous ALC helpers
1323 ************************************************/
1325 void ALCdevice_LockDefault(ALCdevice *device)
1327 EnterCriticalSection(&device->Mutex);
1329 void ALCdevice_UnlockDefault(ALCdevice *device)
1331 LeaveCriticalSection(&device->Mutex);
1333 ALint64 ALCdevice_GetLatencyDefault(ALCdevice *UNUSED(device))
1335 return 0;
1338 /* SetDefaultWFXChannelOrder
1340 * Sets the default channel order used by WaveFormatEx.
1342 void SetDefaultWFXChannelOrder(ALCdevice *device)
1344 ALuint i;
1346 for(i = 0;i < MaxChannels;i++)
1347 device->ChannelOffsets[i] = INVALID_OFFSET;
1349 switch(device->FmtChans)
1351 case DevFmtMono: device->ChannelOffsets[FrontCenter] = 0;
1352 break;
1353 case DevFmtStereo: device->ChannelOffsets[FrontLeft] = 0;
1354 device->ChannelOffsets[FrontRight] = 1;
1355 break;
1356 case DevFmtQuad: device->ChannelOffsets[FrontLeft] = 0;
1357 device->ChannelOffsets[FrontRight] = 1;
1358 device->ChannelOffsets[BackLeft] = 2;
1359 device->ChannelOffsets[BackRight] = 3;
1360 break;
1361 case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0;
1362 device->ChannelOffsets[FrontRight] = 1;
1363 device->ChannelOffsets[FrontCenter] = 2;
1364 device->ChannelOffsets[LFE] = 3;
1365 device->ChannelOffsets[BackLeft] = 4;
1366 device->ChannelOffsets[BackRight] = 5;
1367 break;
1368 case DevFmtX51Side: device->ChannelOffsets[FrontLeft] = 0;
1369 device->ChannelOffsets[FrontRight] = 1;
1370 device->ChannelOffsets[FrontCenter] = 2;
1371 device->ChannelOffsets[LFE] = 3;
1372 device->ChannelOffsets[SideLeft] = 4;
1373 device->ChannelOffsets[SideRight] = 5;
1374 break;
1375 case DevFmtX61: device->ChannelOffsets[FrontLeft] = 0;
1376 device->ChannelOffsets[FrontRight] = 1;
1377 device->ChannelOffsets[FrontCenter] = 2;
1378 device->ChannelOffsets[LFE] = 3;
1379 device->ChannelOffsets[BackCenter] = 4;
1380 device->ChannelOffsets[SideLeft] = 5;
1381 device->ChannelOffsets[SideRight] = 6;
1382 break;
1383 case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0;
1384 device->ChannelOffsets[FrontRight] = 1;
1385 device->ChannelOffsets[FrontCenter] = 2;
1386 device->ChannelOffsets[LFE] = 3;
1387 device->ChannelOffsets[BackLeft] = 4;
1388 device->ChannelOffsets[BackRight] = 5;
1389 device->ChannelOffsets[SideLeft] = 6;
1390 device->ChannelOffsets[SideRight] = 7;
1391 break;
1395 /* SetDefaultChannelOrder
1397 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1399 void SetDefaultChannelOrder(ALCdevice *device)
1401 ALuint i;
1403 for(i = 0;i < MaxChannels;i++)
1404 device->ChannelOffsets[i] = INVALID_OFFSET;
1406 switch(device->FmtChans)
1408 case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0;
1409 device->ChannelOffsets[FrontRight] = 1;
1410 device->ChannelOffsets[BackLeft] = 2;
1411 device->ChannelOffsets[BackRight] = 3;
1412 device->ChannelOffsets[FrontCenter] = 4;
1413 device->ChannelOffsets[LFE] = 5;
1414 return;
1415 case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0;
1416 device->ChannelOffsets[FrontRight] = 1;
1417 device->ChannelOffsets[BackLeft] = 2;
1418 device->ChannelOffsets[BackRight] = 3;
1419 device->ChannelOffsets[FrontCenter] = 4;
1420 device->ChannelOffsets[LFE] = 5;
1421 device->ChannelOffsets[SideLeft] = 6;
1422 device->ChannelOffsets[SideRight] = 7;
1423 return;
1425 /* Same as WFX order */
1426 case DevFmtMono:
1427 case DevFmtStereo:
1428 case DevFmtQuad:
1429 case DevFmtX51Side:
1430 case DevFmtX61:
1431 break;
1433 SetDefaultWFXChannelOrder(device);
1437 /* alcSetError
1439 * Stores the latest ALC device error
1441 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1443 if(TrapALCError)
1445 #ifdef _WIN32
1446 /* DebugBreak() will cause an exception if there is no debugger */
1447 if(IsDebuggerPresent())
1448 DebugBreak();
1449 #elif defined(SIGTRAP)
1450 raise(SIGTRAP);
1451 #endif
1454 if(device)
1455 device->LastError = errorCode;
1456 else
1457 LastNullDeviceError = errorCode;
1461 /* UpdateDeviceParams
1463 * Updates device parameters according to the attribute list (caller is
1464 * responsible for holding the list lock).
1466 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1468 ALCcontext *context;
1469 enum DevFmtChannels oldChans;
1470 enum DevFmtType oldType;
1471 ALCuint oldFreq;
1472 FPUCtl oldMode;
1473 ALuint i;
1475 // Check for attributes
1476 if(device->Type == Loopback)
1478 enum {
1479 GotFreq = 1<<0,
1480 GotChans = 1<<1,
1481 GotType = 1<<2,
1482 GotAll = GotFreq|GotChans|GotType
1484 ALCuint freq, numMono, numStereo, numSends;
1485 enum DevFmtChannels schans;
1486 enum DevFmtType stype;
1487 ALCuint attrIdx = 0;
1488 ALCint gotFmt = 0;
1490 if(!attrList)
1492 WARN("Missing attributes for loopback device\n");
1493 return ALC_INVALID_VALUE;
1496 numMono = device->NumMonoSources;
1497 numStereo = device->NumStereoSources;
1498 numSends = device->NumAuxSends;
1499 schans = device->FmtChans;
1500 stype = device->FmtType;
1501 freq = device->Frequency;
1503 while(attrList[attrIdx])
1505 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1507 ALCint val = attrList[attrIdx + 1];
1508 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1509 return ALC_INVALID_VALUE;
1510 schans = val;
1511 gotFmt |= GotChans;
1514 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1516 ALCint val = attrList[attrIdx + 1];
1517 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1518 return ALC_INVALID_VALUE;
1519 stype = val;
1520 gotFmt |= GotType;
1523 if(attrList[attrIdx] == ALC_FREQUENCY)
1525 freq = attrList[attrIdx + 1];
1526 if(freq < MIN_OUTPUT_RATE)
1527 return ALC_INVALID_VALUE;
1528 gotFmt |= GotFreq;
1531 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1533 numStereo = attrList[attrIdx + 1];
1534 if(numStereo > device->MaxNoOfSources)
1535 numStereo = device->MaxNoOfSources;
1537 numMono = device->MaxNoOfSources - numStereo;
1540 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1541 numSends = attrList[attrIdx + 1];
1543 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1545 if(attrList[attrIdx + 1] != ALC_FALSE)
1546 device->Flags |= DEVICE_HRTF_REQUEST;
1547 else
1548 device->Flags &= ~DEVICE_HRTF_REQUEST;
1551 attrIdx += 2;
1554 if(gotFmt != GotAll)
1556 WARN("Missing format for loopback device\n");
1557 return ALC_INVALID_VALUE;
1560 ConfigValueUInt(NULL, "sends", &numSends);
1561 numSends = minu(MAX_SENDS, numSends);
1563 if((device->Flags&DEVICE_RUNNING))
1564 ALCdevice_StopPlayback(device);
1565 device->Flags &= ~DEVICE_RUNNING;
1567 device->Frequency = freq;
1568 device->FmtChans = schans;
1569 device->FmtType = stype;
1570 device->NumMonoSources = numMono;
1571 device->NumStereoSources = numStereo;
1572 device->NumAuxSends = numSends;
1574 else if(attrList && attrList[0])
1576 ALCuint freq, numMono, numStereo, numSends;
1577 ALCuint attrIdx = 0;
1579 /* If a context is already running on the device, stop playback so the
1580 * device attributes can be updated. */
1581 if((device->Flags&DEVICE_RUNNING))
1582 ALCdevice_StopPlayback(device);
1583 device->Flags &= ~DEVICE_RUNNING;
1585 freq = device->Frequency;
1586 numMono = device->NumMonoSources;
1587 numStereo = device->NumStereoSources;
1588 numSends = device->NumAuxSends;
1590 while(attrList[attrIdx])
1592 if(attrList[attrIdx] == ALC_FREQUENCY)
1594 freq = attrList[attrIdx + 1];
1595 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1598 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1600 numStereo = attrList[attrIdx + 1];
1601 if(numStereo > device->MaxNoOfSources)
1602 numStereo = device->MaxNoOfSources;
1604 numMono = device->MaxNoOfSources - numStereo;
1607 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1608 numSends = attrList[attrIdx + 1];
1610 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1612 if(attrList[attrIdx + 1] != ALC_FALSE)
1613 device->Flags |= DEVICE_HRTF_REQUEST;
1614 else
1615 device->Flags &= ~DEVICE_HRTF_REQUEST;
1618 attrIdx += 2;
1621 ConfigValueUInt(NULL, "frequency", &freq);
1622 freq = maxu(freq, MIN_OUTPUT_RATE);
1624 ConfigValueUInt(NULL, "sends", &numSends);
1625 numSends = minu(MAX_SENDS, numSends);
1627 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1628 device->Frequency;
1629 /* SSE does best with the update size being a multiple of 4 */
1630 if((CPUCapFlags&CPU_CAP_SSE))
1631 device->UpdateSize = (device->UpdateSize+3)&~3;
1633 device->Frequency = freq;
1634 device->NumMonoSources = numMono;
1635 device->NumStereoSources = numStereo;
1636 device->NumAuxSends = numSends;
1639 if((device->Flags&DEVICE_RUNNING))
1640 return ALC_NO_ERROR;
1642 oldFreq = device->Frequency;
1643 oldChans = device->FmtChans;
1644 oldType = device->FmtType;
1646 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1647 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"",
1648 DevFmtChannelsString(device->FmtChans),
1649 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"",
1650 DevFmtTypeString(device->FmtType),
1651 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"",
1652 device->Frequency,
1653 device->UpdateSize, device->NumUpdates);
1655 if((device->Flags&DEVICE_HRTF_REQUEST))
1657 enum DevFmtChannels chans;
1658 ALCuint freq;
1660 FindHrtfFormat(device, &chans, &freq);
1661 device->Frequency = freq;
1662 device->FmtChans = chans;
1663 device->Flags |= DEVICE_CHANNELS_REQUEST |
1664 DEVICE_FREQUENCY_REQUEST;
1667 if(ALCdevice_ResetPlayback(device) == ALC_FALSE)
1668 return ALC_INVALID_DEVICE;
1670 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1672 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1673 DevFmtChannelsString(device->FmtChans));
1674 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1676 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1678 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1679 DevFmtTypeString(device->FmtType));
1680 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1682 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1684 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1685 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1688 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1689 DevFmtChannelsString(device->FmtChans),
1690 DevFmtTypeString(device->FmtType), device->Frequency,
1691 device->UpdateSize, device->NumUpdates);
1693 aluInitPanning(device);
1695 for(i = 0;i < MaxChannels;i++)
1697 device->ClickRemoval[i] = 0.0f;
1698 device->PendingClicks[i] = 0.0f;
1701 device->Hrtf = NULL;
1702 if(device->Type != Loopback && ConfigValueExists(NULL, "hrtf"))
1704 if(GetConfigValueBool(NULL, "hrtf", AL_FALSE))
1705 device->Flags |= DEVICE_HRTF_REQUEST;
1706 else
1707 device->Flags &= ~DEVICE_HRTF_REQUEST;
1709 if((device->Flags&DEVICE_HRTF_REQUEST))
1711 device->Hrtf = GetHrtf(device);
1712 if(!device->Hrtf)
1713 device->Flags &= ~DEVICE_HRTF_REQUEST;
1715 TRACE("HRTF %s\n", device->Hrtf?"enabled":"disabled");
1717 if(!device->Hrtf && device->Bs2bLevel > 0 && device->Bs2bLevel <= 6)
1719 if(!device->Bs2b)
1721 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
1722 bs2b_clear(device->Bs2b);
1724 bs2b_set_srate(device->Bs2b, device->Frequency);
1725 bs2b_set_level(device->Bs2b, device->Bs2bLevel);
1726 TRACE("BS2B level %d\n", device->Bs2bLevel);
1728 else
1730 free(device->Bs2b);
1731 device->Bs2b = NULL;
1732 TRACE("BS2B disabled\n");
1735 device->Flags &= ~DEVICE_WIDE_STEREO;
1736 if(device->Type != Loopback && !device->Hrtf && GetConfigValueBool(NULL, "wide-stereo", AL_FALSE))
1737 device->Flags |= DEVICE_WIDE_STEREO;
1739 if(!device->Hrtf && (device->UpdateSize&3))
1741 if((CPUCapFlags&CPU_CAP_SSE))
1742 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1745 SetMixerFPUMode(&oldMode);
1746 ALCdevice_Lock(device);
1747 context = device->ContextList;
1748 while(context)
1750 ALsizei pos;
1752 context->UpdateSources = AL_FALSE;
1753 LockUIntMapRead(&context->EffectSlotMap);
1754 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
1756 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
1758 if(VCALL(slot->EffectState,deviceUpdate,(device)) == AL_FALSE)
1760 UnlockUIntMapRead(&context->EffectSlotMap);
1761 ALCdevice_Unlock(device);
1762 RestoreFPUMode(&oldMode);
1763 return ALC_INVALID_DEVICE;
1765 slot->NeedsUpdate = AL_FALSE;
1766 VCALL(slot->EffectState,update,(device, slot));
1768 UnlockUIntMapRead(&context->EffectSlotMap);
1770 LockUIntMapRead(&context->SourceMap);
1771 for(pos = 0;pos < context->SourceMap.size;pos++)
1773 ALsource *source = context->SourceMap.array[pos].value;
1774 ALuint s = device->NumAuxSends;
1775 while(s < MAX_SENDS)
1777 if(source->Send[s].Slot)
1778 DecrementRef(&source->Send[s].Slot->ref);
1779 source->Send[s].Slot = NULL;
1780 source->Send[s].Gain = 1.0f;
1781 source->Send[s].GainHF = 1.0f;
1782 s++;
1784 source->NeedsUpdate = AL_FALSE;
1785 ALsource_Update(source, context);
1787 UnlockUIntMapRead(&context->SourceMap);
1789 context = context->next;
1791 if(device->DefaultSlot)
1793 ALeffectslot *slot = device->DefaultSlot;
1795 if(VCALL(slot->EffectState,deviceUpdate,(device)) == AL_FALSE)
1797 ALCdevice_Unlock(device);
1798 RestoreFPUMode(&oldMode);
1799 return ALC_INVALID_DEVICE;
1801 slot->NeedsUpdate = AL_FALSE;
1802 VCALL(slot->EffectState,update,(device, slot));
1804 ALCdevice_Unlock(device);
1805 RestoreFPUMode(&oldMode);
1807 if(ALCdevice_StartPlayback(device) == ALC_FALSE)
1808 return ALC_INVALID_DEVICE;
1809 device->Flags |= DEVICE_RUNNING;
1811 return ALC_NO_ERROR;
1814 /* FreeDevice
1816 * Frees the device structure, and destroys any objects the app failed to
1817 * delete. Called once there's no more references on the device.
1819 static ALCvoid FreeDevice(ALCdevice *device)
1821 TRACE("%p\n", device);
1823 if(device->Type != Capture)
1824 ALCdevice_ClosePlayback(device);
1825 else
1826 ALCdevice_CloseCapture(device);
1828 if(device->DefaultSlot)
1830 ALeffectState *state = device->DefaultSlot->EffectState;
1831 device->DefaultSlot = NULL;
1832 DELETE_OBJ(state);
1835 if(device->BufferMap.size > 0)
1837 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
1838 ReleaseALBuffers(device);
1840 ResetUIntMap(&device->BufferMap);
1842 if(device->EffectMap.size > 0)
1844 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
1845 ReleaseALEffects(device);
1847 ResetUIntMap(&device->EffectMap);
1849 if(device->FilterMap.size > 0)
1851 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
1852 ReleaseALFilters(device);
1854 ResetUIntMap(&device->FilterMap);
1856 free(device->Bs2b);
1857 device->Bs2b = NULL;
1859 free(device->DeviceName);
1860 device->DeviceName = NULL;
1862 DeleteCriticalSection(&device->Mutex);
1864 al_free(device);
1868 void ALCdevice_IncRef(ALCdevice *device)
1870 RefCount ref;
1871 ref = IncrementRef(&device->ref);
1872 TRACEREF("%p increasing refcount to %u\n", device, ref);
1875 void ALCdevice_DecRef(ALCdevice *device)
1877 RefCount ref;
1878 ref = DecrementRef(&device->ref);
1879 TRACEREF("%p decreasing refcount to %u\n", device, ref);
1880 if(ref == 0) FreeDevice(device);
1883 /* VerifyDevice
1885 * Checks if the device handle is valid, and increments its ref count if so.
1887 static ALCdevice *VerifyDevice(ALCdevice *device)
1889 ALCdevice *tmpDevice;
1891 if(!device)
1892 return NULL;
1894 LockLists();
1895 tmpDevice = DeviceList;
1896 while(tmpDevice && tmpDevice != device)
1897 tmpDevice = tmpDevice->next;
1899 if(tmpDevice)
1900 ALCdevice_IncRef(tmpDevice);
1901 UnlockLists();
1902 return tmpDevice;
1906 /* InitContext
1908 * Initializes context fields
1910 static ALvoid InitContext(ALCcontext *Context)
1912 ALint i, j;
1914 //Initialise listener
1915 Context->Listener->Gain = 1.0f;
1916 Context->Listener->MetersPerUnit = 1.0f;
1917 Context->Listener->Position[0] = 0.0f;
1918 Context->Listener->Position[1] = 0.0f;
1919 Context->Listener->Position[2] = 0.0f;
1920 Context->Listener->Velocity[0] = 0.0f;
1921 Context->Listener->Velocity[1] = 0.0f;
1922 Context->Listener->Velocity[2] = 0.0f;
1923 Context->Listener->Forward[0] = 0.0f;
1924 Context->Listener->Forward[1] = 0.0f;
1925 Context->Listener->Forward[2] = -1.0f;
1926 Context->Listener->Up[0] = 0.0f;
1927 Context->Listener->Up[1] = 1.0f;
1928 Context->Listener->Up[2] = 0.0f;
1929 for(i = 0;i < 4;i++)
1931 for(j = 0;j < 4;j++)
1932 Context->Listener->Params.Matrix[i][j] = ((i==j) ? 1.0f : 0.0f);
1934 for(i = 0;i < 3;i++)
1935 Context->Listener->Params.Velocity[i] = 0.0f;
1937 //Validate Context
1938 Context->LastError = AL_NO_ERROR;
1939 Context->UpdateSources = AL_FALSE;
1940 Context->ActiveSourceCount = 0;
1941 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
1942 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
1944 //Set globals
1945 Context->DistanceModel = DefaultDistanceModel;
1946 Context->SourceDistanceModel = AL_FALSE;
1947 Context->DopplerFactor = 1.0f;
1948 Context->DopplerVelocity = 1.0f;
1949 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
1950 Context->DeferUpdates = AL_FALSE;
1952 Context->ExtensionList = alExtList;
1956 /* FreeContext
1958 * Cleans up the context, and destroys any remaining objects the app failed to
1959 * delete. Called once there's no more references on the context.
1961 static ALCvoid FreeContext(ALCcontext *context)
1963 TRACE("%p\n", context);
1965 if(context->SourceMap.size > 0)
1967 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
1968 ReleaseALSources(context);
1970 ResetUIntMap(&context->SourceMap);
1972 if(context->EffectSlotMap.size > 0)
1974 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
1975 ReleaseALAuxiliaryEffectSlots(context);
1977 ResetUIntMap(&context->EffectSlotMap);
1979 context->ActiveSourceCount = 0;
1980 free(context->ActiveSources);
1981 context->ActiveSources = NULL;
1982 context->MaxActiveSources = 0;
1984 context->ActiveEffectSlotCount = 0;
1985 free(context->ActiveEffectSlots);
1986 context->ActiveEffectSlots = NULL;
1987 context->MaxActiveEffectSlots = 0;
1989 ALCdevice_DecRef(context->Device);
1990 context->Device = NULL;
1992 //Invalidate context
1993 memset(context, 0, sizeof(ALCcontext));
1994 free(context);
1997 /* ReleaseContext
1999 * Removes the context reference from the given device and removes it from
2000 * being current on the running thread or globally.
2002 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2004 ALCcontext *volatile*tmp_ctx;
2006 if(pthread_getspecific(LocalContext) == context)
2008 WARN("%p released while current on thread\n", context);
2009 pthread_setspecific(LocalContext, NULL);
2010 ALCcontext_DecRef(context);
2013 if(CompExchangePtr((XchgPtr*)&GlobalContext, context, NULL))
2014 ALCcontext_DecRef(context);
2016 ALCdevice_Lock(device);
2017 tmp_ctx = &device->ContextList;
2018 while(*tmp_ctx)
2020 if(CompExchangePtr((XchgPtr*)tmp_ctx, context, context->next))
2021 break;
2022 tmp_ctx = &(*tmp_ctx)->next;
2024 ALCdevice_Unlock(device);
2026 ALCcontext_DecRef(context);
2029 void ALCcontext_IncRef(ALCcontext *context)
2031 RefCount ref;
2032 ref = IncrementRef(&context->ref);
2033 TRACEREF("%p increasing refcount to %u\n", context, ref);
2036 void ALCcontext_DecRef(ALCcontext *context)
2038 RefCount ref;
2039 ref = DecrementRef(&context->ref);
2040 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2041 if(ref == 0) FreeContext(context);
2044 static void ReleaseThreadCtx(void *ptr)
2046 WARN("%p current for thread being destroyed\n", ptr);
2047 ALCcontext_DecRef(ptr);
2050 /* VerifyContext
2052 * Checks that the given context is valid, and increments its reference count.
2054 static ALCcontext *VerifyContext(ALCcontext *context)
2056 ALCdevice *dev;
2058 LockLists();
2059 dev = DeviceList;
2060 while(dev)
2062 ALCcontext *tmp_ctx = dev->ContextList;
2063 while(tmp_ctx)
2065 if(tmp_ctx == context)
2067 ALCcontext_IncRef(tmp_ctx);
2068 UnlockLists();
2069 return tmp_ctx;
2071 tmp_ctx = tmp_ctx->next;
2073 dev = dev->next;
2075 UnlockLists();
2077 return NULL;
2081 /* GetContextRef
2083 * Returns the currently active context for this thread, and adds a reference
2084 * without locking it.
2086 ALCcontext *GetContextRef(void)
2088 ALCcontext *context;
2090 context = pthread_getspecific(LocalContext);
2091 if(context)
2092 ALCcontext_IncRef(context);
2093 else
2095 LockLists();
2096 context = GlobalContext;
2097 if(context)
2098 ALCcontext_IncRef(context);
2099 UnlockLists();
2102 return context;
2106 /************************************************
2107 * Standard ALC functions
2108 ************************************************/
2110 /* alcGetError
2112 * Return last ALC generated error code for the given device
2114 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2116 ALCenum errorCode;
2118 if(VerifyDevice(device))
2120 errorCode = ExchangeInt(&device->LastError, ALC_NO_ERROR);
2121 ALCdevice_DecRef(device);
2123 else
2124 errorCode = ExchangeInt(&LastNullDeviceError, ALC_NO_ERROR);
2126 return errorCode;
2130 /* alcSuspendContext
2132 * Not functional
2134 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *UNUSED(context))
2138 /* alcProcessContext
2140 * Not functional
2142 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *UNUSED(context))
2147 /* alcGetString
2149 * Returns information about the device, and error strings
2151 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2153 const ALCchar *value = NULL;
2155 switch(param)
2157 case ALC_NO_ERROR:
2158 value = alcNoError;
2159 break;
2161 case ALC_INVALID_ENUM:
2162 value = alcErrInvalidEnum;
2163 break;
2165 case ALC_INVALID_VALUE:
2166 value = alcErrInvalidValue;
2167 break;
2169 case ALC_INVALID_DEVICE:
2170 value = alcErrInvalidDevice;
2171 break;
2173 case ALC_INVALID_CONTEXT:
2174 value = alcErrInvalidContext;
2175 break;
2177 case ALC_OUT_OF_MEMORY:
2178 value = alcErrOutOfMemory;
2179 break;
2181 case ALC_DEVICE_SPECIFIER:
2182 value = alcDefaultName;
2183 break;
2185 case ALC_ALL_DEVICES_SPECIFIER:
2186 if(VerifyDevice(Device))
2188 value = Device->DeviceName;
2189 ALCdevice_DecRef(Device);
2191 else
2193 ProbeAllDevicesList();
2194 value = alcAllDevicesList;
2196 break;
2198 case ALC_CAPTURE_DEVICE_SPECIFIER:
2199 if(VerifyDevice(Device))
2201 value = Device->DeviceName;
2202 ALCdevice_DecRef(Device);
2204 else
2206 ProbeCaptureDeviceList();
2207 value = alcCaptureDeviceList;
2209 break;
2211 /* Default devices are always first in the list */
2212 case ALC_DEFAULT_DEVICE_SPECIFIER:
2213 value = alcDefaultName;
2214 break;
2216 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2217 if(!alcAllDevicesList)
2218 ProbeAllDevicesList();
2220 Device = VerifyDevice(Device);
2222 free(alcDefaultAllDevicesSpecifier);
2223 alcDefaultAllDevicesSpecifier = strdup(alcAllDevicesList ?
2224 alcAllDevicesList : "");
2225 if(!alcDefaultAllDevicesSpecifier)
2226 alcSetError(Device, ALC_OUT_OF_MEMORY);
2228 value = alcDefaultAllDevicesSpecifier;
2229 if(Device) ALCdevice_DecRef(Device);
2230 break;
2232 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2233 if(!alcCaptureDeviceList)
2234 ProbeCaptureDeviceList();
2236 Device = VerifyDevice(Device);
2238 free(alcCaptureDefaultDeviceSpecifier);
2239 alcCaptureDefaultDeviceSpecifier = strdup(alcCaptureDeviceList ?
2240 alcCaptureDeviceList : "");
2241 if(!alcCaptureDefaultDeviceSpecifier)
2242 alcSetError(Device, ALC_OUT_OF_MEMORY);
2244 value = alcCaptureDefaultDeviceSpecifier;
2245 if(Device) ALCdevice_DecRef(Device);
2246 break;
2248 case ALC_EXTENSIONS:
2249 if(!VerifyDevice(Device))
2250 value = alcNoDeviceExtList;
2251 else
2253 value = alcExtensionList;
2254 ALCdevice_DecRef(Device);
2256 break;
2258 default:
2259 Device = VerifyDevice(Device);
2260 alcSetError(Device, ALC_INVALID_ENUM);
2261 if(Device) ALCdevice_DecRef(Device);
2262 break;
2265 return value;
2269 /* alcGetIntegerv
2271 * Returns information about the device and the version of OpenAL
2273 ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsizei size,ALCint *data)
2275 device = VerifyDevice(device);
2277 if(size == 0 || data == NULL)
2279 alcSetError(device, ALC_INVALID_VALUE);
2280 if(device) ALCdevice_DecRef(device);
2281 return;
2284 if(!device)
2286 switch(param)
2288 case ALC_MAJOR_VERSION:
2289 *data = alcMajorVersion;
2290 break;
2291 case ALC_MINOR_VERSION:
2292 *data = alcMinorVersion;
2293 break;
2295 case ALC_ATTRIBUTES_SIZE:
2296 case ALC_ALL_ATTRIBUTES:
2297 case ALC_FREQUENCY:
2298 case ALC_REFRESH:
2299 case ALC_SYNC:
2300 case ALC_MONO_SOURCES:
2301 case ALC_STEREO_SOURCES:
2302 case ALC_CAPTURE_SAMPLES:
2303 case ALC_FORMAT_CHANNELS_SOFT:
2304 case ALC_FORMAT_TYPE_SOFT:
2305 alcSetError(NULL, ALC_INVALID_DEVICE);
2306 break;
2308 default:
2309 alcSetError(NULL, ALC_INVALID_ENUM);
2310 break;
2313 else if(device->Type == Capture)
2315 switch(param)
2317 case ALC_CAPTURE_SAMPLES:
2318 ALCdevice_Lock(device);
2319 *data = ALCdevice_AvailableSamples(device);
2320 ALCdevice_Unlock(device);
2321 break;
2323 case ALC_CONNECTED:
2324 *data = device->Connected;
2325 break;
2327 default:
2328 alcSetError(device, ALC_INVALID_ENUM);
2329 break;
2332 else /* render device */
2334 switch(param)
2336 case ALC_MAJOR_VERSION:
2337 *data = alcMajorVersion;
2338 break;
2340 case ALC_MINOR_VERSION:
2341 *data = alcMinorVersion;
2342 break;
2344 case ALC_EFX_MAJOR_VERSION:
2345 *data = alcEFXMajorVersion;
2346 break;
2348 case ALC_EFX_MINOR_VERSION:
2349 *data = alcEFXMinorVersion;
2350 break;
2352 case ALC_ATTRIBUTES_SIZE:
2353 *data = 15;
2354 break;
2356 case ALC_ALL_ATTRIBUTES:
2357 if(size < 15)
2358 alcSetError(device, ALC_INVALID_VALUE);
2359 else
2361 int i = 0;
2363 data[i++] = ALC_FREQUENCY;
2364 data[i++] = device->Frequency;
2366 if(device->Type != Loopback)
2368 data[i++] = ALC_REFRESH;
2369 data[i++] = device->Frequency / device->UpdateSize;
2371 data[i++] = ALC_SYNC;
2372 data[i++] = ALC_FALSE;
2374 else
2376 data[i++] = ALC_FORMAT_CHANNELS_SOFT;
2377 data[i++] = device->FmtChans;
2379 data[i++] = ALC_FORMAT_TYPE_SOFT;
2380 data[i++] = device->FmtType;
2383 data[i++] = ALC_MONO_SOURCES;
2384 data[i++] = device->NumMonoSources;
2386 data[i++] = ALC_STEREO_SOURCES;
2387 data[i++] = device->NumStereoSources;
2389 data[i++] = ALC_MAX_AUXILIARY_SENDS;
2390 data[i++] = device->NumAuxSends;
2392 data[i++] = ALC_HRTF_SOFT;
2393 data[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2395 data[i++] = 0;
2397 break;
2399 case ALC_FREQUENCY:
2400 *data = device->Frequency;
2401 break;
2403 case ALC_REFRESH:
2404 if(device->Type == Loopback)
2405 alcSetError(device, ALC_INVALID_DEVICE);
2406 else
2407 *data = device->Frequency / device->UpdateSize;
2408 break;
2410 case ALC_SYNC:
2411 if(device->Type == Loopback)
2412 alcSetError(device, ALC_INVALID_DEVICE);
2413 else
2414 *data = ALC_FALSE;
2415 break;
2417 case ALC_FORMAT_CHANNELS_SOFT:
2418 if(device->Type != Loopback)
2419 alcSetError(device, ALC_INVALID_DEVICE);
2420 else
2421 *data = device->FmtChans;
2422 break;
2424 case ALC_FORMAT_TYPE_SOFT:
2425 if(device->Type != Loopback)
2426 alcSetError(device, ALC_INVALID_DEVICE);
2427 else
2428 *data = device->FmtType;
2429 break;
2431 case ALC_MONO_SOURCES:
2432 *data = device->NumMonoSources;
2433 break;
2435 case ALC_STEREO_SOURCES:
2436 *data = device->NumStereoSources;
2437 break;
2439 case ALC_MAX_AUXILIARY_SENDS:
2440 *data = device->NumAuxSends;
2441 break;
2443 case ALC_CONNECTED:
2444 *data = device->Connected;
2445 break;
2447 case ALC_HRTF_SOFT:
2448 *data = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2449 break;
2451 default:
2452 alcSetError(device, ALC_INVALID_ENUM);
2453 break;
2456 if(device)
2457 ALCdevice_DecRef(device);
2461 /* alcIsExtensionPresent
2463 * Determines if there is support for a particular extension
2465 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2467 ALCboolean bResult = ALC_FALSE;
2469 device = VerifyDevice(device);
2471 if(!extName)
2472 alcSetError(device, ALC_INVALID_VALUE);
2473 else
2475 size_t len = strlen(extName);
2476 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2477 while(ptr && *ptr)
2479 if(strncasecmp(ptr, extName, len) == 0 &&
2480 (ptr[len] == '\0' || isspace(ptr[len])))
2482 bResult = ALC_TRUE;
2483 break;
2485 if((ptr=strchr(ptr, ' ')) != NULL)
2487 do {
2488 ++ptr;
2489 } while(isspace(*ptr));
2493 if(device)
2494 ALCdevice_DecRef(device);
2495 return bResult;
2499 /* alcGetProcAddress
2501 * Retrieves the function address for a particular extension function
2503 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2505 ALCvoid *ptr = NULL;
2507 if(!funcName)
2509 device = VerifyDevice(device);
2510 alcSetError(device, ALC_INVALID_VALUE);
2511 if(device) ALCdevice_DecRef(device);
2513 else
2515 ALsizei i = 0;
2516 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
2517 i++;
2518 ptr = alcFunctions[i].address;
2521 return ptr;
2525 /* alcGetEnumValue
2527 * Get the value for a particular ALC enumeration name
2529 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
2531 ALCenum val = 0;
2533 if(!enumName)
2535 device = VerifyDevice(device);
2536 alcSetError(device, ALC_INVALID_VALUE);
2537 if(device) ALCdevice_DecRef(device);
2539 else
2541 ALsizei i = 0;
2542 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
2543 i++;
2544 val = enumeration[i].value;
2547 return val;
2551 /* alcCreateContext
2553 * Create and attach a context to the given device.
2555 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
2557 ALCcontext *ALContext;
2558 ALCenum err;
2560 LockLists();
2561 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
2563 UnlockLists();
2564 alcSetError(device, ALC_INVALID_DEVICE);
2565 if(device) ALCdevice_DecRef(device);
2566 return NULL;
2569 device->LastError = ALC_NO_ERROR;
2571 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
2573 UnlockLists();
2574 alcSetError(device, err);
2575 if(err == ALC_INVALID_DEVICE)
2577 ALCdevice_Lock(device);
2578 aluHandleDisconnect(device);
2579 ALCdevice_Unlock(device);
2581 ALCdevice_DecRef(device);
2582 return NULL;
2585 ALContext = calloc(1, sizeof(ALCcontext)+15+sizeof(ALlistener));
2586 if(ALContext)
2588 ALContext->ref = 1;
2589 ALContext->Listener = (ALlistener*)(((ALintptrEXT)(ALContext+1)+15)&~15);
2591 ALContext->MaxActiveSources = 256;
2592 ALContext->ActiveSources = malloc(sizeof(ALContext->ActiveSources[0]) *
2593 ALContext->MaxActiveSources);
2595 if(!ALContext || !ALContext->ActiveSources)
2597 if(!device->ContextList)
2599 ALCdevice_StopPlayback(device);
2600 device->Flags &= ~DEVICE_RUNNING;
2602 UnlockLists();
2604 free(ALContext);
2605 ALContext = NULL;
2607 alcSetError(device, ALC_OUT_OF_MEMORY);
2608 ALCdevice_DecRef(device);
2609 return NULL;
2612 ALContext->Device = device;
2613 ALCdevice_IncRef(device);
2614 InitContext(ALContext);
2616 do {
2617 ALContext->next = device->ContextList;
2618 } while(!CompExchangePtr((XchgPtr*)&device->ContextList, ALContext->next, ALContext));
2619 UnlockLists();
2621 ALCdevice_DecRef(device);
2623 TRACE("Created context %p\n", ALContext);
2624 return ALContext;
2627 /* alcDestroyContext
2629 * Remove a context from its device
2631 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
2633 ALCdevice *Device;
2635 LockLists();
2636 /* alcGetContextsDevice sets an error for invalid contexts */
2637 Device = alcGetContextsDevice(context);
2638 if(Device)
2640 ReleaseContext(context, Device);
2641 if(!Device->ContextList)
2643 ALCdevice_StopPlayback(Device);
2644 Device->Flags &= ~DEVICE_RUNNING;
2647 UnlockLists();
2651 /* alcGetCurrentContext
2653 * Returns the currently active context on the calling thread
2655 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
2657 ALCcontext *Context;
2659 Context = pthread_getspecific(LocalContext);
2660 if(!Context) Context = GlobalContext;
2662 return Context;
2665 /* alcGetThreadContext
2667 * Returns the currently active thread-local context
2669 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
2671 ALCcontext *Context;
2672 Context = pthread_getspecific(LocalContext);
2673 return Context;
2677 /* alcMakeContextCurrent
2679 * Makes the given context the active process-wide context, and removes the
2680 * thread-local context for the calling thread.
2682 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
2684 /* context must be valid or NULL */
2685 if(context && !(context=VerifyContext(context)))
2687 alcSetError(NULL, ALC_INVALID_CONTEXT);
2688 return ALC_FALSE;
2690 /* context's reference count is already incremented */
2691 context = ExchangePtr((XchgPtr*)&GlobalContext, context);
2692 if(context) ALCcontext_DecRef(context);
2694 if((context=pthread_getspecific(LocalContext)) != NULL)
2696 pthread_setspecific(LocalContext, NULL);
2697 ALCcontext_DecRef(context);
2700 return ALC_TRUE;
2703 /* alcSetThreadContext
2705 * Makes the given context the active context for the current thread
2707 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
2709 ALCcontext *old;
2711 /* context must be valid or NULL */
2712 if(context && !(context=VerifyContext(context)))
2714 alcSetError(NULL, ALC_INVALID_CONTEXT);
2715 return ALC_FALSE;
2717 /* context's reference count is already incremented */
2718 old = pthread_getspecific(LocalContext);
2719 pthread_setspecific(LocalContext, context);
2720 if(old) ALCcontext_DecRef(old);
2722 return ALC_TRUE;
2726 /* alcGetContextsDevice
2728 * Returns the device that a particular context is attached to
2730 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
2732 ALCdevice *Device;
2734 if(!(Context=VerifyContext(Context)))
2736 alcSetError(NULL, ALC_INVALID_CONTEXT);
2737 return NULL;
2739 Device = Context->Device;
2740 ALCcontext_DecRef(Context);
2742 return Device;
2746 /* alcOpenDevice
2748 * Opens the named device.
2750 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
2752 const ALCchar *fmt;
2753 ALCdevice *device;
2754 ALCenum err;
2756 DO_INITCONFIG();
2758 if(!PlaybackBackend.name)
2760 alcSetError(NULL, ALC_INVALID_VALUE);
2761 return NULL;
2764 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
2765 deviceName = NULL;
2767 device = al_calloc(16, sizeof(ALCdevice)+15+sizeof(ALeffectslot));
2768 if(!device)
2770 alcSetError(NULL, ALC_OUT_OF_MEMORY);
2771 return NULL;
2774 //Validate device
2775 device->Funcs = &PlaybackBackend.Funcs;
2776 device->ref = 1;
2777 device->Connected = ALC_TRUE;
2778 device->Type = Playback;
2779 InitializeCriticalSection(&device->Mutex);
2780 device->LastError = ALC_NO_ERROR;
2782 device->Flags = 0;
2783 device->Bs2b = NULL;
2784 device->Bs2bLevel = 0;
2785 device->DeviceName = NULL;
2787 device->ContextList = NULL;
2789 device->MaxNoOfSources = 256;
2790 device->AuxiliaryEffectSlotMax = 4;
2791 device->NumAuxSends = MAX_SENDS;
2793 InitUIntMap(&device->BufferMap, ~0);
2794 InitUIntMap(&device->EffectMap, ~0);
2795 InitUIntMap(&device->FilterMap, ~0);
2797 //Set output format
2798 device->FmtChans = DevFmtChannelsDefault;
2799 device->FmtType = DevFmtTypeDefault;
2800 device->Frequency = DEFAULT_OUTPUT_RATE;
2801 device->NumUpdates = 4;
2802 device->UpdateSize = 1024;
2804 if(ConfigValueStr(NULL, "channels", &fmt))
2806 static const struct {
2807 const char name[16];
2808 enum DevFmtChannels chans;
2809 } chanlist[] = {
2810 { "mono", DevFmtMono },
2811 { "stereo", DevFmtStereo },
2812 { "quad", DevFmtQuad },
2813 { "surround51", DevFmtX51 },
2814 { "surround61", DevFmtX61 },
2815 { "surround71", DevFmtX71 },
2817 size_t i;
2819 for(i = 0;i < COUNTOF(chanlist);i++)
2821 if(strcasecmp(chanlist[i].name, fmt) == 0)
2823 device->FmtChans = chanlist[i].chans;
2824 device->Flags |= DEVICE_CHANNELS_REQUEST;
2825 break;
2828 if(i == COUNTOF(chanlist))
2829 ERR("Unsupported channels: %s\n", fmt);
2831 if(ConfigValueStr(NULL, "sample-type", &fmt))
2833 static const struct {
2834 const char name[16];
2835 enum DevFmtType type;
2836 } typelist[] = {
2837 { "int8", DevFmtByte },
2838 { "uint8", DevFmtUByte },
2839 { "int16", DevFmtShort },
2840 { "uint16", DevFmtUShort },
2841 { "int32", DevFmtInt },
2842 { "uint32", DevFmtUInt },
2843 { "float32", DevFmtFloat },
2845 size_t i;
2847 for(i = 0;i < COUNTOF(typelist);i++)
2849 if(strcasecmp(typelist[i].name, fmt) == 0)
2851 device->FmtType = typelist[i].type;
2852 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
2853 break;
2856 if(i == COUNTOF(typelist))
2857 ERR("Unsupported sample-type: %s\n", fmt);
2859 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
2860 if((device->Flags&DEVICE_FORMAT_REQUEST) != DEVICE_FORMAT_REQUEST &&
2861 ConfigValueStr(NULL, "format", &fmt))
2863 static const struct {
2864 const char name[32];
2865 enum DevFmtChannels channels;
2866 enum DevFmtType type;
2867 } formats[] = {
2868 { "AL_FORMAT_MONO32", DevFmtMono, DevFmtFloat },
2869 { "AL_FORMAT_STEREO32", DevFmtStereo, DevFmtFloat },
2870 { "AL_FORMAT_QUAD32", DevFmtQuad, DevFmtFloat },
2871 { "AL_FORMAT_51CHN32", DevFmtX51, DevFmtFloat },
2872 { "AL_FORMAT_61CHN32", DevFmtX61, DevFmtFloat },
2873 { "AL_FORMAT_71CHN32", DevFmtX71, DevFmtFloat },
2875 { "AL_FORMAT_MONO16", DevFmtMono, DevFmtShort },
2876 { "AL_FORMAT_STEREO16", DevFmtStereo, DevFmtShort },
2877 { "AL_FORMAT_QUAD16", DevFmtQuad, DevFmtShort },
2878 { "AL_FORMAT_51CHN16", DevFmtX51, DevFmtShort },
2879 { "AL_FORMAT_61CHN16", DevFmtX61, DevFmtShort },
2880 { "AL_FORMAT_71CHN16", DevFmtX71, DevFmtShort },
2882 { "AL_FORMAT_MONO8", DevFmtMono, DevFmtByte },
2883 { "AL_FORMAT_STEREO8", DevFmtStereo, DevFmtByte },
2884 { "AL_FORMAT_QUAD8", DevFmtQuad, DevFmtByte },
2885 { "AL_FORMAT_51CHN8", DevFmtX51, DevFmtByte },
2886 { "AL_FORMAT_61CHN8", DevFmtX61, DevFmtByte },
2887 { "AL_FORMAT_71CHN8", DevFmtX71, DevFmtByte }
2889 size_t i;
2891 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
2892 for(i = 0;i < COUNTOF(formats);i++)
2894 if(strcasecmp(fmt, formats[i].name) == 0)
2896 if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
2897 device->FmtChans = formats[i].channels;
2898 if(!(device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2899 device->FmtType = formats[i].type;
2900 device->Flags |= DEVICE_FORMAT_REQUEST;
2901 break;
2904 if(i == COUNTOF(formats))
2905 ERR("Unsupported format: %s\n", fmt);
2907 #undef DEVICE_FORMAT_REQUEST
2909 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
2911 device->Flags |= DEVICE_FREQUENCY_REQUEST;
2912 if(device->Frequency < MIN_OUTPUT_RATE)
2913 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
2914 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
2917 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
2918 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
2920 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
2921 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
2922 if((CPUCapFlags&CPU_CAP_SSE))
2923 device->UpdateSize = (device->UpdateSize+3)&~3;
2925 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
2926 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
2928 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
2929 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
2931 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
2932 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
2934 ConfigValueInt(NULL, "cf_level", &device->Bs2bLevel);
2936 device->NumStereoSources = 1;
2937 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
2939 // Find a playback device to open
2940 if((err=ALCdevice_OpenPlayback(device, deviceName)) != ALC_NO_ERROR)
2942 DeleteCriticalSection(&device->Mutex);
2943 al_free(device);
2944 alcSetError(NULL, err);
2945 return NULL;
2948 if(DefaultEffect.type != AL_EFFECT_NULL)
2950 device->DefaultSlot = (ALeffectslot*)(((ALintptrEXT)(device+1)+15)&~15);
2951 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
2953 device->DefaultSlot = NULL;
2954 ERR("Failed to initialize the default effect slot\n");
2956 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
2958 ALeffectState *state = device->DefaultSlot->EffectState;
2959 device->DefaultSlot = NULL;
2960 DELETE_OBJ(state);
2961 ERR("Failed to initialize the default effect\n");
2965 do {
2966 device->next = DeviceList;
2967 } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device));
2969 TRACE("Created device %p, \"%s\"\n", device, device->DeviceName);
2970 return device;
2973 /* alcCloseDevice
2975 * Closes the given device.
2977 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *Device)
2979 ALCdevice *volatile*list;
2980 ALCcontext *ctx;
2982 LockLists();
2983 list = &DeviceList;
2984 while(*list && *list != Device)
2985 list = &(*list)->next;
2987 if(!*list || (*list)->Type == Capture)
2989 alcSetError(*list, ALC_INVALID_DEVICE);
2990 UnlockLists();
2991 return ALC_FALSE;
2994 *list = (*list)->next;
2995 UnlockLists();
2997 while((ctx=Device->ContextList) != NULL)
2999 WARN("Releasing context %p\n", ctx);
3000 ReleaseContext(ctx, Device);
3002 if((Device->Flags&DEVICE_RUNNING))
3003 ALCdevice_StopPlayback(Device);
3004 Device->Flags &= ~DEVICE_RUNNING;
3006 ALCdevice_DecRef(Device);
3008 return ALC_TRUE;
3012 /************************************************
3013 * ALC capture functions
3014 ************************************************/
3015 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3017 ALCdevice *device = NULL;
3018 ALCenum err;
3020 DO_INITCONFIG();
3022 if(!CaptureBackend.name)
3024 alcSetError(NULL, ALC_INVALID_VALUE);
3025 return NULL;
3028 if(samples <= 0)
3030 alcSetError(NULL, ALC_INVALID_VALUE);
3031 return NULL;
3034 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3035 deviceName = NULL;
3037 device = al_calloc(16, sizeof(ALCdevice));
3038 if(!device)
3040 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3041 return NULL;
3044 //Validate device
3045 device->Funcs = &CaptureBackend.Funcs;
3046 device->ref = 1;
3047 device->Connected = ALC_TRUE;
3048 device->Type = Capture;
3049 InitializeCriticalSection(&device->Mutex);
3051 InitUIntMap(&device->BufferMap, ~0);
3052 InitUIntMap(&device->EffectMap, ~0);
3053 InitUIntMap(&device->FilterMap, ~0);
3055 device->DeviceName = NULL;
3057 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3058 device->Frequency = frequency;
3060 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3061 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3063 DeleteCriticalSection(&device->Mutex);
3064 al_free(device);
3065 alcSetError(NULL, ALC_INVALID_ENUM);
3066 return NULL;
3069 device->UpdateSize = samples;
3070 device->NumUpdates = 1;
3072 if((err=ALCdevice_OpenCapture(device, deviceName)) != ALC_NO_ERROR)
3074 DeleteCriticalSection(&device->Mutex);
3075 al_free(device);
3076 alcSetError(NULL, err);
3077 return NULL;
3080 do {
3081 device->next = DeviceList;
3082 } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device));
3084 TRACE("Created device %p, \"%s\"\n", device, device->DeviceName);
3085 return device;
3088 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *Device)
3090 ALCdevice *volatile*list;
3092 LockLists();
3093 list = &DeviceList;
3094 while(*list && *list != Device)
3095 list = &(*list)->next;
3097 if(!*list || (*list)->Type != Capture)
3099 alcSetError(*list, ALC_INVALID_DEVICE);
3100 UnlockLists();
3101 return ALC_FALSE;
3104 *list = (*list)->next;
3105 UnlockLists();
3107 ALCdevice_DecRef(Device);
3109 return ALC_TRUE;
3112 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3114 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3115 alcSetError(device, ALC_INVALID_DEVICE);
3116 else
3118 ALCdevice_Lock(device);
3119 if(device->Connected)
3121 if(!(device->Flags&DEVICE_RUNNING))
3122 ALCdevice_StartCapture(device);
3123 device->Flags |= DEVICE_RUNNING;
3125 ALCdevice_Unlock(device);
3128 if(device) ALCdevice_DecRef(device);
3131 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3133 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3134 alcSetError(device, ALC_INVALID_DEVICE);
3135 else
3137 ALCdevice_Lock(device);
3138 if((device->Flags&DEVICE_RUNNING))
3139 ALCdevice_StopCapture(device);
3140 device->Flags &= ~DEVICE_RUNNING;
3141 ALCdevice_Unlock(device);
3144 if(device) ALCdevice_DecRef(device);
3147 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3149 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3150 alcSetError(device, ALC_INVALID_DEVICE);
3151 else
3153 ALCenum err = ALC_INVALID_VALUE;
3155 ALCdevice_Lock(device);
3156 if(samples >= 0 && ALCdevice_AvailableSamples(device) >= (ALCuint)samples)
3157 err = ALCdevice_CaptureSamples(device, buffer, samples);
3158 ALCdevice_Unlock(device);
3160 if(err != ALC_NO_ERROR)
3161 alcSetError(device, err);
3163 if(device) ALCdevice_DecRef(device);
3167 /************************************************
3168 * ALC loopback functions
3169 ************************************************/
3171 /* alcLoopbackOpenDeviceSOFT
3173 * Open a loopback device, for manual rendering.
3175 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3177 ALCdevice *device;
3179 DO_INITCONFIG();
3181 /* Make sure the device name, if specified, is us. */
3182 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3184 alcSetError(NULL, ALC_INVALID_VALUE);
3185 return NULL;
3188 device = al_calloc(16, sizeof(ALCdevice));
3189 if(!device)
3191 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3192 return NULL;
3195 //Validate device
3196 device->Funcs = &BackendLoopback.Funcs;
3197 device->ref = 1;
3198 device->Connected = ALC_TRUE;
3199 device->Type = Loopback;
3200 InitializeCriticalSection(&device->Mutex);
3201 device->LastError = ALC_NO_ERROR;
3203 device->Flags = 0;
3204 device->Bs2b = NULL;
3205 device->Bs2bLevel = 0;
3206 device->DeviceName = NULL;
3208 device->ContextList = NULL;
3210 device->MaxNoOfSources = 256;
3211 device->AuxiliaryEffectSlotMax = 4;
3212 device->NumAuxSends = MAX_SENDS;
3214 InitUIntMap(&device->BufferMap, ~0);
3215 InitUIntMap(&device->EffectMap, ~0);
3216 InitUIntMap(&device->FilterMap, ~0);
3218 //Set output format
3219 device->NumUpdates = 0;
3220 device->UpdateSize = 0;
3222 device->Frequency = DEFAULT_OUTPUT_RATE;
3223 device->FmtChans = DevFmtChannelsDefault;
3224 device->FmtType = DevFmtTypeDefault;
3226 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3227 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3229 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3230 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3232 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3233 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3235 device->NumStereoSources = 1;
3236 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3238 // Open the "backend"
3239 ALCdevice_OpenPlayback(device, "Loopback");
3240 do {
3241 device->next = DeviceList;
3242 } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device));
3244 TRACE("Created device %p\n", device);
3245 return device;
3248 /* alcIsRenderFormatSupportedSOFT
3250 * Determines if the loopback device supports the given format for rendering.
3252 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3254 ALCboolean ret = ALC_FALSE;
3256 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3257 alcSetError(device, ALC_INVALID_DEVICE);
3258 else if(freq <= 0)
3259 alcSetError(device, ALC_INVALID_VALUE);
3260 else
3262 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3263 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3264 freq >= MIN_OUTPUT_RATE)
3265 ret = ALC_TRUE;
3267 if(device) ALCdevice_DecRef(device);
3269 return ret;
3272 /* alcRenderSamplesSOFT
3274 * Renders some samples into a buffer, using the format last set by the
3275 * attributes given to alcCreateContext.
3277 ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3279 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3280 alcSetError(device, ALC_INVALID_DEVICE);
3281 else if(samples < 0 || (samples > 0 && buffer == NULL))
3282 alcSetError(device, ALC_INVALID_VALUE);
3283 else
3284 aluMixData(device, buffer, samples);
3285 if(device) ALCdevice_DecRef(device);