Trace the opened device name in alcCaptureOpenDevice
[openal-soft.git] / Alc / ALc.c
blobabd2a01f5d0d839331650b2c7e1cb339c4fb61f9
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_MMDEVAPI
66 { "mmdevapi", alcMMDevApiInit, alcMMDevApiDeinit, alcMMDevApiProbe, EmptyFuncs },
67 #endif
68 #ifdef HAVE_DSOUND
69 { "dsound", alcDSoundInit, alcDSoundDeinit, alcDSoundProbe, EmptyFuncs },
70 #endif
71 #ifdef HAVE_WINMM
72 { "winmm", alcWinMMInit, alcWinMMDeinit, alcWinMMProbe, EmptyFuncs },
73 #endif
74 #ifdef HAVE_PORTAUDIO
75 { "port", alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs },
76 #endif
77 #ifdef HAVE_OPENSL
78 { "opensl", alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
79 #endif
81 { "null", alc_null_init, alc_null_deinit, alc_null_probe, EmptyFuncs },
82 #ifdef HAVE_WAVE
83 { "wave", alc_wave_init, alc_wave_deinit, alc_wave_probe, EmptyFuncs },
84 #endif
86 { NULL, NULL, NULL, NULL, EmptyFuncs }
88 static struct BackendInfo BackendLoopback = {
89 "loopback", alc_loopback_init, alc_loopback_deinit, alc_loopback_probe, EmptyFuncs
91 #undef EmptyFuncs
93 static struct BackendInfo PlaybackBackend;
94 static struct BackendInfo CaptureBackend;
96 /************************************************
97 * Functions, enums, and errors
98 ************************************************/
99 typedef struct ALCfunction {
100 const ALCchar *funcName;
101 ALCvoid *address;
102 } ALCfunction;
104 typedef struct ALCenums {
105 const ALCchar *enumName;
106 ALCenum value;
107 } ALCenums;
109 #define DECL(x) { #x, (ALCvoid*)(x) }
110 static const ALCfunction alcFunctions[] = {
111 DECL(alcCreateContext),
112 DECL(alcMakeContextCurrent),
113 DECL(alcProcessContext),
114 DECL(alcSuspendContext),
115 DECL(alcDestroyContext),
116 DECL(alcGetCurrentContext),
117 DECL(alcGetContextsDevice),
118 DECL(alcOpenDevice),
119 DECL(alcCloseDevice),
120 DECL(alcGetError),
121 DECL(alcIsExtensionPresent),
122 DECL(alcGetProcAddress),
123 DECL(alcGetEnumValue),
124 DECL(alcGetString),
125 DECL(alcGetIntegerv),
126 DECL(alcCaptureOpenDevice),
127 DECL(alcCaptureCloseDevice),
128 DECL(alcCaptureStart),
129 DECL(alcCaptureStop),
130 DECL(alcCaptureSamples),
132 DECL(alcSetThreadContext),
133 DECL(alcGetThreadContext),
135 DECL(alcLoopbackOpenDeviceSOFT),
136 DECL(alcIsRenderFormatSupportedSOFT),
137 DECL(alcRenderSamplesSOFT),
139 DECL(alEnable),
140 DECL(alDisable),
141 DECL(alIsEnabled),
142 DECL(alGetString),
143 DECL(alGetBooleanv),
144 DECL(alGetIntegerv),
145 DECL(alGetFloatv),
146 DECL(alGetDoublev),
147 DECL(alGetBoolean),
148 DECL(alGetInteger),
149 DECL(alGetFloat),
150 DECL(alGetDouble),
151 DECL(alGetError),
152 DECL(alIsExtensionPresent),
153 DECL(alGetProcAddress),
154 DECL(alGetEnumValue),
155 DECL(alListenerf),
156 DECL(alListener3f),
157 DECL(alListenerfv),
158 DECL(alListeneri),
159 DECL(alListener3i),
160 DECL(alListeneriv),
161 DECL(alGetListenerf),
162 DECL(alGetListener3f),
163 DECL(alGetListenerfv),
164 DECL(alGetListeneri),
165 DECL(alGetListener3i),
166 DECL(alGetListeneriv),
167 DECL(alGenSources),
168 DECL(alDeleteSources),
169 DECL(alIsSource),
170 DECL(alSourcef),
171 DECL(alSource3f),
172 DECL(alSourcefv),
173 DECL(alSourcei),
174 DECL(alSource3i),
175 DECL(alSourceiv),
176 DECL(alGetSourcef),
177 DECL(alGetSource3f),
178 DECL(alGetSourcefv),
179 DECL(alGetSourcei),
180 DECL(alGetSource3i),
181 DECL(alGetSourceiv),
182 DECL(alSourcePlayv),
183 DECL(alSourceStopv),
184 DECL(alSourceRewindv),
185 DECL(alSourcePausev),
186 DECL(alSourcePlay),
187 DECL(alSourceStop),
188 DECL(alSourceRewind),
189 DECL(alSourcePause),
190 DECL(alSourceQueueBuffers),
191 DECL(alSourceUnqueueBuffers),
192 DECL(alGenBuffers),
193 DECL(alDeleteBuffers),
194 DECL(alIsBuffer),
195 DECL(alBufferData),
196 DECL(alBufferf),
197 DECL(alBuffer3f),
198 DECL(alBufferfv),
199 DECL(alBufferi),
200 DECL(alBuffer3i),
201 DECL(alBufferiv),
202 DECL(alGetBufferf),
203 DECL(alGetBuffer3f),
204 DECL(alGetBufferfv),
205 DECL(alGetBufferi),
206 DECL(alGetBuffer3i),
207 DECL(alGetBufferiv),
208 DECL(alDopplerFactor),
209 DECL(alDopplerVelocity),
210 DECL(alSpeedOfSound),
211 DECL(alDistanceModel),
213 DECL(alGenFilters),
214 DECL(alDeleteFilters),
215 DECL(alIsFilter),
216 DECL(alFilteri),
217 DECL(alFilteriv),
218 DECL(alFilterf),
219 DECL(alFilterfv),
220 DECL(alGetFilteri),
221 DECL(alGetFilteriv),
222 DECL(alGetFilterf),
223 DECL(alGetFilterfv),
224 DECL(alGenEffects),
225 DECL(alDeleteEffects),
226 DECL(alIsEffect),
227 DECL(alEffecti),
228 DECL(alEffectiv),
229 DECL(alEffectf),
230 DECL(alEffectfv),
231 DECL(alGetEffecti),
232 DECL(alGetEffectiv),
233 DECL(alGetEffectf),
234 DECL(alGetEffectfv),
235 DECL(alGenAuxiliaryEffectSlots),
236 DECL(alDeleteAuxiliaryEffectSlots),
237 DECL(alIsAuxiliaryEffectSlot),
238 DECL(alAuxiliaryEffectSloti),
239 DECL(alAuxiliaryEffectSlotiv),
240 DECL(alAuxiliaryEffectSlotf),
241 DECL(alAuxiliaryEffectSlotfv),
242 DECL(alGetAuxiliaryEffectSloti),
243 DECL(alGetAuxiliaryEffectSlotiv),
244 DECL(alGetAuxiliaryEffectSlotf),
245 DECL(alGetAuxiliaryEffectSlotfv),
247 DECL(alBufferSubDataSOFT),
249 DECL(alBufferSamplesSOFT),
250 DECL(alBufferSubSamplesSOFT),
251 DECL(alGetBufferSamplesSOFT),
252 DECL(alIsBufferFormatSupportedSOFT),
254 DECL(alDeferUpdatesSOFT),
255 DECL(alProcessUpdatesSOFT),
257 DECL(alSourcedSOFT),
258 DECL(alSource3dSOFT),
259 DECL(alSourcedvSOFT),
260 DECL(alGetSourcedSOFT),
261 DECL(alGetSource3dSOFT),
262 DECL(alGetSourcedvSOFT),
263 DECL(alSourcei64SOFT),
264 DECL(alSource3i64SOFT),
265 DECL(alSourcei64vSOFT),
266 DECL(alGetSourcei64SOFT),
267 DECL(alGetSource3i64SOFT),
268 DECL(alGetSourcei64vSOFT),
270 { NULL, NULL }
272 #undef DECL
274 #define DECL(x) { #x, (x) }
275 static const ALCenums enumeration[] = {
276 DECL(ALC_INVALID),
277 DECL(ALC_FALSE),
278 DECL(ALC_TRUE),
280 DECL(ALC_MAJOR_VERSION),
281 DECL(ALC_MINOR_VERSION),
282 DECL(ALC_ATTRIBUTES_SIZE),
283 DECL(ALC_ALL_ATTRIBUTES),
284 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
285 DECL(ALC_DEVICE_SPECIFIER),
286 DECL(ALC_ALL_DEVICES_SPECIFIER),
287 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
288 DECL(ALC_EXTENSIONS),
289 DECL(ALC_FREQUENCY),
290 DECL(ALC_REFRESH),
291 DECL(ALC_SYNC),
292 DECL(ALC_MONO_SOURCES),
293 DECL(ALC_STEREO_SOURCES),
294 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
295 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
296 DECL(ALC_CAPTURE_SAMPLES),
297 DECL(ALC_CONNECTED),
299 DECL(ALC_EFX_MAJOR_VERSION),
300 DECL(ALC_EFX_MINOR_VERSION),
301 DECL(ALC_MAX_AUXILIARY_SENDS),
303 DECL(ALC_FORMAT_CHANNELS_SOFT),
304 DECL(ALC_FORMAT_TYPE_SOFT),
306 DECL(ALC_MONO_SOFT),
307 DECL(ALC_STEREO_SOFT),
308 DECL(ALC_QUAD_SOFT),
309 DECL(ALC_5POINT1_SOFT),
310 DECL(ALC_6POINT1_SOFT),
311 DECL(ALC_7POINT1_SOFT),
313 DECL(ALC_BYTE_SOFT),
314 DECL(ALC_UNSIGNED_BYTE_SOFT),
315 DECL(ALC_SHORT_SOFT),
316 DECL(ALC_UNSIGNED_SHORT_SOFT),
317 DECL(ALC_INT_SOFT),
318 DECL(ALC_UNSIGNED_INT_SOFT),
319 DECL(ALC_FLOAT_SOFT),
321 DECL(ALC_NO_ERROR),
322 DECL(ALC_INVALID_DEVICE),
323 DECL(ALC_INVALID_CONTEXT),
324 DECL(ALC_INVALID_ENUM),
325 DECL(ALC_INVALID_VALUE),
326 DECL(ALC_OUT_OF_MEMORY),
329 DECL(AL_INVALID),
330 DECL(AL_NONE),
331 DECL(AL_FALSE),
332 DECL(AL_TRUE),
334 DECL(AL_SOURCE_RELATIVE),
335 DECL(AL_CONE_INNER_ANGLE),
336 DECL(AL_CONE_OUTER_ANGLE),
337 DECL(AL_PITCH),
338 DECL(AL_POSITION),
339 DECL(AL_DIRECTION),
340 DECL(AL_VELOCITY),
341 DECL(AL_LOOPING),
342 DECL(AL_BUFFER),
343 DECL(AL_GAIN),
344 DECL(AL_MIN_GAIN),
345 DECL(AL_MAX_GAIN),
346 DECL(AL_ORIENTATION),
347 DECL(AL_REFERENCE_DISTANCE),
348 DECL(AL_ROLLOFF_FACTOR),
349 DECL(AL_CONE_OUTER_GAIN),
350 DECL(AL_MAX_DISTANCE),
351 DECL(AL_SEC_OFFSET),
352 DECL(AL_SAMPLE_OFFSET),
353 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
354 DECL(AL_BYTE_OFFSET),
355 DECL(AL_BYTE_RW_OFFSETS_SOFT),
356 DECL(AL_SOURCE_TYPE),
357 DECL(AL_STATIC),
358 DECL(AL_STREAMING),
359 DECL(AL_UNDETERMINED),
360 DECL(AL_METERS_PER_UNIT),
361 DECL(AL_DIRECT_CHANNELS_SOFT),
363 DECL(AL_DIRECT_FILTER),
364 DECL(AL_AUXILIARY_SEND_FILTER),
365 DECL(AL_AIR_ABSORPTION_FACTOR),
366 DECL(AL_ROOM_ROLLOFF_FACTOR),
367 DECL(AL_CONE_OUTER_GAINHF),
368 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
369 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
370 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
372 DECL(AL_SOURCE_STATE),
373 DECL(AL_INITIAL),
374 DECL(AL_PLAYING),
375 DECL(AL_PAUSED),
376 DECL(AL_STOPPED),
378 DECL(AL_BUFFERS_QUEUED),
379 DECL(AL_BUFFERS_PROCESSED),
381 DECL(AL_FORMAT_MONO8),
382 DECL(AL_FORMAT_MONO16),
383 DECL(AL_FORMAT_MONO_FLOAT32),
384 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
385 DECL(AL_FORMAT_STEREO8),
386 DECL(AL_FORMAT_STEREO16),
387 DECL(AL_FORMAT_STEREO_FLOAT32),
388 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
389 DECL(AL_FORMAT_MONO_IMA4),
390 DECL(AL_FORMAT_STEREO_IMA4),
391 DECL(AL_FORMAT_QUAD8_LOKI),
392 DECL(AL_FORMAT_QUAD16_LOKI),
393 DECL(AL_FORMAT_QUAD8),
394 DECL(AL_FORMAT_QUAD16),
395 DECL(AL_FORMAT_QUAD32),
396 DECL(AL_FORMAT_51CHN8),
397 DECL(AL_FORMAT_51CHN16),
398 DECL(AL_FORMAT_51CHN32),
399 DECL(AL_FORMAT_61CHN8),
400 DECL(AL_FORMAT_61CHN16),
401 DECL(AL_FORMAT_61CHN32),
402 DECL(AL_FORMAT_71CHN8),
403 DECL(AL_FORMAT_71CHN16),
404 DECL(AL_FORMAT_71CHN32),
405 DECL(AL_FORMAT_REAR8),
406 DECL(AL_FORMAT_REAR16),
407 DECL(AL_FORMAT_REAR32),
408 DECL(AL_FORMAT_MONO_MULAW),
409 DECL(AL_FORMAT_MONO_MULAW_EXT),
410 DECL(AL_FORMAT_STEREO_MULAW),
411 DECL(AL_FORMAT_STEREO_MULAW_EXT),
412 DECL(AL_FORMAT_QUAD_MULAW),
413 DECL(AL_FORMAT_51CHN_MULAW),
414 DECL(AL_FORMAT_61CHN_MULAW),
415 DECL(AL_FORMAT_71CHN_MULAW),
416 DECL(AL_FORMAT_REAR_MULAW),
417 DECL(AL_FORMAT_MONO_ALAW_EXT),
418 DECL(AL_FORMAT_STEREO_ALAW_EXT),
420 DECL(AL_MONO8_SOFT),
421 DECL(AL_MONO16_SOFT),
422 DECL(AL_MONO32F_SOFT),
423 DECL(AL_STEREO8_SOFT),
424 DECL(AL_STEREO16_SOFT),
425 DECL(AL_STEREO32F_SOFT),
426 DECL(AL_QUAD8_SOFT),
427 DECL(AL_QUAD16_SOFT),
428 DECL(AL_QUAD32F_SOFT),
429 DECL(AL_REAR8_SOFT),
430 DECL(AL_REAR16_SOFT),
431 DECL(AL_REAR32F_SOFT),
432 DECL(AL_5POINT1_8_SOFT),
433 DECL(AL_5POINT1_16_SOFT),
434 DECL(AL_5POINT1_32F_SOFT),
435 DECL(AL_6POINT1_8_SOFT),
436 DECL(AL_6POINT1_16_SOFT),
437 DECL(AL_6POINT1_32F_SOFT),
438 DECL(AL_7POINT1_8_SOFT),
439 DECL(AL_7POINT1_16_SOFT),
440 DECL(AL_7POINT1_32F_SOFT),
442 DECL(AL_MONO_SOFT),
443 DECL(AL_STEREO_SOFT),
444 DECL(AL_QUAD_SOFT),
445 DECL(AL_REAR_SOFT),
446 DECL(AL_5POINT1_SOFT),
447 DECL(AL_6POINT1_SOFT),
448 DECL(AL_7POINT1_SOFT),
450 DECL(AL_BYTE_SOFT),
451 DECL(AL_UNSIGNED_BYTE_SOFT),
452 DECL(AL_SHORT_SOFT),
453 DECL(AL_UNSIGNED_SHORT_SOFT),
454 DECL(AL_INT_SOFT),
455 DECL(AL_UNSIGNED_INT_SOFT),
456 DECL(AL_FLOAT_SOFT),
457 DECL(AL_DOUBLE_SOFT),
458 DECL(AL_BYTE3_SOFT),
459 DECL(AL_UNSIGNED_BYTE3_SOFT),
461 DECL(AL_FREQUENCY),
462 DECL(AL_BITS),
463 DECL(AL_CHANNELS),
464 DECL(AL_SIZE),
465 DECL(AL_INTERNAL_FORMAT_SOFT),
466 DECL(AL_BYTE_LENGTH_SOFT),
467 DECL(AL_SAMPLE_LENGTH_SOFT),
468 DECL(AL_SEC_LENGTH_SOFT),
470 DECL(AL_UNUSED),
471 DECL(AL_PENDING),
472 DECL(AL_PROCESSED),
474 DECL(AL_NO_ERROR),
475 DECL(AL_INVALID_NAME),
476 DECL(AL_INVALID_ENUM),
477 DECL(AL_INVALID_VALUE),
478 DECL(AL_INVALID_OPERATION),
479 DECL(AL_OUT_OF_MEMORY),
481 DECL(AL_VENDOR),
482 DECL(AL_VERSION),
483 DECL(AL_RENDERER),
484 DECL(AL_EXTENSIONS),
486 DECL(AL_DOPPLER_FACTOR),
487 DECL(AL_DOPPLER_VELOCITY),
488 DECL(AL_DISTANCE_MODEL),
489 DECL(AL_SPEED_OF_SOUND),
490 DECL(AL_SOURCE_DISTANCE_MODEL),
491 DECL(AL_DEFERRED_UPDATES_SOFT),
493 DECL(AL_INVERSE_DISTANCE),
494 DECL(AL_INVERSE_DISTANCE_CLAMPED),
495 DECL(AL_LINEAR_DISTANCE),
496 DECL(AL_LINEAR_DISTANCE_CLAMPED),
497 DECL(AL_EXPONENT_DISTANCE),
498 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
500 DECL(AL_FILTER_TYPE),
501 DECL(AL_FILTER_NULL),
502 DECL(AL_FILTER_LOWPASS),
503 #if 0
504 DECL(AL_FILTER_HIGHPASS),
505 DECL(AL_FILTER_BANDPASS),
506 #endif
508 DECL(AL_LOWPASS_GAIN),
509 DECL(AL_LOWPASS_GAINHF),
511 DECL(AL_EFFECT_TYPE),
512 DECL(AL_EFFECT_NULL),
513 DECL(AL_EFFECT_REVERB),
514 DECL(AL_EFFECT_EAXREVERB),
515 #if 0
516 DECL(AL_EFFECT_CHORUS),
517 DECL(AL_EFFECT_DISTORTION),
518 #endif
519 DECL(AL_EFFECT_ECHO),
520 #if 0
521 DECL(AL_EFFECT_FLANGER),
522 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
523 DECL(AL_EFFECT_VOCAL_MORPHER),
524 DECL(AL_EFFECT_PITCH_SHIFTER),
525 #endif
526 DECL(AL_EFFECT_RING_MODULATOR),
527 #if 0
528 DECL(AL_EFFECT_AUTOWAH),
529 DECL(AL_EFFECT_COMPRESSOR),
530 DECL(AL_EFFECT_EQUALIZER),
531 #endif
532 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
533 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
535 DECL(AL_EAXREVERB_DENSITY),
536 DECL(AL_EAXREVERB_DIFFUSION),
537 DECL(AL_EAXREVERB_GAIN),
538 DECL(AL_EAXREVERB_GAINHF),
539 DECL(AL_EAXREVERB_GAINLF),
540 DECL(AL_EAXREVERB_DECAY_TIME),
541 DECL(AL_EAXREVERB_DECAY_HFRATIO),
542 DECL(AL_EAXREVERB_DECAY_LFRATIO),
543 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
544 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
545 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
546 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
547 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
548 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
549 DECL(AL_EAXREVERB_ECHO_TIME),
550 DECL(AL_EAXREVERB_ECHO_DEPTH),
551 DECL(AL_EAXREVERB_MODULATION_TIME),
552 DECL(AL_EAXREVERB_MODULATION_DEPTH),
553 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
554 DECL(AL_EAXREVERB_HFREFERENCE),
555 DECL(AL_EAXREVERB_LFREFERENCE),
556 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
557 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
559 DECL(AL_REVERB_DENSITY),
560 DECL(AL_REVERB_DIFFUSION),
561 DECL(AL_REVERB_GAIN),
562 DECL(AL_REVERB_GAINHF),
563 DECL(AL_REVERB_DECAY_TIME),
564 DECL(AL_REVERB_DECAY_HFRATIO),
565 DECL(AL_REVERB_REFLECTIONS_GAIN),
566 DECL(AL_REVERB_REFLECTIONS_DELAY),
567 DECL(AL_REVERB_LATE_REVERB_GAIN),
568 DECL(AL_REVERB_LATE_REVERB_DELAY),
569 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
570 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
571 DECL(AL_REVERB_DECAY_HFLIMIT),
573 DECL(AL_ECHO_DELAY),
574 DECL(AL_ECHO_LRDELAY),
575 DECL(AL_ECHO_DAMPING),
576 DECL(AL_ECHO_FEEDBACK),
577 DECL(AL_ECHO_SPREAD),
579 DECL(AL_RING_MODULATOR_FREQUENCY),
580 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
581 DECL(AL_RING_MODULATOR_WAVEFORM),
583 DECL(AL_DEDICATED_GAIN),
585 { NULL, (ALCenum)0 }
587 #undef DECL
589 static const ALCchar alcNoError[] = "No Error";
590 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
591 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
592 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
593 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
594 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
597 /************************************************
598 * Global variables
599 ************************************************/
601 /* Enumerated device names */
602 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
603 static ALCchar *alcAllDevicesList;
604 static ALCchar *alcCaptureDeviceList;
605 /* Sizes only include the first ending null character, not the second */
606 static size_t alcAllDevicesListSize;
607 static size_t alcCaptureDeviceListSize;
609 /* Default is always the first in the list */
610 static ALCchar *alcDefaultAllDevicesSpecifier;
611 static ALCchar *alcCaptureDefaultDeviceSpecifier;
613 /* Default context extensions */
614 static const ALchar alExtList[] =
615 "AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 "
616 "AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW "
617 "AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model "
618 "AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data "
619 "AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points "
620 "AL_SOFT_source_latency";
622 static volatile ALCenum LastNullDeviceError = ALC_NO_ERROR;
624 /* Thread-local current context */
625 static pthread_key_t LocalContext;
626 /* Process-wide current context */
627 static ALCcontext *volatile GlobalContext = NULL;
629 /* Mixing thread piority level */
630 ALint RTPrioLevel;
632 FILE *LogFile;
633 #ifdef _DEBUG
634 enum LogLevel LogLevel = LogWarning;
635 #else
636 enum LogLevel LogLevel = LogError;
637 #endif
639 /* Flag to trap ALC device errors */
640 static ALCboolean TrapALCError = ALC_FALSE;
642 /* One-time configuration init control */
643 static pthread_once_t alc_config_once = PTHREAD_ONCE_INIT;
645 /* Default effect that applies to sources that don't have an effect on send 0 */
646 static ALeffect DefaultEffect;
649 /************************************************
650 * ALC information
651 ************************************************/
652 static const ALCchar alcNoDeviceExtList[] =
653 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
654 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
655 static const ALCchar alcExtensionList[] =
656 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
657 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
658 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
659 static const ALCint alcMajorVersion = 1;
660 static const ALCint alcMinorVersion = 1;
662 static const ALCint alcEFXMajorVersion = 1;
663 static const ALCint alcEFXMinorVersion = 0;
666 /************************************************
667 * Device lists
668 ************************************************/
669 static ALCdevice *volatile DeviceList = NULL;
671 static CRITICAL_SECTION ListLock;
673 static void LockLists(void)
675 EnterCriticalSection(&ListLock);
677 static void UnlockLists(void)
679 LeaveCriticalSection(&ListLock);
682 /************************************************
683 * Library initialization
684 ************************************************/
685 #if defined(_WIN32)
686 static void alc_init(void);
687 static void alc_deinit(void);
688 static void alc_deinit_safe(void);
690 UIntMap TlsDestructor;
692 #ifndef AL_LIBTYPE_STATIC
693 BOOL APIENTRY DllMain(HINSTANCE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
695 ALsizei i;
697 // Perform actions based on the reason for calling.
698 switch(ul_reason_for_call)
700 case DLL_PROCESS_ATTACH:
701 /* Pin the DLL so we won't get unloaded until the process terminates */
702 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
703 (WCHAR*)hModule, &hModule);
704 InitUIntMap(&TlsDestructor, ~0);
705 alc_init();
706 break;
708 case DLL_THREAD_DETACH:
709 LockUIntMapRead(&TlsDestructor);
710 for(i = 0;i < TlsDestructor.size;i++)
712 void *ptr = pthread_getspecific(TlsDestructor.array[i].key);
713 void (*callback)(void*) = (void(*)(void*))TlsDestructor.array[i].value;
714 if(ptr && callback)
715 callback(ptr);
717 UnlockUIntMapRead(&TlsDestructor);
718 break;
720 case DLL_PROCESS_DETACH:
721 if(!lpReserved)
722 alc_deinit();
723 else
724 alc_deinit_safe();
725 ResetUIntMap(&TlsDestructor);
726 break;
728 return TRUE;
730 #elif defined(_MSC_VER)
731 #pragma section(".CRT$XCU",read)
732 static void alc_constructor(void);
733 static void alc_destructor(void);
734 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
736 static void alc_constructor(void)
738 atexit(alc_destructor);
739 alc_init();
742 static void alc_destructor(void)
744 alc_deinit();
746 #elif defined(HAVE_GCC_DESTRUCTOR)
747 static void alc_init(void) __attribute__((constructor));
748 static void alc_deinit(void) __attribute__((destructor));
749 #else
750 #error "No static initialization available on this platform!"
751 #endif
753 #elif defined(HAVE_GCC_DESTRUCTOR)
755 static void alc_init(void) __attribute__((constructor));
756 static void alc_deinit(void) __attribute__((destructor));
758 #else
759 #error "No global initialization available on this platform!"
760 #endif
762 static void ReleaseThreadCtx(void *ptr);
763 static void alc_init(void)
765 const char *str;
767 LogFile = stderr;
769 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
770 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
771 ConeScale *= 0.5f;
773 str = getenv("__ALSOFT_REVERSE_Z");
774 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
775 ZScale *= -1.0f;
777 pthread_key_create(&LocalContext, ReleaseThreadCtx);
778 InitializeCriticalSection(&ListLock);
779 ThunkInit();
782 static void alc_initconfig(void)
784 const char *devs, *str;
785 ALuint capfilter;
786 float valf;
787 int i, n;
789 str = getenv("ALSOFT_LOGLEVEL");
790 if(str)
792 long lvl = strtol(str, NULL, 0);
793 if(lvl >= NoLog && lvl <= LogRef)
794 LogLevel = lvl;
797 str = getenv("ALSOFT_LOGFILE");
798 if(str && str[0])
800 FILE *logfile = fopen(str, "wat");
801 if(logfile) LogFile = logfile;
802 else ERR("Failed to open log file '%s'\n", str);
805 ReadALConfig();
807 capfilter = 0;
808 #ifdef HAVE_SSE
809 capfilter |= CPU_CAP_SSE;
810 #endif
811 #ifdef HAVE_NEON
812 capfilter |= CPU_CAP_NEON;
813 #endif
814 if(ConfigValueStr(NULL, "disable-cpu-exts", &str))
816 if(strcasecmp(str, "all") == 0)
817 capfilter = 0;
818 else
820 size_t len;
821 const char *next = str;
823 i = 0;
824 do {
825 str = next;
826 next = strchr(str, ',');
828 while(isspace(str[0]))
829 str++;
830 if(!str[0] || str[0] == ',')
831 continue;
833 len = (next ? ((size_t)(next-str)) : strlen(str));
834 if(strncasecmp(str, "sse", len) == 0)
835 capfilter &= ~CPU_CAP_SSE;
836 else if(strncasecmp(str, "neon", len) == 0)
837 capfilter &= ~CPU_CAP_NEON;
838 else
839 WARN("Invalid CPU extension \"%s\"\n", str);
840 } while(next++);
843 FillCPUCaps(capfilter);
845 #ifdef _WIN32
846 RTPrioLevel = 1;
847 #else
848 RTPrioLevel = 0;
849 #endif
850 ConfigValueInt(NULL, "rt-prio", &RTPrioLevel);
852 if(ConfigValueStr(NULL, "resampler", &str))
854 if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
855 DefaultResampler = PointResampler;
856 else if(strcasecmp(str, "linear") == 0)
857 DefaultResampler = LinearResampler;
858 else if(strcasecmp(str, "cubic") == 0)
859 DefaultResampler = CubicResampler;
860 else
862 char *end;
864 n = strtol(str, &end, 0);
865 if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == CubicResampler))
866 DefaultResampler = n;
867 else
868 WARN("Invalid resampler: %s\n", str);
872 str = getenv("ALSOFT_TRAP_ERROR");
873 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
875 TrapALError = AL_TRUE;
876 TrapALCError = AL_TRUE;
878 else
880 str = getenv("ALSOFT_TRAP_AL_ERROR");
881 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
882 TrapALError = AL_TRUE;
883 TrapALError = GetConfigValueBool(NULL, "trap-al-error", TrapALError);
885 str = getenv("ALSOFT_TRAP_ALC_ERROR");
886 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
887 TrapALCError = ALC_TRUE;
888 TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", TrapALCError);
891 if(ConfigValueFloat("reverb", "boost", &valf))
892 ReverbBoost *= powf(10.0f, valf / 20.0f);
894 EmulateEAXReverb = GetConfigValueBool("reverb", "emulate-eax", AL_FALSE);
896 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
897 ConfigValueStr(NULL, "drivers", &devs))
899 int n;
900 size_t len;
901 const char *next = devs;
902 int endlist, delitem;
904 i = 0;
905 do {
906 devs = next;
907 next = strchr(devs, ',');
909 delitem = (devs[0] == '-');
910 if(devs[0] == '-') devs++;
912 if(!devs[0] || devs[0] == ',')
914 endlist = 0;
915 continue;
917 endlist = 1;
919 len = (next ? ((size_t)(next-devs)) : strlen(devs));
920 for(n = i;BackendList[n].Init;n++)
922 if(len == strlen(BackendList[n].name) &&
923 strncmp(BackendList[n].name, devs, len) == 0)
925 if(delitem)
927 do {
928 BackendList[n] = BackendList[n+1];
929 ++n;
930 } while(BackendList[n].Init);
932 else
934 struct BackendInfo Bkp = BackendList[n];
935 while(n > i)
937 BackendList[n] = BackendList[n-1];
938 --n;
940 BackendList[n] = Bkp;
942 i++;
944 break;
947 } while(next++);
949 if(endlist)
951 BackendList[i].name = NULL;
952 BackendList[i].Init = NULL;
953 BackendList[i].Deinit = NULL;
954 BackendList[i].Probe = NULL;
958 for(i = 0;BackendList[i].Init && (!PlaybackBackend.name || !CaptureBackend.name);i++)
960 if(!BackendList[i].Init(&BackendList[i].Funcs))
962 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
963 continue;
966 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
967 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
969 PlaybackBackend = BackendList[i];
970 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
972 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
974 CaptureBackend = BackendList[i];
975 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
978 BackendLoopback.Init(&BackendLoopback.Funcs);
980 if(ConfigValueStr(NULL, "excludefx", &str))
982 size_t len;
983 const char *next = str;
985 do {
986 str = next;
987 next = strchr(str, ',');
989 if(!str[0] || next == str)
990 continue;
992 len = (next ? ((size_t)(next-str)) : strlen(str));
993 for(n = 0;EffectList[n].name;n++)
995 if(len == strlen(EffectList[n].name) &&
996 strncmp(EffectList[n].name, str, len) == 0)
997 DisabledEffects[EffectList[n].type] = AL_TRUE;
999 } while(next++);
1002 InitEffect(&DefaultEffect);
1003 str = getenv("ALSOFT_DEFAULT_REVERB");
1004 if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str))
1005 LoadReverbPreset(str, &DefaultEffect);
1007 #define DO_INITCONFIG() pthread_once(&alc_config_once, alc_initconfig)
1010 /************************************************
1011 * Library deinitialization
1012 ************************************************/
1013 static void alc_cleanup(void)
1015 ALCdevice *dev;
1017 free(alcAllDevicesList); alcAllDevicesList = NULL;
1018 alcAllDevicesListSize = 0;
1019 free(alcCaptureDeviceList); alcCaptureDeviceList = NULL;
1020 alcCaptureDeviceListSize = 0;
1022 free(alcDefaultAllDevicesSpecifier);
1023 alcDefaultAllDevicesSpecifier = NULL;
1024 free(alcCaptureDefaultDeviceSpecifier);
1025 alcCaptureDefaultDeviceSpecifier = NULL;
1027 if((dev=ExchangePtr((XchgPtr*)&DeviceList, NULL)) != NULL)
1029 ALCuint num = 0;
1030 do {
1031 num++;
1032 } while((dev=dev->next) != NULL);
1033 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1037 static void alc_deinit_safe(void)
1039 alc_cleanup();
1041 FreeHrtfs();
1042 FreeALConfig();
1044 ThunkExit();
1045 DeleteCriticalSection(&ListLock);
1046 pthread_key_delete(LocalContext);
1048 if(LogFile != stderr)
1049 fclose(LogFile);
1050 LogFile = NULL;
1053 static void alc_deinit(void)
1055 int i;
1057 alc_cleanup();
1059 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1060 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1062 for(i = 0;BackendList[i].Deinit;i++)
1063 BackendList[i].Deinit();
1064 BackendLoopback.Deinit();
1066 alc_deinit_safe();
1070 /************************************************
1071 * Device enumeration
1072 ************************************************/
1073 static void ProbeList(ALCchar **list, size_t *listsize, enum DevProbe type)
1075 DO_INITCONFIG();
1077 LockLists();
1078 free(*list);
1079 *list = NULL;
1080 *listsize = 0;
1082 if(type == ALL_DEVICE_PROBE && PlaybackBackend.Probe)
1083 PlaybackBackend.Probe(type);
1084 else if(type == CAPTURE_DEVICE_PROBE && CaptureBackend.Probe)
1085 CaptureBackend.Probe(type);
1086 UnlockLists();
1089 static void ProbeAllDevicesList(void)
1090 { ProbeList(&alcAllDevicesList, &alcAllDevicesListSize, ALL_DEVICE_PROBE); }
1091 static void ProbeCaptureDeviceList(void)
1092 { ProbeList(&alcCaptureDeviceList, &alcCaptureDeviceListSize, CAPTURE_DEVICE_PROBE); }
1095 static void AppendList(const ALCchar *name, ALCchar **List, size_t *ListSize)
1097 size_t len = strlen(name);
1098 void *temp;
1100 if(len == 0)
1101 return;
1103 temp = realloc(*List, (*ListSize) + len + 2);
1104 if(!temp)
1106 ERR("Realloc failed to add %s!\n", name);
1107 return;
1109 *List = temp;
1111 memcpy((*List)+(*ListSize), name, len+1);
1112 *ListSize += len+1;
1113 (*List)[*ListSize] = 0;
1116 #define DECL_APPEND_LIST_FUNC(type) \
1117 void Append##type##List(const ALCchar *name) \
1118 { AppendList(name, &alc##type##List, &alc##type##ListSize); }
1120 DECL_APPEND_LIST_FUNC(AllDevices)
1121 DECL_APPEND_LIST_FUNC(CaptureDevice)
1123 #undef DECL_APPEND_LIST_FUNC
1126 /************************************************
1127 * Device format information
1128 ************************************************/
1129 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1131 switch(type)
1133 case DevFmtByte: return "Signed Byte";
1134 case DevFmtUByte: return "Unsigned Byte";
1135 case DevFmtShort: return "Signed Short";
1136 case DevFmtUShort: return "Unsigned Short";
1137 case DevFmtInt: return "Signed Int";
1138 case DevFmtUInt: return "Unsigned Int";
1139 case DevFmtFloat: return "Float";
1141 return "(unknown type)";
1143 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1145 switch(chans)
1147 case DevFmtMono: return "Mono";
1148 case DevFmtStereo: return "Stereo";
1149 case DevFmtQuad: return "Quadraphonic";
1150 case DevFmtX51: return "5.1 Surround";
1151 case DevFmtX51Side: return "5.1 Side";
1152 case DevFmtX61: return "6.1 Surround";
1153 case DevFmtX71: return "7.1 Surround";
1155 return "(unknown channels)";
1158 ALuint BytesFromDevFmt(enum DevFmtType type)
1160 switch(type)
1162 case DevFmtByte: return sizeof(ALbyte);
1163 case DevFmtUByte: return sizeof(ALubyte);
1164 case DevFmtShort: return sizeof(ALshort);
1165 case DevFmtUShort: return sizeof(ALushort);
1166 case DevFmtInt: return sizeof(ALint);
1167 case DevFmtUInt: return sizeof(ALuint);
1168 case DevFmtFloat: return sizeof(ALfloat);
1170 return 0;
1172 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1174 switch(chans)
1176 case DevFmtMono: return 1;
1177 case DevFmtStereo: return 2;
1178 case DevFmtQuad: return 4;
1179 case DevFmtX51: return 6;
1180 case DevFmtX51Side: return 6;
1181 case DevFmtX61: return 7;
1182 case DevFmtX71: return 8;
1184 return 0;
1187 static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans,
1188 enum DevFmtType *type)
1190 static const struct {
1191 ALenum format;
1192 enum DevFmtChannels channels;
1193 enum DevFmtType type;
1194 } list[] = {
1195 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1196 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1197 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1199 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1200 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1201 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1203 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1204 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1205 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1207 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1208 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1209 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1211 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1212 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1213 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1215 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1216 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1217 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1219 ALuint i;
1221 for(i = 0;i < COUNTOF(list);i++)
1223 if(list[i].format == format)
1225 *chans = list[i].channels;
1226 *type = list[i].type;
1227 return AL_TRUE;
1231 return AL_FALSE;
1234 static ALCboolean IsValidALCType(ALCenum type)
1236 switch(type)
1238 case ALC_BYTE_SOFT:
1239 case ALC_UNSIGNED_BYTE_SOFT:
1240 case ALC_SHORT_SOFT:
1241 case ALC_UNSIGNED_SHORT_SOFT:
1242 case ALC_INT_SOFT:
1243 case ALC_UNSIGNED_INT_SOFT:
1244 case ALC_FLOAT_SOFT:
1245 return ALC_TRUE;
1247 return ALC_FALSE;
1250 static ALCboolean IsValidALCChannels(ALCenum channels)
1252 switch(channels)
1254 case ALC_MONO_SOFT:
1255 case ALC_STEREO_SOFT:
1256 case ALC_QUAD_SOFT:
1257 case ALC_5POINT1_SOFT:
1258 case ALC_6POINT1_SOFT:
1259 case ALC_7POINT1_SOFT:
1260 return ALC_TRUE;
1262 return ALC_FALSE;
1266 /************************************************
1267 * Miscellaneous ALC helpers
1268 ************************************************/
1270 void ALCdevice_LockDefault(ALCdevice *device)
1272 EnterCriticalSection(&device->Mutex);
1274 void ALCdevice_UnlockDefault(ALCdevice *device)
1276 LeaveCriticalSection(&device->Mutex);
1278 ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device)
1280 (void)device;
1281 return 0;
1284 /* SetDefaultWFXChannelOrder
1286 * Sets the default channel order used by WaveFormatEx.
1288 void SetDefaultWFXChannelOrder(ALCdevice *device)
1290 ALuint i;
1292 for(i = 0;i < MaxChannels;i++)
1293 device->ChannelOffsets[i] = INVALID_OFFSET;
1295 switch(device->FmtChans)
1297 case DevFmtMono: device->ChannelOffsets[FrontCenter] = 0;
1298 break;
1299 case DevFmtStereo: device->ChannelOffsets[FrontLeft] = 0;
1300 device->ChannelOffsets[FrontRight] = 1;
1301 break;
1302 case DevFmtQuad: device->ChannelOffsets[FrontLeft] = 0;
1303 device->ChannelOffsets[FrontRight] = 1;
1304 device->ChannelOffsets[BackLeft] = 2;
1305 device->ChannelOffsets[BackRight] = 3;
1306 break;
1307 case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0;
1308 device->ChannelOffsets[FrontRight] = 1;
1309 device->ChannelOffsets[FrontCenter] = 2;
1310 device->ChannelOffsets[LFE] = 3;
1311 device->ChannelOffsets[BackLeft] = 4;
1312 device->ChannelOffsets[BackRight] = 5;
1313 break;
1314 case DevFmtX51Side: device->ChannelOffsets[FrontLeft] = 0;
1315 device->ChannelOffsets[FrontRight] = 1;
1316 device->ChannelOffsets[FrontCenter] = 2;
1317 device->ChannelOffsets[LFE] = 3;
1318 device->ChannelOffsets[SideLeft] = 4;
1319 device->ChannelOffsets[SideRight] = 5;
1320 break;
1321 case DevFmtX61: device->ChannelOffsets[FrontLeft] = 0;
1322 device->ChannelOffsets[FrontRight] = 1;
1323 device->ChannelOffsets[FrontCenter] = 2;
1324 device->ChannelOffsets[LFE] = 3;
1325 device->ChannelOffsets[BackCenter] = 4;
1326 device->ChannelOffsets[SideLeft] = 5;
1327 device->ChannelOffsets[SideRight] = 6;
1328 break;
1329 case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0;
1330 device->ChannelOffsets[FrontRight] = 1;
1331 device->ChannelOffsets[FrontCenter] = 2;
1332 device->ChannelOffsets[LFE] = 3;
1333 device->ChannelOffsets[BackLeft] = 4;
1334 device->ChannelOffsets[BackRight] = 5;
1335 device->ChannelOffsets[SideLeft] = 6;
1336 device->ChannelOffsets[SideRight] = 7;
1337 break;
1341 /* SetDefaultChannelOrder
1343 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1345 void SetDefaultChannelOrder(ALCdevice *device)
1347 ALuint i;
1349 for(i = 0;i < MaxChannels;i++)
1350 device->ChannelOffsets[i] = INVALID_OFFSET;
1352 switch(device->FmtChans)
1354 case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0;
1355 device->ChannelOffsets[FrontRight] = 1;
1356 device->ChannelOffsets[BackLeft] = 2;
1357 device->ChannelOffsets[BackRight] = 3;
1358 device->ChannelOffsets[FrontCenter] = 4;
1359 device->ChannelOffsets[LFE] = 5;
1360 return;
1361 case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0;
1362 device->ChannelOffsets[FrontRight] = 1;
1363 device->ChannelOffsets[BackLeft] = 2;
1364 device->ChannelOffsets[BackRight] = 3;
1365 device->ChannelOffsets[FrontCenter] = 4;
1366 device->ChannelOffsets[LFE] = 5;
1367 device->ChannelOffsets[SideLeft] = 6;
1368 device->ChannelOffsets[SideRight] = 7;
1369 return;
1371 /* Same as WFX order */
1372 case DevFmtMono:
1373 case DevFmtStereo:
1374 case DevFmtQuad:
1375 case DevFmtX51Side:
1376 case DevFmtX61:
1377 break;
1379 SetDefaultWFXChannelOrder(device);
1383 /* alcSetError
1385 * Stores the latest ALC device error
1387 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1389 if(TrapALCError)
1391 #ifdef _WIN32
1392 /* DebugBreak() will cause an exception if there is no debugger */
1393 if(IsDebuggerPresent())
1394 DebugBreak();
1395 #elif defined(SIGTRAP)
1396 raise(SIGTRAP);
1397 #endif
1400 if(device)
1401 device->LastError = errorCode;
1402 else
1403 LastNullDeviceError = errorCode;
1407 /* UpdateDeviceParams
1409 * Updates device parameters according to the attribute list (caller is
1410 * responsible for holding the list lock).
1412 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1414 ALCcontext *context;
1415 enum DevFmtChannels oldChans;
1416 enum DevFmtType oldType;
1417 ALCuint oldFreq;
1418 FPUCtl oldMode;
1419 ALuint i;
1421 // Check for attributes
1422 if(device->Type == Loopback)
1424 enum {
1425 GotFreq = 1<<0,
1426 GotChans = 1<<1,
1427 GotType = 1<<2,
1428 GotAll = GotFreq|GotChans|GotType
1430 ALCuint freq, numMono, numStereo, numSends;
1431 enum DevFmtChannels schans;
1432 enum DevFmtType stype;
1433 ALCuint attrIdx = 0;
1434 ALCint gotFmt = 0;
1436 if(!attrList)
1438 WARN("Missing attributes for loopback device\n");
1439 return ALC_INVALID_VALUE;
1442 numMono = device->NumMonoSources;
1443 numStereo = device->NumStereoSources;
1444 numSends = device->NumAuxSends;
1445 schans = device->FmtChans;
1446 stype = device->FmtType;
1447 freq = device->Frequency;
1449 while(attrList[attrIdx])
1451 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1453 ALCint val = attrList[attrIdx + 1];
1454 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1455 return ALC_INVALID_VALUE;
1456 schans = val;
1457 gotFmt |= GotChans;
1460 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1462 ALCint val = attrList[attrIdx + 1];
1463 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1464 return ALC_INVALID_VALUE;
1465 stype = val;
1466 gotFmt |= GotType;
1469 if(attrList[attrIdx] == ALC_FREQUENCY)
1471 freq = attrList[attrIdx + 1];
1472 if(freq < MIN_OUTPUT_RATE)
1473 return ALC_INVALID_VALUE;
1474 gotFmt |= GotFreq;
1477 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1479 numStereo = attrList[attrIdx + 1];
1480 if(numStereo > device->MaxNoOfSources)
1481 numStereo = device->MaxNoOfSources;
1483 numMono = device->MaxNoOfSources - numStereo;
1486 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1487 numSends = attrList[attrIdx + 1];
1489 attrIdx += 2;
1492 if(gotFmt != GotAll)
1494 WARN("Missing format for loopback device\n");
1495 return ALC_INVALID_VALUE;
1498 ConfigValueUInt(NULL, "sends", &numSends);
1499 numSends = minu(MAX_SENDS, numSends);
1501 if((device->Flags&DEVICE_RUNNING))
1502 ALCdevice_StopPlayback(device);
1503 device->Flags &= ~DEVICE_RUNNING;
1505 device->Frequency = freq;
1506 device->FmtChans = schans;
1507 device->FmtType = stype;
1508 device->NumMonoSources = numMono;
1509 device->NumStereoSources = numStereo;
1510 device->NumAuxSends = numSends;
1512 else if(attrList && attrList[0])
1514 ALCuint freq, numMono, numStereo, numSends;
1515 ALCuint attrIdx = 0;
1517 /* If a context is already running on the device, stop playback so the
1518 * device attributes can be updated. */
1519 if((device->Flags&DEVICE_RUNNING))
1520 ALCdevice_StopPlayback(device);
1521 device->Flags &= ~DEVICE_RUNNING;
1523 freq = device->Frequency;
1524 numMono = device->NumMonoSources;
1525 numStereo = device->NumStereoSources;
1526 numSends = device->NumAuxSends;
1528 while(attrList[attrIdx])
1530 if(attrList[attrIdx] == ALC_FREQUENCY)
1532 freq = attrList[attrIdx + 1];
1533 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1536 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1538 numStereo = attrList[attrIdx + 1];
1539 if(numStereo > device->MaxNoOfSources)
1540 numStereo = device->MaxNoOfSources;
1542 numMono = device->MaxNoOfSources - numStereo;
1545 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1546 numSends = attrList[attrIdx + 1];
1548 attrIdx += 2;
1551 ConfigValueUInt(NULL, "frequency", &freq);
1552 freq = maxu(freq, MIN_OUTPUT_RATE);
1554 ConfigValueUInt(NULL, "sends", &numSends);
1555 numSends = minu(MAX_SENDS, numSends);
1557 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1558 device->Frequency;
1559 /* SSE does best with the update size being a multiple of 4 */
1560 if((CPUCapFlags&CPU_CAP_SSE))
1561 device->UpdateSize = (device->UpdateSize+3)&~3;
1563 device->Frequency = freq;
1564 device->NumMonoSources = numMono;
1565 device->NumStereoSources = numStereo;
1566 device->NumAuxSends = numSends;
1569 if((device->Flags&DEVICE_RUNNING))
1570 return ALC_NO_ERROR;
1572 oldFreq = device->Frequency;
1573 oldChans = device->FmtChans;
1574 oldType = device->FmtType;
1576 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1577 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"",
1578 DevFmtChannelsString(device->FmtChans),
1579 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"",
1580 DevFmtTypeString(device->FmtType),
1581 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"",
1582 device->Frequency,
1583 device->UpdateSize, device->NumUpdates);
1585 if(ALCdevice_ResetPlayback(device) == ALC_FALSE)
1586 return ALC_INVALID_DEVICE;
1588 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1590 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1591 DevFmtChannelsString(device->FmtChans));
1592 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1594 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1596 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1597 DevFmtTypeString(device->FmtType));
1598 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1600 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1602 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1603 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1606 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1607 DevFmtChannelsString(device->FmtChans),
1608 DevFmtTypeString(device->FmtType), device->Frequency,
1609 device->UpdateSize, device->NumUpdates);
1611 aluInitPanning(device);
1613 for(i = 0;i < MaxChannels;i++)
1615 device->ClickRemoval[i] = 0.0f;
1616 device->PendingClicks[i] = 0.0f;
1619 device->Hrtf = NULL;
1620 if(device->Type != Loopback && GetConfigValueBool(NULL, "hrtf", AL_FALSE))
1621 device->Hrtf = GetHrtf(device);
1622 TRACE("HRTF %s\n", device->Hrtf?"enabled":"disabled");
1624 if(!device->Hrtf && device->Bs2bLevel > 0 && device->Bs2bLevel <= 6)
1626 if(!device->Bs2b)
1628 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
1629 bs2b_clear(device->Bs2b);
1631 bs2b_set_srate(device->Bs2b, device->Frequency);
1632 bs2b_set_level(device->Bs2b, device->Bs2bLevel);
1633 TRACE("BS2B level %d\n", device->Bs2bLevel);
1635 else
1637 free(device->Bs2b);
1638 device->Bs2b = NULL;
1639 TRACE("BS2B disabled\n");
1642 device->Flags &= ~DEVICE_WIDE_STEREO;
1643 if(device->Type != Loopback && !device->Hrtf && GetConfigValueBool(NULL, "wide-stereo", AL_FALSE))
1644 device->Flags |= DEVICE_WIDE_STEREO;
1646 if(!device->Hrtf && (device->UpdateSize&3))
1648 if((CPUCapFlags&CPU_CAP_SSE))
1649 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1652 SetMixerFPUMode(&oldMode);
1653 ALCdevice_Lock(device);
1654 context = device->ContextList;
1655 while(context)
1657 ALsizei pos;
1659 context->UpdateSources = AL_FALSE;
1660 LockUIntMapRead(&context->EffectSlotMap);
1661 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
1663 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
1665 if(ALeffectState_DeviceUpdate(slot->EffectState, device) == AL_FALSE)
1667 UnlockUIntMapRead(&context->EffectSlotMap);
1668 ALCdevice_Unlock(device);
1669 RestoreFPUMode(&oldMode);
1670 return ALC_INVALID_DEVICE;
1672 slot->NeedsUpdate = AL_FALSE;
1673 ALeffectState_Update(slot->EffectState, device, slot);
1675 UnlockUIntMapRead(&context->EffectSlotMap);
1677 LockUIntMapRead(&context->SourceMap);
1678 for(pos = 0;pos < context->SourceMap.size;pos++)
1680 ALsource *source = context->SourceMap.array[pos].value;
1681 ALuint s = device->NumAuxSends;
1682 while(s < MAX_SENDS)
1684 if(source->Send[s].Slot)
1685 DecrementRef(&source->Send[s].Slot->ref);
1686 source->Send[s].Slot = NULL;
1687 source->Send[s].Gain = 1.0f;
1688 source->Send[s].GainHF = 1.0f;
1689 s++;
1691 source->NeedsUpdate = AL_FALSE;
1692 ALsource_Update(source, context);
1694 UnlockUIntMapRead(&context->SourceMap);
1696 context = context->next;
1698 if(device->DefaultSlot)
1700 ALeffectslot *slot = device->DefaultSlot;
1702 if(ALeffectState_DeviceUpdate(slot->EffectState, device) == AL_FALSE)
1704 ALCdevice_Unlock(device);
1705 RestoreFPUMode(&oldMode);
1706 return ALC_INVALID_DEVICE;
1708 slot->NeedsUpdate = AL_FALSE;
1709 ALeffectState_Update(slot->EffectState, device, slot);
1711 ALCdevice_Unlock(device);
1712 RestoreFPUMode(&oldMode);
1714 if(ALCdevice_StartPlayback(device) == ALC_FALSE)
1715 return ALC_INVALID_DEVICE;
1716 device->Flags |= DEVICE_RUNNING;
1718 return ALC_NO_ERROR;
1721 /* FreeDevice
1723 * Frees the device structure, and destroys any objects the app failed to
1724 * delete. Called once there's no more references on the device.
1726 static ALCvoid FreeDevice(ALCdevice *device)
1728 TRACE("%p\n", device);
1730 if(device->Type != Capture)
1731 ALCdevice_ClosePlayback(device);
1732 else
1733 ALCdevice_CloseCapture(device);
1735 if(device->DefaultSlot)
1737 ALeffectState_Destroy(device->DefaultSlot->EffectState);
1738 device->DefaultSlot->EffectState = NULL;
1741 if(device->BufferMap.size > 0)
1743 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
1744 ReleaseALBuffers(device);
1746 ResetUIntMap(&device->BufferMap);
1748 if(device->EffectMap.size > 0)
1750 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
1751 ReleaseALEffects(device);
1753 ResetUIntMap(&device->EffectMap);
1755 if(device->FilterMap.size > 0)
1757 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
1758 ReleaseALFilters(device);
1760 ResetUIntMap(&device->FilterMap);
1762 free(device->Bs2b);
1763 device->Bs2b = NULL;
1765 free(device->DeviceName);
1766 device->DeviceName = NULL;
1768 DeleteCriticalSection(&device->Mutex);
1770 al_free(device);
1774 void ALCdevice_IncRef(ALCdevice *device)
1776 RefCount ref;
1777 ref = IncrementRef(&device->ref);
1778 TRACEREF("%p increasing refcount to %u\n", device, ref);
1781 void ALCdevice_DecRef(ALCdevice *device)
1783 RefCount ref;
1784 ref = DecrementRef(&device->ref);
1785 TRACEREF("%p decreasing refcount to %u\n", device, ref);
1786 if(ref == 0) FreeDevice(device);
1789 /* VerifyDevice
1791 * Checks if the device handle is valid, and increments its ref count if so.
1793 static ALCdevice *VerifyDevice(ALCdevice *device)
1795 ALCdevice *tmpDevice;
1797 if(!device)
1798 return NULL;
1800 LockLists();
1801 tmpDevice = DeviceList;
1802 while(tmpDevice && tmpDevice != device)
1803 tmpDevice = tmpDevice->next;
1805 if(tmpDevice)
1806 ALCdevice_IncRef(tmpDevice);
1807 UnlockLists();
1808 return tmpDevice;
1812 /* InitContext
1814 * Initializes context fields
1816 static ALvoid InitContext(ALCcontext *Context)
1818 ALint i, j;
1820 //Initialise listener
1821 Context->Listener->Gain = 1.0f;
1822 Context->Listener->MetersPerUnit = 1.0f;
1823 Context->Listener->Position[0] = 0.0f;
1824 Context->Listener->Position[1] = 0.0f;
1825 Context->Listener->Position[2] = 0.0f;
1826 Context->Listener->Velocity[0] = 0.0f;
1827 Context->Listener->Velocity[1] = 0.0f;
1828 Context->Listener->Velocity[2] = 0.0f;
1829 Context->Listener->Forward[0] = 0.0f;
1830 Context->Listener->Forward[1] = 0.0f;
1831 Context->Listener->Forward[2] = -1.0f;
1832 Context->Listener->Up[0] = 0.0f;
1833 Context->Listener->Up[1] = 1.0f;
1834 Context->Listener->Up[2] = 0.0f;
1835 for(i = 0;i < 4;i++)
1837 for(j = 0;j < 4;j++)
1838 Context->Listener->Params.Matrix[i][j] = ((i==j) ? 1.0f : 0.0f);
1840 for(i = 0;i < 3;i++)
1841 Context->Listener->Params.Velocity[i] = 0.0f;
1843 //Validate Context
1844 Context->LastError = AL_NO_ERROR;
1845 Context->UpdateSources = AL_FALSE;
1846 Context->ActiveSourceCount = 0;
1847 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
1848 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
1850 //Set globals
1851 Context->DistanceModel = DefaultDistanceModel;
1852 Context->SourceDistanceModel = AL_FALSE;
1853 Context->DopplerFactor = 1.0f;
1854 Context->DopplerVelocity = 1.0f;
1855 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
1856 Context->DeferUpdates = AL_FALSE;
1858 Context->ExtensionList = alExtList;
1862 /* FreeContext
1864 * Cleans up the context, and destroys any remaining objects the app failed to
1865 * delete. Called once there's no more references on the context.
1867 static ALCvoid FreeContext(ALCcontext *context)
1869 TRACE("%p\n", context);
1871 if(context->SourceMap.size > 0)
1873 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
1874 ReleaseALSources(context);
1876 ResetUIntMap(&context->SourceMap);
1878 if(context->EffectSlotMap.size > 0)
1880 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
1881 ReleaseALAuxiliaryEffectSlots(context);
1883 ResetUIntMap(&context->EffectSlotMap);
1885 context->ActiveSourceCount = 0;
1886 free(context->ActiveSources);
1887 context->ActiveSources = NULL;
1888 context->MaxActiveSources = 0;
1890 context->ActiveEffectSlotCount = 0;
1891 free(context->ActiveEffectSlots);
1892 context->ActiveEffectSlots = NULL;
1893 context->MaxActiveEffectSlots = 0;
1895 ALCdevice_DecRef(context->Device);
1896 context->Device = NULL;
1898 //Invalidate context
1899 memset(context, 0, sizeof(ALCcontext));
1900 free(context);
1903 /* ReleaseContext
1905 * Removes the context reference from the given device and removes it from
1906 * being current on the running thread or globally.
1908 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
1910 ALCcontext *volatile*tmp_ctx;
1912 if(pthread_getspecific(LocalContext) == context)
1914 WARN("%p released while current on thread\n", context);
1915 pthread_setspecific(LocalContext, NULL);
1916 ALCcontext_DecRef(context);
1919 if(CompExchangePtr((XchgPtr*)&GlobalContext, context, NULL))
1920 ALCcontext_DecRef(context);
1922 ALCdevice_Lock(device);
1923 tmp_ctx = &device->ContextList;
1924 while(*tmp_ctx)
1926 if(CompExchangePtr((XchgPtr*)tmp_ctx, context, context->next))
1927 break;
1928 tmp_ctx = &(*tmp_ctx)->next;
1930 ALCdevice_Unlock(device);
1932 ALCcontext_DecRef(context);
1935 void ALCcontext_IncRef(ALCcontext *context)
1937 RefCount ref;
1938 ref = IncrementRef(&context->ref);
1939 TRACEREF("%p increasing refcount to %u\n", context, ref);
1942 void ALCcontext_DecRef(ALCcontext *context)
1944 RefCount ref;
1945 ref = DecrementRef(&context->ref);
1946 TRACEREF("%p decreasing refcount to %u\n", context, ref);
1947 if(ref == 0) FreeContext(context);
1950 static void ReleaseThreadCtx(void *ptr)
1952 WARN("%p current for thread being destroyed\n", ptr);
1953 ALCcontext_DecRef(ptr);
1956 /* VerifyContext
1958 * Checks that the given context is valid, and increments its reference count.
1960 static ALCcontext *VerifyContext(ALCcontext *context)
1962 ALCdevice *dev;
1964 LockLists();
1965 dev = DeviceList;
1966 while(dev)
1968 ALCcontext *tmp_ctx = dev->ContextList;
1969 while(tmp_ctx)
1971 if(tmp_ctx == context)
1973 ALCcontext_IncRef(tmp_ctx);
1974 UnlockLists();
1975 return tmp_ctx;
1977 tmp_ctx = tmp_ctx->next;
1979 dev = dev->next;
1981 UnlockLists();
1983 return NULL;
1987 /* GetContextRef
1989 * Returns the currently active context for this thread, and adds a reference
1990 * without locking it.
1992 ALCcontext *GetContextRef(void)
1994 ALCcontext *context;
1996 context = pthread_getspecific(LocalContext);
1997 if(context)
1998 ALCcontext_IncRef(context);
1999 else
2001 LockLists();
2002 context = GlobalContext;
2003 if(context)
2004 ALCcontext_IncRef(context);
2005 UnlockLists();
2008 return context;
2012 /************************************************
2013 * Standard ALC functions
2014 ************************************************/
2016 /* alcGetError
2018 * Return last ALC generated error code for the given device
2020 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2022 ALCenum errorCode;
2024 if(VerifyDevice(device))
2026 errorCode = ExchangeInt(&device->LastError, ALC_NO_ERROR);
2027 ALCdevice_DecRef(device);
2029 else
2030 errorCode = ExchangeInt(&LastNullDeviceError, ALC_NO_ERROR);
2032 return errorCode;
2036 /* alcSuspendContext
2038 * Not functional
2040 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *Context)
2042 (void)Context;
2045 /* alcProcessContext
2047 * Not functional
2049 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *Context)
2051 (void)Context;
2055 /* alcGetString
2057 * Returns information about the device, and error strings
2059 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2061 const ALCchar *value = NULL;
2063 switch(param)
2065 case ALC_NO_ERROR:
2066 value = alcNoError;
2067 break;
2069 case ALC_INVALID_ENUM:
2070 value = alcErrInvalidEnum;
2071 break;
2073 case ALC_INVALID_VALUE:
2074 value = alcErrInvalidValue;
2075 break;
2077 case ALC_INVALID_DEVICE:
2078 value = alcErrInvalidDevice;
2079 break;
2081 case ALC_INVALID_CONTEXT:
2082 value = alcErrInvalidContext;
2083 break;
2085 case ALC_OUT_OF_MEMORY:
2086 value = alcErrOutOfMemory;
2087 break;
2089 case ALC_DEVICE_SPECIFIER:
2090 value = alcDefaultName;
2091 break;
2093 case ALC_ALL_DEVICES_SPECIFIER:
2094 if(VerifyDevice(Device))
2096 value = Device->DeviceName;
2097 ALCdevice_DecRef(Device);
2099 else
2101 ProbeAllDevicesList();
2102 value = alcAllDevicesList;
2104 break;
2106 case ALC_CAPTURE_DEVICE_SPECIFIER:
2107 if(VerifyDevice(Device))
2109 value = Device->DeviceName;
2110 ALCdevice_DecRef(Device);
2112 else
2114 ProbeCaptureDeviceList();
2115 value = alcCaptureDeviceList;
2117 break;
2119 /* Default devices are always first in the list */
2120 case ALC_DEFAULT_DEVICE_SPECIFIER:
2121 value = alcDefaultName;
2122 break;
2124 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2125 if(!alcAllDevicesList)
2126 ProbeAllDevicesList();
2128 Device = VerifyDevice(Device);
2130 free(alcDefaultAllDevicesSpecifier);
2131 alcDefaultAllDevicesSpecifier = strdup(alcAllDevicesList ?
2132 alcAllDevicesList : "");
2133 if(!alcDefaultAllDevicesSpecifier)
2134 alcSetError(Device, ALC_OUT_OF_MEMORY);
2136 value = alcDefaultAllDevicesSpecifier;
2137 if(Device) ALCdevice_DecRef(Device);
2138 break;
2140 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2141 if(!alcCaptureDeviceList)
2142 ProbeCaptureDeviceList();
2144 Device = VerifyDevice(Device);
2146 free(alcCaptureDefaultDeviceSpecifier);
2147 alcCaptureDefaultDeviceSpecifier = strdup(alcCaptureDeviceList ?
2148 alcCaptureDeviceList : "");
2149 if(!alcCaptureDefaultDeviceSpecifier)
2150 alcSetError(Device, ALC_OUT_OF_MEMORY);
2152 value = alcCaptureDefaultDeviceSpecifier;
2153 if(Device) ALCdevice_DecRef(Device);
2154 break;
2156 case ALC_EXTENSIONS:
2157 if(!VerifyDevice(Device))
2158 value = alcNoDeviceExtList;
2159 else
2161 value = alcExtensionList;
2162 ALCdevice_DecRef(Device);
2164 break;
2166 default:
2167 Device = VerifyDevice(Device);
2168 alcSetError(Device, ALC_INVALID_ENUM);
2169 if(Device) ALCdevice_DecRef(Device);
2170 break;
2173 return value;
2177 /* alcGetIntegerv
2179 * Returns information about the device and the version of OpenAL
2181 ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsizei size,ALCint *data)
2183 device = VerifyDevice(device);
2185 if(size == 0 || data == NULL)
2187 alcSetError(device, ALC_INVALID_VALUE);
2188 if(device) ALCdevice_DecRef(device);
2189 return;
2192 if(!device)
2194 switch(param)
2196 case ALC_MAJOR_VERSION:
2197 *data = alcMajorVersion;
2198 break;
2199 case ALC_MINOR_VERSION:
2200 *data = alcMinorVersion;
2201 break;
2203 case ALC_ATTRIBUTES_SIZE:
2204 case ALC_ALL_ATTRIBUTES:
2205 case ALC_FREQUENCY:
2206 case ALC_REFRESH:
2207 case ALC_SYNC:
2208 case ALC_MONO_SOURCES:
2209 case ALC_STEREO_SOURCES:
2210 case ALC_CAPTURE_SAMPLES:
2211 case ALC_FORMAT_CHANNELS_SOFT:
2212 case ALC_FORMAT_TYPE_SOFT:
2213 alcSetError(NULL, ALC_INVALID_DEVICE);
2214 break;
2216 default:
2217 alcSetError(NULL, ALC_INVALID_ENUM);
2218 break;
2221 else if(device->Type == Capture)
2223 switch(param)
2225 case ALC_CAPTURE_SAMPLES:
2226 ALCdevice_Lock(device);
2227 *data = ALCdevice_AvailableSamples(device);
2228 ALCdevice_Unlock(device);
2229 break;
2231 case ALC_CONNECTED:
2232 *data = device->Connected;
2233 break;
2235 default:
2236 alcSetError(device, ALC_INVALID_ENUM);
2237 break;
2240 else /* render device */
2242 switch(param)
2244 case ALC_MAJOR_VERSION:
2245 *data = alcMajorVersion;
2246 break;
2248 case ALC_MINOR_VERSION:
2249 *data = alcMinorVersion;
2250 break;
2252 case ALC_EFX_MAJOR_VERSION:
2253 *data = alcEFXMajorVersion;
2254 break;
2256 case ALC_EFX_MINOR_VERSION:
2257 *data = alcEFXMinorVersion;
2258 break;
2260 case ALC_ATTRIBUTES_SIZE:
2261 *data = 13;
2262 break;
2264 case ALC_ALL_ATTRIBUTES:
2265 if(size < 13)
2266 alcSetError(device, ALC_INVALID_VALUE);
2267 else
2269 int i = 0;
2271 data[i++] = ALC_FREQUENCY;
2272 data[i++] = device->Frequency;
2274 if(device->Type != Loopback)
2276 data[i++] = ALC_REFRESH;
2277 data[i++] = device->Frequency / device->UpdateSize;
2279 data[i++] = ALC_SYNC;
2280 data[i++] = ALC_FALSE;
2282 else
2284 data[i++] = ALC_FORMAT_CHANNELS_SOFT;
2285 data[i++] = device->FmtChans;
2287 data[i++] = ALC_FORMAT_TYPE_SOFT;
2288 data[i++] = device->FmtType;
2291 data[i++] = ALC_MONO_SOURCES;
2292 data[i++] = device->NumMonoSources;
2294 data[i++] = ALC_STEREO_SOURCES;
2295 data[i++] = device->NumStereoSources;
2297 data[i++] = ALC_MAX_AUXILIARY_SENDS;
2298 data[i++] = device->NumAuxSends;
2300 data[i++] = 0;
2302 break;
2304 case ALC_FREQUENCY:
2305 *data = device->Frequency;
2306 break;
2308 case ALC_REFRESH:
2309 if(device->Type == Loopback)
2310 alcSetError(device, ALC_INVALID_DEVICE);
2311 else
2312 *data = device->Frequency / device->UpdateSize;
2313 break;
2315 case ALC_SYNC:
2316 if(device->Type == Loopback)
2317 alcSetError(device, ALC_INVALID_DEVICE);
2318 else
2319 *data = ALC_FALSE;
2320 break;
2322 case ALC_FORMAT_CHANNELS_SOFT:
2323 if(device->Type != Loopback)
2324 alcSetError(device, ALC_INVALID_DEVICE);
2325 else
2326 *data = device->FmtChans;
2327 break;
2329 case ALC_FORMAT_TYPE_SOFT:
2330 if(device->Type != Loopback)
2331 alcSetError(device, ALC_INVALID_DEVICE);
2332 else
2333 *data = device->FmtType;
2334 break;
2336 case ALC_MONO_SOURCES:
2337 *data = device->NumMonoSources;
2338 break;
2340 case ALC_STEREO_SOURCES:
2341 *data = device->NumStereoSources;
2342 break;
2344 case ALC_MAX_AUXILIARY_SENDS:
2345 *data = device->NumAuxSends;
2346 break;
2348 case ALC_CONNECTED:
2349 *data = device->Connected;
2350 break;
2352 default:
2353 alcSetError(device, ALC_INVALID_ENUM);
2354 break;
2357 if(device)
2358 ALCdevice_DecRef(device);
2362 /* alcIsExtensionPresent
2364 * Determines if there is support for a particular extension
2366 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2368 ALCboolean bResult = ALC_FALSE;
2370 device = VerifyDevice(device);
2372 if(!extName)
2373 alcSetError(device, ALC_INVALID_VALUE);
2374 else
2376 size_t len = strlen(extName);
2377 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2378 while(ptr && *ptr)
2380 if(strncasecmp(ptr, extName, len) == 0 &&
2381 (ptr[len] == '\0' || isspace(ptr[len])))
2383 bResult = ALC_TRUE;
2384 break;
2386 if((ptr=strchr(ptr, ' ')) != NULL)
2388 do {
2389 ++ptr;
2390 } while(isspace(*ptr));
2394 if(device)
2395 ALCdevice_DecRef(device);
2396 return bResult;
2400 /* alcGetProcAddress
2402 * Retrieves the function address for a particular extension function
2404 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2406 ALCvoid *ptr = NULL;
2408 if(!funcName)
2410 device = VerifyDevice(device);
2411 alcSetError(device, ALC_INVALID_VALUE);
2412 if(device) ALCdevice_DecRef(device);
2414 else
2416 ALsizei i = 0;
2417 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
2418 i++;
2419 ptr = alcFunctions[i].address;
2422 return ptr;
2426 /* alcGetEnumValue
2428 * Get the value for a particular ALC enumeration name
2430 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
2432 ALCenum val = 0;
2434 if(!enumName)
2436 device = VerifyDevice(device);
2437 alcSetError(device, ALC_INVALID_VALUE);
2438 if(device) ALCdevice_DecRef(device);
2440 else
2442 ALsizei i = 0;
2443 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
2444 i++;
2445 val = enumeration[i].value;
2448 return val;
2452 /* alcCreateContext
2454 * Create and attach a context to the given device.
2456 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
2458 ALCcontext *ALContext;
2459 ALCenum err;
2461 LockLists();
2462 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
2464 UnlockLists();
2465 alcSetError(device, ALC_INVALID_DEVICE);
2466 if(device) ALCdevice_DecRef(device);
2467 return NULL;
2470 device->LastError = ALC_NO_ERROR;
2472 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
2474 UnlockLists();
2475 alcSetError(device, err);
2476 if(err == ALC_INVALID_DEVICE)
2477 aluHandleDisconnect(device);
2478 ALCdevice_DecRef(device);
2479 return NULL;
2482 ALContext = calloc(1, sizeof(ALCcontext)+15+sizeof(ALlistener));
2483 if(ALContext)
2485 ALContext->ref = 1;
2486 ALContext->Listener = (ALlistener*)(((ALintptrEXT)(ALContext+1)+15)&~15);
2488 ALContext->MaxActiveSources = 256;
2489 ALContext->ActiveSources = malloc(sizeof(ALContext->ActiveSources[0]) *
2490 ALContext->MaxActiveSources);
2492 if(!ALContext || !ALContext->ActiveSources)
2494 if(!device->ContextList)
2496 ALCdevice_StopPlayback(device);
2497 device->Flags &= ~DEVICE_RUNNING;
2499 UnlockLists();
2501 free(ALContext);
2502 ALContext = NULL;
2504 alcSetError(device, ALC_OUT_OF_MEMORY);
2505 ALCdevice_DecRef(device);
2506 return NULL;
2509 ALContext->Device = device;
2510 ALCdevice_IncRef(device);
2511 InitContext(ALContext);
2513 do {
2514 ALContext->next = device->ContextList;
2515 } while(!CompExchangePtr((XchgPtr*)&device->ContextList, ALContext->next, ALContext));
2516 UnlockLists();
2518 ALCdevice_DecRef(device);
2520 TRACE("Created context %p\n", ALContext);
2521 return ALContext;
2524 /* alcDestroyContext
2526 * Remove a context from its device
2528 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
2530 ALCdevice *Device;
2532 LockLists();
2533 /* alcGetContextsDevice sets an error for invalid contexts */
2534 Device = alcGetContextsDevice(context);
2535 if(Device)
2537 ReleaseContext(context, Device);
2538 if(!Device->ContextList)
2540 ALCdevice_StopPlayback(Device);
2541 Device->Flags &= ~DEVICE_RUNNING;
2544 UnlockLists();
2548 /* alcGetCurrentContext
2550 * Returns the currently active context on the calling thread
2552 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
2554 ALCcontext *Context;
2556 Context = pthread_getspecific(LocalContext);
2557 if(!Context) Context = GlobalContext;
2559 return Context;
2562 /* alcGetThreadContext
2564 * Returns the currently active thread-local context
2566 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
2568 ALCcontext *Context;
2569 Context = pthread_getspecific(LocalContext);
2570 return Context;
2574 /* alcMakeContextCurrent
2576 * Makes the given context the active process-wide context, and removes the
2577 * thread-local context for the calling thread.
2579 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
2581 /* context must be valid or NULL */
2582 if(context && !(context=VerifyContext(context)))
2584 alcSetError(NULL, ALC_INVALID_CONTEXT);
2585 return ALC_FALSE;
2587 /* context's reference count is already incremented */
2588 context = ExchangePtr((XchgPtr*)&GlobalContext, context);
2589 if(context) ALCcontext_DecRef(context);
2591 if((context=pthread_getspecific(LocalContext)) != NULL)
2593 pthread_setspecific(LocalContext, NULL);
2594 ALCcontext_DecRef(context);
2597 return ALC_TRUE;
2600 /* alcSetThreadContext
2602 * Makes the given context the active context for the current thread
2604 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
2606 ALCcontext *old;
2608 /* context must be valid or NULL */
2609 if(context && !(context=VerifyContext(context)))
2611 alcSetError(NULL, ALC_INVALID_CONTEXT);
2612 return ALC_FALSE;
2614 /* context's reference count is already incremented */
2615 old = pthread_getspecific(LocalContext);
2616 pthread_setspecific(LocalContext, context);
2617 if(old) ALCcontext_DecRef(old);
2619 return ALC_TRUE;
2623 /* alcGetContextsDevice
2625 * Returns the device that a particular context is attached to
2627 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
2629 ALCdevice *Device;
2631 if(!(Context=VerifyContext(Context)))
2633 alcSetError(NULL, ALC_INVALID_CONTEXT);
2634 return NULL;
2636 Device = Context->Device;
2637 ALCcontext_DecRef(Context);
2639 return Device;
2643 /* alcOpenDevice
2645 * Opens the named device.
2647 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
2649 const ALCchar *fmt;
2650 ALCdevice *device;
2651 ALCenum err;
2653 DO_INITCONFIG();
2655 if(!PlaybackBackend.name)
2657 alcSetError(NULL, ALC_INVALID_VALUE);
2658 return NULL;
2661 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
2662 deviceName = NULL;
2664 device = al_calloc(16, sizeof(ALCdevice)+15+sizeof(ALeffectslot));
2665 if(!device)
2667 alcSetError(NULL, ALC_OUT_OF_MEMORY);
2668 return NULL;
2671 //Validate device
2672 device->Funcs = &PlaybackBackend.Funcs;
2673 device->ref = 1;
2674 device->Connected = ALC_TRUE;
2675 device->Type = Playback;
2676 InitializeCriticalSection(&device->Mutex);
2677 device->LastError = ALC_NO_ERROR;
2679 device->Flags = 0;
2680 device->Bs2b = NULL;
2681 device->Bs2bLevel = 0;
2682 device->DeviceName = NULL;
2684 device->ContextList = NULL;
2686 device->MaxNoOfSources = 256;
2687 device->AuxiliaryEffectSlotMax = 4;
2688 device->NumAuxSends = MAX_SENDS;
2690 InitUIntMap(&device->BufferMap, ~0);
2691 InitUIntMap(&device->EffectMap, ~0);
2692 InitUIntMap(&device->FilterMap, ~0);
2694 //Set output format
2695 device->FmtChans = DevFmtChannelsDefault;
2696 device->FmtType = DevFmtTypeDefault;
2697 device->Frequency = DEFAULT_OUTPUT_RATE;
2698 device->NumUpdates = 4;
2699 device->UpdateSize = 1024;
2701 if(ConfigValueStr(NULL, "channels", &fmt))
2703 static const struct {
2704 const char name[16];
2705 enum DevFmtChannels chans;
2706 } chanlist[] = {
2707 { "mono", DevFmtMono },
2708 { "stereo", DevFmtStereo },
2709 { "quad", DevFmtQuad },
2710 { "surround51", DevFmtX51 },
2711 { "surround61", DevFmtX61 },
2712 { "surround71", DevFmtX71 },
2714 size_t i;
2716 for(i = 0;i < COUNTOF(chanlist);i++)
2718 if(strcasecmp(chanlist[i].name, fmt) == 0)
2720 device->FmtChans = chanlist[i].chans;
2721 device->Flags |= DEVICE_CHANNELS_REQUEST;
2722 break;
2725 if(i == COUNTOF(chanlist))
2726 ERR("Unsupported channels: %s\n", fmt);
2728 if(ConfigValueStr(NULL, "sample-type", &fmt))
2730 static const struct {
2731 const char name[16];
2732 enum DevFmtType type;
2733 } typelist[] = {
2734 { "int8", DevFmtByte },
2735 { "uint8", DevFmtUByte },
2736 { "int16", DevFmtShort },
2737 { "uint16", DevFmtUShort },
2738 { "int32", DevFmtInt },
2739 { "uint32", DevFmtUInt },
2740 { "float32", DevFmtFloat },
2742 size_t i;
2744 for(i = 0;i < COUNTOF(typelist);i++)
2746 if(strcasecmp(typelist[i].name, fmt) == 0)
2748 device->FmtType = typelist[i].type;
2749 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
2750 break;
2753 if(i == COUNTOF(typelist))
2754 ERR("Unsupported sample-type: %s\n", fmt);
2756 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
2757 if((device->Flags&DEVICE_FORMAT_REQUEST) != DEVICE_FORMAT_REQUEST &&
2758 ConfigValueStr(NULL, "format", &fmt))
2760 static const struct {
2761 const char name[32];
2762 enum DevFmtChannels channels;
2763 enum DevFmtType type;
2764 } formats[] = {
2765 { "AL_FORMAT_MONO32", DevFmtMono, DevFmtFloat },
2766 { "AL_FORMAT_STEREO32", DevFmtStereo, DevFmtFloat },
2767 { "AL_FORMAT_QUAD32", DevFmtQuad, DevFmtFloat },
2768 { "AL_FORMAT_51CHN32", DevFmtX51, DevFmtFloat },
2769 { "AL_FORMAT_61CHN32", DevFmtX61, DevFmtFloat },
2770 { "AL_FORMAT_71CHN32", DevFmtX71, DevFmtFloat },
2772 { "AL_FORMAT_MONO16", DevFmtMono, DevFmtShort },
2773 { "AL_FORMAT_STEREO16", DevFmtStereo, DevFmtShort },
2774 { "AL_FORMAT_QUAD16", DevFmtQuad, DevFmtShort },
2775 { "AL_FORMAT_51CHN16", DevFmtX51, DevFmtShort },
2776 { "AL_FORMAT_61CHN16", DevFmtX61, DevFmtShort },
2777 { "AL_FORMAT_71CHN16", DevFmtX71, DevFmtShort },
2779 { "AL_FORMAT_MONO8", DevFmtMono, DevFmtByte },
2780 { "AL_FORMAT_STEREO8", DevFmtStereo, DevFmtByte },
2781 { "AL_FORMAT_QUAD8", DevFmtQuad, DevFmtByte },
2782 { "AL_FORMAT_51CHN8", DevFmtX51, DevFmtByte },
2783 { "AL_FORMAT_61CHN8", DevFmtX61, DevFmtByte },
2784 { "AL_FORMAT_71CHN8", DevFmtX71, DevFmtByte }
2786 size_t i;
2788 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
2789 for(i = 0;i < COUNTOF(formats);i++)
2791 if(strcasecmp(fmt, formats[i].name) == 0)
2793 if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
2794 device->FmtChans = formats[i].channels;
2795 if(!(device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
2796 device->FmtType = formats[i].type;
2797 device->Flags |= DEVICE_FORMAT_REQUEST;
2798 break;
2801 if(i == COUNTOF(formats))
2802 ERR("Unsupported format: %s\n", fmt);
2804 #undef DEVICE_FORMAT_REQUEST
2806 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
2808 device->Flags |= DEVICE_FREQUENCY_REQUEST;
2809 if(device->Frequency < MIN_OUTPUT_RATE)
2810 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
2811 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
2814 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
2815 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
2817 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
2818 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
2819 if((CPUCapFlags&CPU_CAP_SSE))
2820 device->UpdateSize = (device->UpdateSize+3)&~3;
2822 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
2823 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
2825 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
2826 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
2828 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
2829 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
2831 ConfigValueInt(NULL, "cf_level", &device->Bs2bLevel);
2833 device->NumStereoSources = 1;
2834 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
2836 // Find a playback device to open
2837 if((err=ALCdevice_OpenPlayback(device, deviceName)) != ALC_NO_ERROR)
2839 DeleteCriticalSection(&device->Mutex);
2840 al_free(device);
2841 alcSetError(NULL, err);
2842 return NULL;
2845 if(DefaultEffect.type != AL_EFFECT_NULL)
2847 device->DefaultSlot = (ALeffectslot*)(((ALintptrEXT)(device+1)+15)&~15);
2848 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
2850 device->DefaultSlot = NULL;
2851 ERR("Failed to initialize the default effect slot\n");
2853 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
2855 ALeffectState_Destroy(device->DefaultSlot->EffectState);
2856 device->DefaultSlot = NULL;
2857 ERR("Failed to initialize the default effect\n");
2861 do {
2862 device->next = DeviceList;
2863 } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device));
2865 TRACE("Created device %p, \"%s\"\n", device, device->DeviceName);
2866 return device;
2869 /* alcCloseDevice
2871 * Closes the given device.
2873 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *Device)
2875 ALCdevice *volatile*list;
2876 ALCcontext *ctx;
2878 LockLists();
2879 list = &DeviceList;
2880 while(*list && *list != Device)
2881 list = &(*list)->next;
2883 if(!*list || (*list)->Type == Capture)
2885 alcSetError(*list, ALC_INVALID_DEVICE);
2886 UnlockLists();
2887 return ALC_FALSE;
2890 *list = (*list)->next;
2891 UnlockLists();
2893 while((ctx=Device->ContextList) != NULL)
2895 WARN("Releasing context %p\n", ctx);
2896 ReleaseContext(ctx, Device);
2898 if((Device->Flags&DEVICE_RUNNING))
2899 ALCdevice_StopPlayback(Device);
2900 Device->Flags &= ~DEVICE_RUNNING;
2902 ALCdevice_DecRef(Device);
2904 return ALC_TRUE;
2908 /************************************************
2909 * ALC capture functions
2910 ************************************************/
2911 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
2913 ALCdevice *device = NULL;
2914 ALCenum err;
2916 DO_INITCONFIG();
2918 if(!CaptureBackend.name)
2920 alcSetError(NULL, ALC_INVALID_VALUE);
2921 return NULL;
2924 if(samples <= 0)
2926 alcSetError(NULL, ALC_INVALID_VALUE);
2927 return NULL;
2930 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
2931 deviceName = NULL;
2933 device = al_calloc(16, sizeof(ALCdevice));
2934 if(!device)
2936 alcSetError(NULL, ALC_OUT_OF_MEMORY);
2937 return NULL;
2940 //Validate device
2941 device->Funcs = &CaptureBackend.Funcs;
2942 device->ref = 1;
2943 device->Connected = ALC_TRUE;
2944 device->Type = Capture;
2945 InitializeCriticalSection(&device->Mutex);
2947 InitUIntMap(&device->BufferMap, ~0);
2948 InitUIntMap(&device->EffectMap, ~0);
2949 InitUIntMap(&device->FilterMap, ~0);
2951 device->DeviceName = NULL;
2953 device->Flags |= DEVICE_FREQUENCY_REQUEST;
2954 device->Frequency = frequency;
2956 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
2957 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
2959 DeleteCriticalSection(&device->Mutex);
2960 al_free(device);
2961 alcSetError(NULL, ALC_INVALID_ENUM);
2962 return NULL;
2965 device->UpdateSize = samples;
2966 device->NumUpdates = 1;
2968 if((err=ALCdevice_OpenCapture(device, deviceName)) != ALC_NO_ERROR)
2970 DeleteCriticalSection(&device->Mutex);
2971 al_free(device);
2972 alcSetError(NULL, err);
2973 return NULL;
2976 do {
2977 device->next = DeviceList;
2978 } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device));
2980 TRACE("Created device %p, \"%s\"\n", device, device->DeviceName);
2981 return device;
2984 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *Device)
2986 ALCdevice *volatile*list;
2988 LockLists();
2989 list = &DeviceList;
2990 while(*list && *list != Device)
2991 list = &(*list)->next;
2993 if(!*list || (*list)->Type != Capture)
2995 alcSetError(*list, ALC_INVALID_DEVICE);
2996 UnlockLists();
2997 return ALC_FALSE;
3000 *list = (*list)->next;
3001 UnlockLists();
3003 ALCdevice_DecRef(Device);
3005 return ALC_TRUE;
3008 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3010 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3011 alcSetError(device, ALC_INVALID_DEVICE);
3012 else
3014 ALCdevice_Lock(device);
3015 if(device->Connected)
3017 if(!(device->Flags&DEVICE_RUNNING))
3018 ALCdevice_StartCapture(device);
3019 device->Flags |= DEVICE_RUNNING;
3021 ALCdevice_Unlock(device);
3024 if(device) ALCdevice_DecRef(device);
3027 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3029 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3030 alcSetError(device, ALC_INVALID_DEVICE);
3031 else
3033 ALCdevice_Lock(device);
3034 if((device->Flags&DEVICE_RUNNING))
3035 ALCdevice_StopCapture(device);
3036 device->Flags &= ~DEVICE_RUNNING;
3037 ALCdevice_Unlock(device);
3040 if(device) ALCdevice_DecRef(device);
3043 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3045 if(!(device=VerifyDevice(device)) && device->Type != Capture)
3046 alcSetError(device, ALC_INVALID_DEVICE);
3047 else
3049 ALCenum err = ALC_INVALID_VALUE;
3051 ALCdevice_Lock(device);
3052 if(samples >= 0 && ALCdevice_AvailableSamples(device) >= (ALCuint)samples)
3053 err = ALCdevice_CaptureSamples(device, buffer, samples);
3054 ALCdevice_Unlock(device);
3056 if(err != ALC_NO_ERROR)
3057 alcSetError(device, err);
3059 if(device) ALCdevice_DecRef(device);
3063 /************************************************
3064 * ALC loopback functions
3065 ************************************************/
3067 /* alcLoopbackOpenDeviceSOFT
3069 * Open a loopback device, for manual rendering.
3071 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3073 ALCdevice *device;
3075 DO_INITCONFIG();
3077 /* Make sure the device name, if specified, is us. */
3078 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3080 alcSetError(NULL, ALC_INVALID_VALUE);
3081 return NULL;
3084 device = al_calloc(16, sizeof(ALCdevice));
3085 if(!device)
3087 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3088 return NULL;
3091 //Validate device
3092 device->Funcs = &BackendLoopback.Funcs;
3093 device->ref = 1;
3094 device->Connected = ALC_TRUE;
3095 device->Type = Loopback;
3096 InitializeCriticalSection(&device->Mutex);
3097 device->LastError = ALC_NO_ERROR;
3099 device->Flags = 0;
3100 device->Bs2b = NULL;
3101 device->Bs2bLevel = 0;
3102 device->DeviceName = NULL;
3104 device->ContextList = NULL;
3106 device->MaxNoOfSources = 256;
3107 device->AuxiliaryEffectSlotMax = 4;
3108 device->NumAuxSends = MAX_SENDS;
3110 InitUIntMap(&device->BufferMap, ~0);
3111 InitUIntMap(&device->EffectMap, ~0);
3112 InitUIntMap(&device->FilterMap, ~0);
3114 //Set output format
3115 device->NumUpdates = 0;
3116 device->UpdateSize = 0;
3118 device->Frequency = DEFAULT_OUTPUT_RATE;
3119 device->FmtChans = DevFmtChannelsDefault;
3120 device->FmtType = DevFmtTypeDefault;
3122 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3123 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3125 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3126 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3128 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3129 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3131 device->NumStereoSources = 1;
3132 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3134 // Open the "backend"
3135 ALCdevice_OpenPlayback(device, "Loopback");
3136 do {
3137 device->next = DeviceList;
3138 } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device));
3140 TRACE("Created device %p\n", device);
3141 return device;
3144 /* alcIsRenderFormatSupportedSOFT
3146 * Determines if the loopback device supports the given format for rendering.
3148 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3150 ALCboolean ret = ALC_FALSE;
3152 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3153 alcSetError(device, ALC_INVALID_DEVICE);
3154 else if(freq <= 0)
3155 alcSetError(device, ALC_INVALID_VALUE);
3156 else
3158 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3159 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3160 freq >= MIN_OUTPUT_RATE)
3161 ret = ALC_TRUE;
3163 if(device) ALCdevice_DecRef(device);
3165 return ret;
3168 /* alcRenderSamplesSOFT
3170 * Renders some samples into a buffer, using the format last set by the
3171 * attributes given to alcCreateContext.
3173 ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3175 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3176 alcSetError(device, ALC_INVALID_DEVICE);
3177 else if(samples < 0 || (samples > 0 && buffer == NULL))
3178 alcSetError(device, ALC_INVALID_VALUE);
3179 else
3180 aluMixData(device, buffer, samples);
3181 if(device) ALCdevice_DecRef(device);