Use an ATOMIC_INIT macro instead of ATOMIC_LOAD_UNSAFE
[openal-soft.git] / Alc / ALc.c
blobf0875f37098b0e83f5635039c721ba07d949a586
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 "alMidi.h"
39 #include "bs2b.h"
40 #include "alu.h"
42 #include "compat.h"
43 #include "threads.h"
44 #include "alstring.h"
46 #include "backends/base.h"
47 #include "midi/base.h"
50 /************************************************
51 * Backends
52 ************************************************/
53 struct BackendInfo {
54 const char *name;
55 ALCbackendFactory* (*getFactory)(void);
56 ALCboolean (*Init)(BackendFuncs*);
57 void (*Deinit)(void);
58 void (*Probe)(enum DevProbe);
59 BackendFuncs Funcs;
62 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
63 static struct BackendInfo BackendList[] = {
64 #ifdef HAVE_PULSEAUDIO
65 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
66 #endif
67 #ifdef HAVE_ALSA
68 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
69 #endif
70 #ifdef HAVE_COREAUDIO
71 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
72 #endif
73 #ifdef HAVE_OSS
74 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
75 #endif
76 #ifdef HAVE_SOLARIS
77 { "solaris", NULL, alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs },
78 #endif
79 #ifdef HAVE_SNDIO
80 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
81 #endif
82 #ifdef HAVE_QSA
83 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
84 #endif
85 #ifdef HAVE_MMDEVAPI
86 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
87 #endif
88 #ifdef HAVE_DSOUND
89 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
90 #endif
91 #ifdef HAVE_WINMM
92 { "winmm", NULL, alcWinMMInit, alcWinMMDeinit, alcWinMMProbe, EmptyFuncs },
93 #endif
94 #ifdef HAVE_PORTAUDIO
95 { "port", NULL, alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs },
96 #endif
97 #ifdef HAVE_OPENSL
98 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
99 #endif
101 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
102 #ifdef HAVE_WAVE
103 { "wave", NULL, alc_wave_init, alc_wave_deinit, alc_wave_probe, EmptyFuncs },
104 #endif
106 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
108 #undef EmptyFuncs
110 static struct BackendInfo PlaybackBackend;
111 static struct BackendInfo CaptureBackend;
114 /************************************************
115 * Functions, enums, and errors
116 ************************************************/
117 typedef struct ALCfunction {
118 const ALCchar *funcName;
119 ALCvoid *address;
120 } ALCfunction;
122 typedef struct ALCenums {
123 const ALCchar *enumName;
124 ALCenum value;
125 } ALCenums;
127 #define DECL(x) { #x, (ALCvoid*)(x) }
128 static const ALCfunction alcFunctions[] = {
129 DECL(alcCreateContext),
130 DECL(alcMakeContextCurrent),
131 DECL(alcProcessContext),
132 DECL(alcSuspendContext),
133 DECL(alcDestroyContext),
134 DECL(alcGetCurrentContext),
135 DECL(alcGetContextsDevice),
136 DECL(alcOpenDevice),
137 DECL(alcCloseDevice),
138 DECL(alcGetError),
139 DECL(alcIsExtensionPresent),
140 DECL(alcGetProcAddress),
141 DECL(alcGetEnumValue),
142 DECL(alcGetString),
143 DECL(alcGetIntegerv),
144 DECL(alcCaptureOpenDevice),
145 DECL(alcCaptureCloseDevice),
146 DECL(alcCaptureStart),
147 DECL(alcCaptureStop),
148 DECL(alcCaptureSamples),
150 DECL(alcSetThreadContext),
151 DECL(alcGetThreadContext),
153 DECL(alcLoopbackOpenDeviceSOFT),
154 DECL(alcIsRenderFormatSupportedSOFT),
155 DECL(alcRenderSamplesSOFT),
157 DECL(alcDevicePauseSOFT),
158 DECL(alcDeviceResumeSOFT),
160 DECL(alcGetInteger64vSOFT),
162 DECL(alEnable),
163 DECL(alDisable),
164 DECL(alIsEnabled),
165 DECL(alGetString),
166 DECL(alGetBooleanv),
167 DECL(alGetIntegerv),
168 DECL(alGetFloatv),
169 DECL(alGetDoublev),
170 DECL(alGetBoolean),
171 DECL(alGetInteger),
172 DECL(alGetFloat),
173 DECL(alGetDouble),
174 DECL(alGetError),
175 DECL(alIsExtensionPresent),
176 DECL(alGetProcAddress),
177 DECL(alGetEnumValue),
178 DECL(alListenerf),
179 DECL(alListener3f),
180 DECL(alListenerfv),
181 DECL(alListeneri),
182 DECL(alListener3i),
183 DECL(alListeneriv),
184 DECL(alGetListenerf),
185 DECL(alGetListener3f),
186 DECL(alGetListenerfv),
187 DECL(alGetListeneri),
188 DECL(alGetListener3i),
189 DECL(alGetListeneriv),
190 DECL(alGenSources),
191 DECL(alDeleteSources),
192 DECL(alIsSource),
193 DECL(alSourcef),
194 DECL(alSource3f),
195 DECL(alSourcefv),
196 DECL(alSourcei),
197 DECL(alSource3i),
198 DECL(alSourceiv),
199 DECL(alGetSourcef),
200 DECL(alGetSource3f),
201 DECL(alGetSourcefv),
202 DECL(alGetSourcei),
203 DECL(alGetSource3i),
204 DECL(alGetSourceiv),
205 DECL(alSourcePlayv),
206 DECL(alSourceStopv),
207 DECL(alSourceRewindv),
208 DECL(alSourcePausev),
209 DECL(alSourcePlay),
210 DECL(alSourceStop),
211 DECL(alSourceRewind),
212 DECL(alSourcePause),
213 DECL(alSourceQueueBuffers),
214 DECL(alSourceUnqueueBuffers),
215 DECL(alGenBuffers),
216 DECL(alDeleteBuffers),
217 DECL(alIsBuffer),
218 DECL(alBufferData),
219 DECL(alBufferf),
220 DECL(alBuffer3f),
221 DECL(alBufferfv),
222 DECL(alBufferi),
223 DECL(alBuffer3i),
224 DECL(alBufferiv),
225 DECL(alGetBufferf),
226 DECL(alGetBuffer3f),
227 DECL(alGetBufferfv),
228 DECL(alGetBufferi),
229 DECL(alGetBuffer3i),
230 DECL(alGetBufferiv),
231 DECL(alDopplerFactor),
232 DECL(alDopplerVelocity),
233 DECL(alSpeedOfSound),
234 DECL(alDistanceModel),
236 DECL(alGenFilters),
237 DECL(alDeleteFilters),
238 DECL(alIsFilter),
239 DECL(alFilteri),
240 DECL(alFilteriv),
241 DECL(alFilterf),
242 DECL(alFilterfv),
243 DECL(alGetFilteri),
244 DECL(alGetFilteriv),
245 DECL(alGetFilterf),
246 DECL(alGetFilterfv),
247 DECL(alGenEffects),
248 DECL(alDeleteEffects),
249 DECL(alIsEffect),
250 DECL(alEffecti),
251 DECL(alEffectiv),
252 DECL(alEffectf),
253 DECL(alEffectfv),
254 DECL(alGetEffecti),
255 DECL(alGetEffectiv),
256 DECL(alGetEffectf),
257 DECL(alGetEffectfv),
258 DECL(alGenAuxiliaryEffectSlots),
259 DECL(alDeleteAuxiliaryEffectSlots),
260 DECL(alIsAuxiliaryEffectSlot),
261 DECL(alAuxiliaryEffectSloti),
262 DECL(alAuxiliaryEffectSlotiv),
263 DECL(alAuxiliaryEffectSlotf),
264 DECL(alAuxiliaryEffectSlotfv),
265 DECL(alGetAuxiliaryEffectSloti),
266 DECL(alGetAuxiliaryEffectSlotiv),
267 DECL(alGetAuxiliaryEffectSlotf),
268 DECL(alGetAuxiliaryEffectSlotfv),
270 DECL(alBufferSubDataSOFT),
272 DECL(alBufferSamplesSOFT),
273 DECL(alBufferSubSamplesSOFT),
274 DECL(alGetBufferSamplesSOFT),
275 DECL(alIsBufferFormatSupportedSOFT),
277 DECL(alDeferUpdatesSOFT),
278 DECL(alProcessUpdatesSOFT),
280 DECL(alSourcedSOFT),
281 DECL(alSource3dSOFT),
282 DECL(alSourcedvSOFT),
283 DECL(alGetSourcedSOFT),
284 DECL(alGetSource3dSOFT),
285 DECL(alGetSourcedvSOFT),
286 DECL(alSourcei64SOFT),
287 DECL(alSource3i64SOFT),
288 DECL(alSourcei64vSOFT),
289 DECL(alGetSourcei64SOFT),
290 DECL(alGetSource3i64SOFT),
291 DECL(alGetSourcei64vSOFT),
293 DECL(alGenSoundfontsSOFT),
294 DECL(alDeleteSoundfontsSOFT),
295 DECL(alIsSoundfontSOFT),
296 DECL(alGetSoundfontivSOFT),
297 DECL(alSoundfontPresetsSOFT),
298 DECL(alGenPresetsSOFT),
299 DECL(alDeletePresetsSOFT),
300 DECL(alIsPresetSOFT),
301 DECL(alPresetiSOFT),
302 DECL(alPresetivSOFT),
303 DECL(alGetPresetivSOFT),
304 DECL(alPresetFontsoundsSOFT),
305 DECL(alGenFontsoundsSOFT),
306 DECL(alDeleteFontsoundsSOFT),
307 DECL(alIsFontsoundSOFT),
308 DECL(alFontsoundiSOFT),
309 DECL(alFontsound2iSOFT),
310 DECL(alFontsoundivSOFT),
311 DECL(alGetFontsoundivSOFT),
312 DECL(alFontsoundModulatoriSOFT),
313 DECL(alGetFontsoundModulatorivSOFT),
314 DECL(alMidiSoundfontSOFT),
315 DECL(alMidiSoundfontvSOFT),
316 DECL(alMidiEventSOFT),
317 DECL(alMidiSysExSOFT),
318 DECL(alMidiPlaySOFT),
319 DECL(alMidiPauseSOFT),
320 DECL(alMidiStopSOFT),
321 DECL(alMidiResetSOFT),
322 DECL(alMidiGainSOFT),
323 DECL(alGetInteger64SOFT),
324 DECL(alGetInteger64vSOFT),
325 DECL(alLoadSoundfontSOFT),
327 { NULL, NULL }
329 #undef DECL
331 #define DECL(x) { #x, (x) }
332 static const ALCenums enumeration[] = {
333 DECL(ALC_INVALID),
334 DECL(ALC_FALSE),
335 DECL(ALC_TRUE),
337 DECL(ALC_MAJOR_VERSION),
338 DECL(ALC_MINOR_VERSION),
339 DECL(ALC_ATTRIBUTES_SIZE),
340 DECL(ALC_ALL_ATTRIBUTES),
341 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
342 DECL(ALC_DEVICE_SPECIFIER),
343 DECL(ALC_ALL_DEVICES_SPECIFIER),
344 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
345 DECL(ALC_EXTENSIONS),
346 DECL(ALC_FREQUENCY),
347 DECL(ALC_REFRESH),
348 DECL(ALC_SYNC),
349 DECL(ALC_MONO_SOURCES),
350 DECL(ALC_STEREO_SOURCES),
351 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
352 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
353 DECL(ALC_CAPTURE_SAMPLES),
354 DECL(ALC_CONNECTED),
356 DECL(ALC_EFX_MAJOR_VERSION),
357 DECL(ALC_EFX_MINOR_VERSION),
358 DECL(ALC_MAX_AUXILIARY_SENDS),
360 DECL(ALC_FORMAT_CHANNELS_SOFT),
361 DECL(ALC_FORMAT_TYPE_SOFT),
363 DECL(ALC_MONO_SOFT),
364 DECL(ALC_STEREO_SOFT),
365 DECL(ALC_QUAD_SOFT),
366 DECL(ALC_5POINT1_SOFT),
367 DECL(ALC_6POINT1_SOFT),
368 DECL(ALC_7POINT1_SOFT),
370 DECL(ALC_BYTE_SOFT),
371 DECL(ALC_UNSIGNED_BYTE_SOFT),
372 DECL(ALC_SHORT_SOFT),
373 DECL(ALC_UNSIGNED_SHORT_SOFT),
374 DECL(ALC_INT_SOFT),
375 DECL(ALC_UNSIGNED_INT_SOFT),
376 DECL(ALC_FLOAT_SOFT),
378 DECL(ALC_NO_ERROR),
379 DECL(ALC_INVALID_DEVICE),
380 DECL(ALC_INVALID_CONTEXT),
381 DECL(ALC_INVALID_ENUM),
382 DECL(ALC_INVALID_VALUE),
383 DECL(ALC_OUT_OF_MEMORY),
386 DECL(AL_INVALID),
387 DECL(AL_NONE),
388 DECL(AL_FALSE),
389 DECL(AL_TRUE),
391 DECL(AL_SOURCE_RELATIVE),
392 DECL(AL_CONE_INNER_ANGLE),
393 DECL(AL_CONE_OUTER_ANGLE),
394 DECL(AL_PITCH),
395 DECL(AL_POSITION),
396 DECL(AL_DIRECTION),
397 DECL(AL_VELOCITY),
398 DECL(AL_LOOPING),
399 DECL(AL_BUFFER),
400 DECL(AL_GAIN),
401 DECL(AL_MIN_GAIN),
402 DECL(AL_MAX_GAIN),
403 DECL(AL_ORIENTATION),
404 DECL(AL_REFERENCE_DISTANCE),
405 DECL(AL_ROLLOFF_FACTOR),
406 DECL(AL_CONE_OUTER_GAIN),
407 DECL(AL_MAX_DISTANCE),
408 DECL(AL_SEC_OFFSET),
409 DECL(AL_SAMPLE_OFFSET),
410 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
411 DECL(AL_BYTE_OFFSET),
412 DECL(AL_BYTE_RW_OFFSETS_SOFT),
413 DECL(AL_SOURCE_TYPE),
414 DECL(AL_STATIC),
415 DECL(AL_STREAMING),
416 DECL(AL_UNDETERMINED),
417 DECL(AL_METERS_PER_UNIT),
418 DECL(AL_DIRECT_CHANNELS_SOFT),
420 DECL(AL_DIRECT_FILTER),
421 DECL(AL_AUXILIARY_SEND_FILTER),
422 DECL(AL_AIR_ABSORPTION_FACTOR),
423 DECL(AL_ROOM_ROLLOFF_FACTOR),
424 DECL(AL_CONE_OUTER_GAINHF),
425 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
426 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
427 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
429 DECL(AL_SOURCE_STATE),
430 DECL(AL_INITIAL),
431 DECL(AL_PLAYING),
432 DECL(AL_PAUSED),
433 DECL(AL_STOPPED),
435 DECL(AL_BUFFERS_QUEUED),
436 DECL(AL_BUFFERS_PROCESSED),
438 DECL(AL_FORMAT_MONO8),
439 DECL(AL_FORMAT_MONO16),
440 DECL(AL_FORMAT_MONO_FLOAT32),
441 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
442 DECL(AL_FORMAT_STEREO8),
443 DECL(AL_FORMAT_STEREO16),
444 DECL(AL_FORMAT_STEREO_FLOAT32),
445 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
446 DECL(AL_FORMAT_MONO_IMA4),
447 DECL(AL_FORMAT_STEREO_IMA4),
448 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
449 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
450 DECL(AL_FORMAT_QUAD8_LOKI),
451 DECL(AL_FORMAT_QUAD16_LOKI),
452 DECL(AL_FORMAT_QUAD8),
453 DECL(AL_FORMAT_QUAD16),
454 DECL(AL_FORMAT_QUAD32),
455 DECL(AL_FORMAT_51CHN8),
456 DECL(AL_FORMAT_51CHN16),
457 DECL(AL_FORMAT_51CHN32),
458 DECL(AL_FORMAT_61CHN8),
459 DECL(AL_FORMAT_61CHN16),
460 DECL(AL_FORMAT_61CHN32),
461 DECL(AL_FORMAT_71CHN8),
462 DECL(AL_FORMAT_71CHN16),
463 DECL(AL_FORMAT_71CHN32),
464 DECL(AL_FORMAT_REAR8),
465 DECL(AL_FORMAT_REAR16),
466 DECL(AL_FORMAT_REAR32),
467 DECL(AL_FORMAT_MONO_MULAW),
468 DECL(AL_FORMAT_MONO_MULAW_EXT),
469 DECL(AL_FORMAT_STEREO_MULAW),
470 DECL(AL_FORMAT_STEREO_MULAW_EXT),
471 DECL(AL_FORMAT_QUAD_MULAW),
472 DECL(AL_FORMAT_51CHN_MULAW),
473 DECL(AL_FORMAT_61CHN_MULAW),
474 DECL(AL_FORMAT_71CHN_MULAW),
475 DECL(AL_FORMAT_REAR_MULAW),
476 DECL(AL_FORMAT_MONO_ALAW_EXT),
477 DECL(AL_FORMAT_STEREO_ALAW_EXT),
479 DECL(AL_MONO8_SOFT),
480 DECL(AL_MONO16_SOFT),
481 DECL(AL_MONO32F_SOFT),
482 DECL(AL_STEREO8_SOFT),
483 DECL(AL_STEREO16_SOFT),
484 DECL(AL_STEREO32F_SOFT),
485 DECL(AL_QUAD8_SOFT),
486 DECL(AL_QUAD16_SOFT),
487 DECL(AL_QUAD32F_SOFT),
488 DECL(AL_REAR8_SOFT),
489 DECL(AL_REAR16_SOFT),
490 DECL(AL_REAR32F_SOFT),
491 DECL(AL_5POINT1_8_SOFT),
492 DECL(AL_5POINT1_16_SOFT),
493 DECL(AL_5POINT1_32F_SOFT),
494 DECL(AL_6POINT1_8_SOFT),
495 DECL(AL_6POINT1_16_SOFT),
496 DECL(AL_6POINT1_32F_SOFT),
497 DECL(AL_7POINT1_8_SOFT),
498 DECL(AL_7POINT1_16_SOFT),
499 DECL(AL_7POINT1_32F_SOFT),
501 DECL(AL_MONO_SOFT),
502 DECL(AL_STEREO_SOFT),
503 DECL(AL_QUAD_SOFT),
504 DECL(AL_REAR_SOFT),
505 DECL(AL_5POINT1_SOFT),
506 DECL(AL_6POINT1_SOFT),
507 DECL(AL_7POINT1_SOFT),
509 DECL(AL_BYTE_SOFT),
510 DECL(AL_UNSIGNED_BYTE_SOFT),
511 DECL(AL_SHORT_SOFT),
512 DECL(AL_UNSIGNED_SHORT_SOFT),
513 DECL(AL_INT_SOFT),
514 DECL(AL_UNSIGNED_INT_SOFT),
515 DECL(AL_FLOAT_SOFT),
516 DECL(AL_DOUBLE_SOFT),
517 DECL(AL_BYTE3_SOFT),
518 DECL(AL_UNSIGNED_BYTE3_SOFT),
520 DECL(AL_FREQUENCY),
521 DECL(AL_BITS),
522 DECL(AL_CHANNELS),
523 DECL(AL_SIZE),
524 DECL(AL_INTERNAL_FORMAT_SOFT),
525 DECL(AL_BYTE_LENGTH_SOFT),
526 DECL(AL_SAMPLE_LENGTH_SOFT),
527 DECL(AL_SEC_LENGTH_SOFT),
528 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
529 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
531 DECL(AL_UNUSED),
532 DECL(AL_PENDING),
533 DECL(AL_PROCESSED),
535 DECL(AL_NO_ERROR),
536 DECL(AL_INVALID_NAME),
537 DECL(AL_INVALID_ENUM),
538 DECL(AL_INVALID_VALUE),
539 DECL(AL_INVALID_OPERATION),
540 DECL(AL_OUT_OF_MEMORY),
542 DECL(AL_VENDOR),
543 DECL(AL_VERSION),
544 DECL(AL_RENDERER),
545 DECL(AL_EXTENSIONS),
547 DECL(AL_DOPPLER_FACTOR),
548 DECL(AL_DOPPLER_VELOCITY),
549 DECL(AL_DISTANCE_MODEL),
550 DECL(AL_SPEED_OF_SOUND),
551 DECL(AL_SOURCE_DISTANCE_MODEL),
552 DECL(AL_DEFERRED_UPDATES_SOFT),
554 DECL(AL_INVERSE_DISTANCE),
555 DECL(AL_INVERSE_DISTANCE_CLAMPED),
556 DECL(AL_LINEAR_DISTANCE),
557 DECL(AL_LINEAR_DISTANCE_CLAMPED),
558 DECL(AL_EXPONENT_DISTANCE),
559 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
561 DECL(AL_FILTER_TYPE),
562 DECL(AL_FILTER_NULL),
563 DECL(AL_FILTER_LOWPASS),
564 DECL(AL_FILTER_HIGHPASS),
565 DECL(AL_FILTER_BANDPASS),
567 DECL(AL_LOWPASS_GAIN),
568 DECL(AL_LOWPASS_GAINHF),
570 DECL(AL_HIGHPASS_GAIN),
571 DECL(AL_HIGHPASS_GAINLF),
573 DECL(AL_BANDPASS_GAIN),
574 DECL(AL_BANDPASS_GAINHF),
575 DECL(AL_BANDPASS_GAINLF),
577 DECL(AL_EFFECT_TYPE),
578 DECL(AL_EFFECT_NULL),
579 DECL(AL_EFFECT_REVERB),
580 DECL(AL_EFFECT_EAXREVERB),
581 DECL(AL_EFFECT_CHORUS),
582 DECL(AL_EFFECT_DISTORTION),
583 DECL(AL_EFFECT_ECHO),
584 DECL(AL_EFFECT_FLANGER),
585 #if 0
586 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
587 DECL(AL_EFFECT_VOCAL_MORPHER),
588 DECL(AL_EFFECT_PITCH_SHIFTER),
589 #endif
590 DECL(AL_EFFECT_RING_MODULATOR),
591 DECL(AL_EFFECT_AUTOWAH),
592 DECL(AL_EFFECT_COMPRESSOR),
593 DECL(AL_EFFECT_EQUALIZER),
594 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
595 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
597 DECL(AL_EAXREVERB_DENSITY),
598 DECL(AL_EAXREVERB_DIFFUSION),
599 DECL(AL_EAXREVERB_GAIN),
600 DECL(AL_EAXREVERB_GAINHF),
601 DECL(AL_EAXREVERB_GAINLF),
602 DECL(AL_EAXREVERB_DECAY_TIME),
603 DECL(AL_EAXREVERB_DECAY_HFRATIO),
604 DECL(AL_EAXREVERB_DECAY_LFRATIO),
605 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
606 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
607 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
608 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
609 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
610 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
611 DECL(AL_EAXREVERB_ECHO_TIME),
612 DECL(AL_EAXREVERB_ECHO_DEPTH),
613 DECL(AL_EAXREVERB_MODULATION_TIME),
614 DECL(AL_EAXREVERB_MODULATION_DEPTH),
615 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
616 DECL(AL_EAXREVERB_HFREFERENCE),
617 DECL(AL_EAXREVERB_LFREFERENCE),
618 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
619 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
621 DECL(AL_REVERB_DENSITY),
622 DECL(AL_REVERB_DIFFUSION),
623 DECL(AL_REVERB_GAIN),
624 DECL(AL_REVERB_GAINHF),
625 DECL(AL_REVERB_DECAY_TIME),
626 DECL(AL_REVERB_DECAY_HFRATIO),
627 DECL(AL_REVERB_REFLECTIONS_GAIN),
628 DECL(AL_REVERB_REFLECTIONS_DELAY),
629 DECL(AL_REVERB_LATE_REVERB_GAIN),
630 DECL(AL_REVERB_LATE_REVERB_DELAY),
631 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
632 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
633 DECL(AL_REVERB_DECAY_HFLIMIT),
635 DECL(AL_CHORUS_WAVEFORM),
636 DECL(AL_CHORUS_PHASE),
637 DECL(AL_CHORUS_RATE),
638 DECL(AL_CHORUS_DEPTH),
639 DECL(AL_CHORUS_FEEDBACK),
640 DECL(AL_CHORUS_DELAY),
642 DECL(AL_DISTORTION_EDGE),
643 DECL(AL_DISTORTION_GAIN),
644 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
645 DECL(AL_DISTORTION_EQCENTER),
646 DECL(AL_DISTORTION_EQBANDWIDTH),
648 DECL(AL_ECHO_DELAY),
649 DECL(AL_ECHO_LRDELAY),
650 DECL(AL_ECHO_DAMPING),
651 DECL(AL_ECHO_FEEDBACK),
652 DECL(AL_ECHO_SPREAD),
654 DECL(AL_FLANGER_WAVEFORM),
655 DECL(AL_FLANGER_PHASE),
656 DECL(AL_FLANGER_RATE),
657 DECL(AL_FLANGER_DEPTH),
658 DECL(AL_FLANGER_FEEDBACK),
659 DECL(AL_FLANGER_DELAY),
661 DECL(AL_RING_MODULATOR_FREQUENCY),
662 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
663 DECL(AL_RING_MODULATOR_WAVEFORM),
665 DECL(AL_AUTOWAH_ATTACK_TIME),
666 DECL(AL_AUTOWAH_PEAK_GAIN),
667 DECL(AL_AUTOWAH_RELEASE_TIME),
668 DECL(AL_AUTOWAH_RESONANCE),
670 DECL(AL_COMPRESSOR_ONOFF),
672 DECL(AL_EQUALIZER_LOW_GAIN),
673 DECL(AL_EQUALIZER_LOW_CUTOFF),
674 DECL(AL_EQUALIZER_MID1_GAIN),
675 DECL(AL_EQUALIZER_MID1_CENTER),
676 DECL(AL_EQUALIZER_MID1_WIDTH),
677 DECL(AL_EQUALIZER_MID2_GAIN),
678 DECL(AL_EQUALIZER_MID2_CENTER),
679 DECL(AL_EQUALIZER_MID2_WIDTH),
680 DECL(AL_EQUALIZER_HIGH_GAIN),
681 DECL(AL_EQUALIZER_HIGH_CUTOFF),
683 DECL(AL_DEDICATED_GAIN),
685 { NULL, (ALCenum)0 }
687 #undef DECL
689 static const ALCchar alcNoError[] = "No Error";
690 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
691 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
692 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
693 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
694 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
697 /************************************************
698 * Global variables
699 ************************************************/
701 /* Enumerated device names */
702 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
704 static al_string alcAllDevicesList;
705 static al_string alcCaptureDeviceList;
707 /* Default is always the first in the list */
708 static ALCchar *alcDefaultAllDevicesSpecifier;
709 static ALCchar *alcCaptureDefaultDeviceSpecifier;
711 /* Default context extensions */
712 static const ALchar alExtList[] =
713 "AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 "
714 "AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW "
715 "AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model "
716 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_buffer_samples "
717 "AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates AL_SOFT_direct_channels "
718 "AL_SOFT_loop_points AL_SOFT_MSADPCM AL_SOFT_source_latency "
719 "AL_SOFT_source_length";
721 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
723 /* Thread-local current context */
724 static altss_t LocalContext;
725 /* Process-wide current context */
726 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
728 /* Mixing thread piority level */
729 ALint RTPrioLevel;
731 FILE *LogFile;
732 #ifdef _DEBUG
733 enum LogLevel LogLevel = LogWarning;
734 #else
735 enum LogLevel LogLevel = LogError;
736 #endif
738 /* Flag to trap ALC device errors */
739 static ALCboolean TrapALCError = ALC_FALSE;
741 /* One-time configuration init control */
742 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
744 /* Default effect that applies to sources that don't have an effect on send 0 */
745 static ALeffect DefaultEffect;
748 /************************************************
749 * ALC information
750 ************************************************/
751 static const ALCchar alcNoDeviceExtList[] =
752 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
753 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
754 static const ALCchar alcExtensionList[] =
755 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
756 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
757 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
758 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFTX_pause_device";
759 static const ALCint alcMajorVersion = 1;
760 static const ALCint alcMinorVersion = 1;
762 static const ALCint alcEFXMajorVersion = 1;
763 static const ALCint alcEFXMinorVersion = 0;
766 /************************************************
767 * Device lists
768 ************************************************/
769 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
771 static almtx_t ListLock;
772 static inline void LockLists(void)
774 int lockret = almtx_lock(&ListLock);
775 assert(lockret == althrd_success);
777 static inline void UnlockLists(void)
779 int unlockret = almtx_unlock(&ListLock);
780 assert(unlockret == althrd_success);
783 /************************************************
784 * Library initialization
785 ************************************************/
786 #if defined(_WIN32)
787 static void alc_init(void);
788 static void alc_deinit(void);
789 static void alc_deinit_safe(void);
791 #ifndef AL_LIBTYPE_STATIC
792 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
794 switch(reason)
796 case DLL_PROCESS_ATTACH:
797 /* Pin the DLL so we won't get unloaded until the process terminates */
798 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
799 (WCHAR*)hModule, &hModule);
800 alc_init();
801 break;
803 case DLL_THREAD_DETACH:
804 break;
806 case DLL_PROCESS_DETACH:
807 if(!lpReserved)
808 alc_deinit();
809 else
810 alc_deinit_safe();
811 break;
813 return TRUE;
815 #elif defined(_MSC_VER)
816 #pragma section(".CRT$XCU",read)
817 static void alc_constructor(void);
818 static void alc_destructor(void);
819 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
821 static void alc_constructor(void)
823 atexit(alc_destructor);
824 alc_init();
827 static void alc_destructor(void)
829 alc_deinit();
831 #elif defined(HAVE_GCC_DESTRUCTOR)
832 static void alc_init(void) __attribute__((constructor));
833 static void alc_deinit(void) __attribute__((destructor));
834 #else
835 #error "No static initialization available on this platform!"
836 #endif
838 #elif defined(HAVE_GCC_DESTRUCTOR)
840 static void alc_init(void) __attribute__((constructor));
841 static void alc_deinit(void) __attribute__((destructor));
843 #else
844 #error "No global initialization available on this platform!"
845 #endif
847 static void ReleaseThreadCtx(void *ptr);
848 static void alc_init(void)
850 const char *str;
851 int ret;
853 LogFile = stderr;
855 AL_STRING_INIT(alcAllDevicesList);
856 AL_STRING_INIT(alcCaptureDeviceList);
858 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
859 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
860 ConeScale *= 0.5f;
862 str = getenv("__ALSOFT_REVERSE_Z");
863 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
864 ZScale *= -1.0f;
866 ret = altss_create(&LocalContext, ReleaseThreadCtx);
867 assert(ret == althrd_success);
869 ret = almtx_init(&ListLock, almtx_recursive);
870 assert(ret == althrd_success);
872 ThunkInit();
875 static void alc_initconfig(void)
877 const char *devs, *str;
878 ALuint capfilter;
879 float valf;
880 int i, n;
882 str = getenv("ALSOFT_LOGLEVEL");
883 if(str)
885 long lvl = strtol(str, NULL, 0);
886 if(lvl >= NoLog && lvl <= LogRef)
887 LogLevel = lvl;
890 str = getenv("ALSOFT_LOGFILE");
891 if(str && str[0])
893 FILE *logfile = al_fopen(str, "wt");
894 if(logfile) LogFile = logfile;
895 else ERR("Failed to open log file '%s'\n", str);
899 char buf[1024] = "";
900 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
901 for(i = 1;BackendList[i].name;i++)
902 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
903 TRACE("Supported backends: %s\n", buf);
905 ReadALConfig();
907 capfilter = 0;
908 #if defined(HAVE_SSE4_1)
909 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE4_1;
910 #elif defined(HAVE_SSE2)
911 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
912 #elif defined(HAVE_SSE)
913 capfilter |= CPU_CAP_SSE;
914 #endif
915 #ifdef HAVE_NEON
916 capfilter |= CPU_CAP_NEON;
917 #endif
918 if(ConfigValueStr(NULL, "disable-cpu-exts", &str))
920 if(strcasecmp(str, "all") == 0)
921 capfilter = 0;
922 else
924 size_t len;
925 const char *next = str;
927 do {
928 str = next;
929 while(isspace(str[0]))
930 str++;
931 next = strchr(str, ',');
933 if(!str[0] || str[0] == ',')
934 continue;
936 len = (next ? ((size_t)(next-str)) : strlen(str));
937 while(len > 0 && isspace(str[len-1]))
938 len--;
939 if(len == 3 && strncasecmp(str, "sse", len) == 0)
940 capfilter &= ~CPU_CAP_SSE;
941 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
942 capfilter &= ~CPU_CAP_SSE2;
943 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
944 capfilter &= ~CPU_CAP_SSE4_1;
945 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
946 capfilter &= ~CPU_CAP_NEON;
947 else
948 WARN("Invalid CPU extension \"%s\"\n", str);
949 } while(next++);
952 FillCPUCaps(capfilter);
954 #ifdef _WIN32
955 RTPrioLevel = 1;
956 #else
957 RTPrioLevel = 0;
958 #endif
959 ConfigValueInt(NULL, "rt-prio", &RTPrioLevel);
961 if(ConfigValueStr(NULL, "resampler", &str))
963 if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
964 DefaultResampler = PointResampler;
965 else if(strcasecmp(str, "linear") == 0)
966 DefaultResampler = LinearResampler;
967 else if(strcasecmp(str, "cubic") == 0)
968 DefaultResampler = CubicResampler;
969 else
971 char *end;
973 n = strtol(str, &end, 0);
974 if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == CubicResampler))
975 DefaultResampler = n;
976 else
977 WARN("Invalid resampler: %s\n", str);
981 str = getenv("ALSOFT_TRAP_ERROR");
982 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
984 TrapALError = AL_TRUE;
985 TrapALCError = AL_TRUE;
987 else
989 str = getenv("ALSOFT_TRAP_AL_ERROR");
990 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
991 TrapALError = AL_TRUE;
992 TrapALError = GetConfigValueBool(NULL, "trap-al-error", TrapALError);
994 str = getenv("ALSOFT_TRAP_ALC_ERROR");
995 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
996 TrapALCError = ALC_TRUE;
997 TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", TrapALCError);
1000 if(ConfigValueFloat("reverb", "boost", &valf))
1001 ReverbBoost *= powf(10.0f, valf / 20.0f);
1003 EmulateEAXReverb = GetConfigValueBool("reverb", "emulate-eax", AL_FALSE);
1005 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1006 ConfigValueStr(NULL, "drivers", &devs))
1008 int n;
1009 size_t len;
1010 const char *next = devs;
1011 int endlist, delitem;
1013 i = 0;
1014 do {
1015 devs = next;
1016 while(isspace(devs[0]))
1017 devs++;
1018 next = strchr(devs, ',');
1020 delitem = (devs[0] == '-');
1021 if(devs[0] == '-') devs++;
1023 if(!devs[0] || devs[0] == ',')
1025 endlist = 0;
1026 continue;
1028 endlist = 1;
1030 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1031 while(len > 0 && isspace(devs[len-1]))
1032 len--;
1033 for(n = i;BackendList[n].name;n++)
1035 if(len == strlen(BackendList[n].name) &&
1036 strncmp(BackendList[n].name, devs, len) == 0)
1038 if(delitem)
1040 do {
1041 BackendList[n] = BackendList[n+1];
1042 ++n;
1043 } while(BackendList[n].name);
1045 else
1047 struct BackendInfo Bkp = BackendList[n];
1048 while(n > i)
1050 BackendList[n] = BackendList[n-1];
1051 --n;
1053 BackendList[n] = Bkp;
1055 i++;
1057 break;
1060 } while(next++);
1062 if(endlist)
1064 BackendList[i].name = NULL;
1065 BackendList[i].getFactory = NULL;
1066 BackendList[i].Init = NULL;
1067 BackendList[i].Deinit = NULL;
1068 BackendList[i].Probe = NULL;
1072 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1074 if(BackendList[i].getFactory)
1076 ALCbackendFactory *factory = BackendList[i].getFactory();
1077 if(!V0(factory,init)())
1079 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1080 continue;
1083 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1084 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1086 PlaybackBackend = BackendList[i];
1087 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1089 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1091 CaptureBackend = BackendList[i];
1092 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1095 continue;
1098 if(!BackendList[i].Init(&BackendList[i].Funcs))
1100 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1101 continue;
1104 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1105 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1107 PlaybackBackend = BackendList[i];
1108 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1110 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1112 CaptureBackend = BackendList[i];
1113 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1117 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1118 V0(factory,init)();
1121 if(ConfigValueStr(NULL, "excludefx", &str))
1123 size_t len;
1124 const char *next = str;
1126 do {
1127 str = next;
1128 next = strchr(str, ',');
1130 if(!str[0] || next == str)
1131 continue;
1133 len = (next ? ((size_t)(next-str)) : strlen(str));
1134 for(n = 0;EffectList[n].name;n++)
1136 if(len == strlen(EffectList[n].name) &&
1137 strncmp(EffectList[n].name, str, len) == 0)
1138 DisabledEffects[EffectList[n].type] = AL_TRUE;
1140 } while(next++);
1143 InitEffectFactoryMap();
1145 InitEffect(&DefaultEffect);
1146 str = getenv("ALSOFT_DEFAULT_REVERB");
1147 if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str))
1148 LoadReverbPreset(str, &DefaultEffect);
1150 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1153 /************************************************
1154 * Library deinitialization
1155 ************************************************/
1156 static void alc_cleanup(void)
1158 ALCdevice *dev;
1160 AL_STRING_DEINIT(alcAllDevicesList);
1161 AL_STRING_DEINIT(alcCaptureDeviceList);
1163 free(alcDefaultAllDevicesSpecifier);
1164 alcDefaultAllDevicesSpecifier = NULL;
1165 free(alcCaptureDefaultDeviceSpecifier);
1166 alcCaptureDefaultDeviceSpecifier = NULL;
1168 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1170 ALCuint num = 0;
1171 do {
1172 num++;
1173 } while((dev=dev->next) != NULL);
1174 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1177 DeinitEffectFactoryMap();
1180 static void alc_deinit_safe(void)
1182 alc_cleanup();
1184 FreeHrtfs();
1185 FreeALConfig();
1187 ThunkExit();
1188 almtx_destroy(&ListLock);
1189 altss_delete(LocalContext);
1191 if(LogFile != stderr)
1192 fclose(LogFile);
1193 LogFile = NULL;
1196 static void alc_deinit(void)
1198 int i;
1200 alc_cleanup();
1202 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1203 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1205 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1207 if(!BackendList[i].getFactory)
1208 BackendList[i].Deinit();
1209 else
1211 ALCbackendFactory *factory = BackendList[i].getFactory();
1212 V0(factory,deinit)();
1216 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1217 V0(factory,deinit)();
1220 alc_deinit_safe();
1224 /************************************************
1225 * Device enumeration
1226 ************************************************/
1227 static void ProbeDevices(al_string *list, enum DevProbe type)
1229 DO_INITCONFIG();
1231 LockLists();
1232 al_string_clear(list);
1234 if(type == ALL_DEVICE_PROBE && (PlaybackBackend.Probe || PlaybackBackend.getFactory))
1236 if(!PlaybackBackend.getFactory)
1237 PlaybackBackend.Probe(type);
1238 else
1240 ALCbackendFactory *factory = PlaybackBackend.getFactory();
1241 V(factory,probe)(type);
1244 else if(type == CAPTURE_DEVICE_PROBE && (CaptureBackend.Probe || CaptureBackend.getFactory))
1246 if(!CaptureBackend.getFactory)
1247 CaptureBackend.Probe(type);
1248 else
1250 ALCbackendFactory *factory = CaptureBackend.getFactory();
1251 V(factory,probe)(type);
1254 UnlockLists();
1256 static void ProbeAllDevicesList(void)
1257 { ProbeDevices(&alcAllDevicesList, ALL_DEVICE_PROBE); }
1258 static void ProbeCaptureDeviceList(void)
1259 { ProbeDevices(&alcCaptureDeviceList, CAPTURE_DEVICE_PROBE); }
1261 static void AppendDevice(const ALCchar *name, al_string *devnames)
1263 size_t len = strlen(name);
1264 if(len > 0)
1266 al_string_append_range(devnames, name, name+len);
1267 al_string_append_char(devnames, '\0');
1270 void AppendAllDevicesList(const ALCchar *name)
1271 { AppendDevice(name, &alcAllDevicesList); }
1272 void AppendCaptureDeviceList(const ALCchar *name)
1273 { AppendDevice(name, &alcCaptureDeviceList); }
1276 /************************************************
1277 * Device format information
1278 ************************************************/
1279 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1281 switch(type)
1283 case DevFmtByte: return "Signed Byte";
1284 case DevFmtUByte: return "Unsigned Byte";
1285 case DevFmtShort: return "Signed Short";
1286 case DevFmtUShort: return "Unsigned Short";
1287 case DevFmtInt: return "Signed Int";
1288 case DevFmtUInt: return "Unsigned Int";
1289 case DevFmtFloat: return "Float";
1291 return "(unknown type)";
1293 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1295 switch(chans)
1297 case DevFmtMono: return "Mono";
1298 case DevFmtStereo: return "Stereo";
1299 case DevFmtQuad: return "Quadraphonic";
1300 case DevFmtX51: return "5.1 Surround";
1301 case DevFmtX51Side: return "5.1 Side";
1302 case DevFmtX61: return "6.1 Surround";
1303 case DevFmtX71: return "7.1 Surround";
1305 return "(unknown channels)";
1308 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1309 ALuint BytesFromDevFmt(enum DevFmtType type)
1311 switch(type)
1313 case DevFmtByte: return sizeof(ALbyte);
1314 case DevFmtUByte: return sizeof(ALubyte);
1315 case DevFmtShort: return sizeof(ALshort);
1316 case DevFmtUShort: return sizeof(ALushort);
1317 case DevFmtInt: return sizeof(ALint);
1318 case DevFmtUInt: return sizeof(ALuint);
1319 case DevFmtFloat: return sizeof(ALfloat);
1321 return 0;
1323 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1325 switch(chans)
1327 case DevFmtMono: return 1;
1328 case DevFmtStereo: return 2;
1329 case DevFmtQuad: return 4;
1330 case DevFmtX51: return 6;
1331 case DevFmtX51Side: return 6;
1332 case DevFmtX61: return 7;
1333 case DevFmtX71: return 8;
1335 return 0;
1338 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1339 enum DevFmtChannels *chans, enum DevFmtType *type)
1341 static const struct {
1342 ALenum format;
1343 enum DevFmtChannels channels;
1344 enum DevFmtType type;
1345 } list[] = {
1346 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1347 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1348 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1350 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1351 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1352 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1354 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1355 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1356 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1358 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1359 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1360 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1362 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1363 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1364 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1366 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1367 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1368 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1370 ALuint i;
1372 for(i = 0;i < COUNTOF(list);i++)
1374 if(list[i].format == format)
1376 *chans = list[i].channels;
1377 *type = list[i].type;
1378 return AL_TRUE;
1382 return AL_FALSE;
1385 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1387 switch(type)
1389 case ALC_BYTE_SOFT:
1390 case ALC_UNSIGNED_BYTE_SOFT:
1391 case ALC_SHORT_SOFT:
1392 case ALC_UNSIGNED_SHORT_SOFT:
1393 case ALC_INT_SOFT:
1394 case ALC_UNSIGNED_INT_SOFT:
1395 case ALC_FLOAT_SOFT:
1396 return ALC_TRUE;
1398 return ALC_FALSE;
1401 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1403 switch(channels)
1405 case ALC_MONO_SOFT:
1406 case ALC_STEREO_SOFT:
1407 case ALC_QUAD_SOFT:
1408 case ALC_5POINT1_SOFT:
1409 case ALC_6POINT1_SOFT:
1410 case ALC_7POINT1_SOFT:
1411 return ALC_TRUE;
1413 return ALC_FALSE;
1417 /************************************************
1418 * Miscellaneous ALC helpers
1419 ************************************************/
1420 extern inline void LockContext(ALCcontext *context);
1421 extern inline void UnlockContext(ALCcontext *context);
1423 ALint64 ALCdevice_GetLatencyDefault(ALCdevice *UNUSED(device))
1425 return 0;
1428 ALint64 ALCdevice_GetLatency(ALCdevice *device)
1430 return V0(device->Backend,getLatency)();
1433 void ALCdevice_Lock(ALCdevice *device)
1435 V0(device->Backend,lock)();
1438 void ALCdevice_Unlock(ALCdevice *device)
1440 V0(device->Backend,unlock)();
1444 /* SetDefaultWFXChannelOrder
1446 * Sets the default channel order used by WaveFormatEx.
1448 void SetDefaultWFXChannelOrder(ALCdevice *device)
1450 ALuint i;
1452 for(i = 0;i < MaxChannels;i++)
1453 device->ChannelOffsets[i] = INVALID_OFFSET;
1455 switch(device->FmtChans)
1457 case DevFmtMono: device->ChannelOffsets[FrontCenter] = 0;
1458 break;
1459 case DevFmtStereo: device->ChannelOffsets[FrontLeft] = 0;
1460 device->ChannelOffsets[FrontRight] = 1;
1461 break;
1462 case DevFmtQuad: device->ChannelOffsets[FrontLeft] = 0;
1463 device->ChannelOffsets[FrontRight] = 1;
1464 device->ChannelOffsets[BackLeft] = 2;
1465 device->ChannelOffsets[BackRight] = 3;
1466 break;
1467 case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0;
1468 device->ChannelOffsets[FrontRight] = 1;
1469 device->ChannelOffsets[FrontCenter] = 2;
1470 device->ChannelOffsets[LFE] = 3;
1471 device->ChannelOffsets[BackLeft] = 4;
1472 device->ChannelOffsets[BackRight] = 5;
1473 break;
1474 case DevFmtX51Side: device->ChannelOffsets[FrontLeft] = 0;
1475 device->ChannelOffsets[FrontRight] = 1;
1476 device->ChannelOffsets[FrontCenter] = 2;
1477 device->ChannelOffsets[LFE] = 3;
1478 device->ChannelOffsets[SideLeft] = 4;
1479 device->ChannelOffsets[SideRight] = 5;
1480 break;
1481 case DevFmtX61: device->ChannelOffsets[FrontLeft] = 0;
1482 device->ChannelOffsets[FrontRight] = 1;
1483 device->ChannelOffsets[FrontCenter] = 2;
1484 device->ChannelOffsets[LFE] = 3;
1485 device->ChannelOffsets[BackCenter] = 4;
1486 device->ChannelOffsets[SideLeft] = 5;
1487 device->ChannelOffsets[SideRight] = 6;
1488 break;
1489 case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0;
1490 device->ChannelOffsets[FrontRight] = 1;
1491 device->ChannelOffsets[FrontCenter] = 2;
1492 device->ChannelOffsets[LFE] = 3;
1493 device->ChannelOffsets[BackLeft] = 4;
1494 device->ChannelOffsets[BackRight] = 5;
1495 device->ChannelOffsets[SideLeft] = 6;
1496 device->ChannelOffsets[SideRight] = 7;
1497 break;
1501 /* SetDefaultChannelOrder
1503 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1505 void SetDefaultChannelOrder(ALCdevice *device)
1507 ALuint i;
1509 for(i = 0;i < MaxChannels;i++)
1510 device->ChannelOffsets[i] = INVALID_OFFSET;
1512 switch(device->FmtChans)
1514 case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0;
1515 device->ChannelOffsets[FrontRight] = 1;
1516 device->ChannelOffsets[BackLeft] = 2;
1517 device->ChannelOffsets[BackRight] = 3;
1518 device->ChannelOffsets[FrontCenter] = 4;
1519 device->ChannelOffsets[LFE] = 5;
1520 return;
1521 case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0;
1522 device->ChannelOffsets[FrontRight] = 1;
1523 device->ChannelOffsets[BackLeft] = 2;
1524 device->ChannelOffsets[BackRight] = 3;
1525 device->ChannelOffsets[FrontCenter] = 4;
1526 device->ChannelOffsets[LFE] = 5;
1527 device->ChannelOffsets[SideLeft] = 6;
1528 device->ChannelOffsets[SideRight] = 7;
1529 return;
1531 /* Same as WFX order */
1532 case DevFmtMono:
1533 case DevFmtStereo:
1534 case DevFmtQuad:
1535 case DevFmtX51Side:
1536 case DevFmtX61:
1537 break;
1539 SetDefaultWFXChannelOrder(device);
1543 /* alcSetError
1545 * Stores the latest ALC device error
1547 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1549 if(TrapALCError)
1551 #ifdef _WIN32
1552 /* DebugBreak() will cause an exception if there is no debugger */
1553 if(IsDebuggerPresent())
1554 DebugBreak();
1555 #elif defined(SIGTRAP)
1556 raise(SIGTRAP);
1557 #endif
1560 if(device)
1561 ATOMIC_STORE(&device->LastError, errorCode);
1562 else
1563 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1567 /* UpdateClockBase
1569 * Updates the device's base clock time with however many samples have been
1570 * done. This is used so frequency changes on the device don't cause the time
1571 * to jump forward or back.
1573 static inline void UpdateClockBase(ALCdevice *device)
1575 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1576 device->SamplesDone = 0;
1579 /* UpdateDeviceParams
1581 * Updates device parameters according to the attribute list (caller is
1582 * responsible for holding the list lock).
1584 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1586 ALCcontext *context;
1587 enum DevFmtChannels oldChans;
1588 enum DevFmtType oldType;
1589 ALCuint oldFreq;
1590 FPUCtl oldMode;
1592 // Check for attributes
1593 if(device->Type == Loopback)
1595 enum {
1596 GotFreq = 1<<0,
1597 GotChans = 1<<1,
1598 GotType = 1<<2,
1599 GotAll = GotFreq|GotChans|GotType
1601 ALCuint freq, numMono, numStereo, numSends, flags;
1602 enum DevFmtChannels schans;
1603 enum DevFmtType stype;
1604 ALCuint attrIdx = 0;
1605 ALCint gotFmt = 0;
1607 if(!attrList)
1609 WARN("Missing attributes for loopback device\n");
1610 return ALC_INVALID_VALUE;
1613 numMono = device->NumMonoSources;
1614 numStereo = device->NumStereoSources;
1615 numSends = device->NumAuxSends;
1616 schans = device->FmtChans;
1617 stype = device->FmtType;
1618 freq = device->Frequency;
1619 flags = device->Flags;
1621 while(attrList[attrIdx])
1623 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1625 ALCint val = attrList[attrIdx + 1];
1626 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1627 return ALC_INVALID_VALUE;
1628 schans = val;
1629 gotFmt |= GotChans;
1632 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1634 ALCint val = attrList[attrIdx + 1];
1635 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1636 return ALC_INVALID_VALUE;
1637 stype = val;
1638 gotFmt |= GotType;
1641 if(attrList[attrIdx] == ALC_FREQUENCY)
1643 freq = attrList[attrIdx + 1];
1644 if(freq < MIN_OUTPUT_RATE)
1645 return ALC_INVALID_VALUE;
1646 gotFmt |= GotFreq;
1649 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1651 numStereo = attrList[attrIdx + 1];
1652 if(numStereo > device->MaxNoOfSources)
1653 numStereo = device->MaxNoOfSources;
1655 numMono = device->MaxNoOfSources - numStereo;
1658 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1659 numSends = attrList[attrIdx + 1];
1661 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1663 if(attrList[attrIdx + 1] != ALC_FALSE)
1664 flags |= DEVICE_HRTF_REQUEST;
1665 else
1666 flags &= ~DEVICE_HRTF_REQUEST;
1669 attrIdx += 2;
1672 if(gotFmt != GotAll)
1674 WARN("Missing format for loopback device\n");
1675 return ALC_INVALID_VALUE;
1678 ConfigValueUInt(NULL, "sends", &numSends);
1679 numSends = minu(MAX_SENDS, numSends);
1681 if((device->Flags&DEVICE_RUNNING))
1682 V0(device->Backend,stop)();
1683 device->Flags = (flags & ~DEVICE_RUNNING);
1685 if(freq != device->Frequency)
1686 UpdateClockBase(device);
1687 device->Frequency = freq;
1688 device->FmtChans = schans;
1689 device->FmtType = stype;
1690 device->NumMonoSources = numMono;
1691 device->NumStereoSources = numStereo;
1692 device->NumAuxSends = numSends;
1694 else if(attrList && attrList[0])
1696 ALCuint freq, numMono, numStereo, numSends;
1697 ALCuint attrIdx = 0;
1699 /* If a context is already running on the device, stop playback so the
1700 * device attributes can be updated. */
1701 if((device->Flags&DEVICE_RUNNING))
1702 V0(device->Backend,stop)();
1703 device->Flags &= ~DEVICE_RUNNING;
1705 freq = device->Frequency;
1706 numMono = device->NumMonoSources;
1707 numStereo = device->NumStereoSources;
1708 numSends = device->NumAuxSends;
1710 while(attrList[attrIdx])
1712 if(attrList[attrIdx] == ALC_FREQUENCY)
1714 freq = attrList[attrIdx + 1];
1715 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1718 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1720 numStereo = attrList[attrIdx + 1];
1721 if(numStereo > device->MaxNoOfSources)
1722 numStereo = device->MaxNoOfSources;
1724 numMono = device->MaxNoOfSources - numStereo;
1727 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1728 numSends = attrList[attrIdx + 1];
1730 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1732 if(attrList[attrIdx + 1] != ALC_FALSE)
1733 device->Flags |= DEVICE_HRTF_REQUEST;
1734 else
1735 device->Flags &= ~DEVICE_HRTF_REQUEST;
1738 attrIdx += 2;
1741 ConfigValueUInt(NULL, "frequency", &freq);
1742 freq = maxu(freq, MIN_OUTPUT_RATE);
1744 ConfigValueUInt(NULL, "sends", &numSends);
1745 numSends = minu(MAX_SENDS, numSends);
1747 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1748 device->Frequency;
1749 /* SSE and Neon do best with the update size being a multiple of 4 */
1750 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1751 device->UpdateSize = (device->UpdateSize+3)&~3;
1753 if(freq != device->Frequency)
1754 UpdateClockBase(device);
1755 device->Frequency = freq;
1756 device->NumMonoSources = numMono;
1757 device->NumStereoSources = numStereo;
1758 device->NumAuxSends = numSends;
1761 if((device->Flags&DEVICE_RUNNING))
1762 return ALC_NO_ERROR;
1764 UpdateClockBase(device);
1766 oldFreq = device->Frequency;
1767 oldChans = device->FmtChans;
1768 oldType = device->FmtType;
1770 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1771 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"",
1772 DevFmtChannelsString(device->FmtChans),
1773 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"",
1774 DevFmtTypeString(device->FmtType),
1775 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"",
1776 device->Frequency,
1777 device->UpdateSize, device->NumUpdates);
1779 if(device->Type != Loopback)
1781 bool usehrtf = !!(device->Flags&DEVICE_HRTF_REQUEST);
1782 if(GetConfigValueBool(NULL, "hrtf", usehrtf))
1783 device->Flags |= DEVICE_HRTF_REQUEST;
1784 else
1785 device->Flags &= ~DEVICE_HRTF_REQUEST;
1787 if((device->Flags&DEVICE_HRTF_REQUEST))
1789 enum DevFmtChannels chans = device->FmtChans;
1790 ALCuint freq = device->Frequency;
1791 if(FindHrtfFormat(&chans, &freq))
1793 if(device->Type != Loopback)
1795 device->Frequency = freq;
1796 device->FmtChans = chans;
1797 device->Flags |= DEVICE_CHANNELS_REQUEST |
1798 DEVICE_FREQUENCY_REQUEST;
1800 else if(device->Frequency != freq || device->FmtChans != chans)
1802 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1803 DevFmtChannelsString(device->FmtChans), device->Frequency);
1804 device->Flags &= ~DEVICE_HRTF_REQUEST;
1809 if(V0(device->Backend,reset)() == ALC_FALSE)
1810 return ALC_INVALID_DEVICE;
1812 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1814 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1815 DevFmtChannelsString(device->FmtChans));
1816 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1818 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1820 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1821 DevFmtTypeString(device->FmtType));
1822 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1824 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1826 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1827 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1830 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1831 DevFmtChannelsString(device->FmtChans),
1832 DevFmtTypeString(device->FmtType), device->Frequency,
1833 device->UpdateSize, device->NumUpdates);
1835 aluInitPanning(device);
1837 V(device->Synth,update)(device);
1839 device->Hrtf = NULL;
1840 if((device->Flags&DEVICE_HRTF_REQUEST))
1842 device->Hrtf = GetHrtf(device->FmtChans, device->Frequency);
1843 if(!device->Hrtf)
1844 device->Flags &= ~DEVICE_HRTF_REQUEST;
1846 TRACE("HRTF %s\n", device->Hrtf?"enabled":"disabled");
1848 if(!device->Hrtf && device->Bs2bLevel > 0 && device->Bs2bLevel <= 6)
1850 if(!device->Bs2b)
1852 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
1853 bs2b_clear(device->Bs2b);
1855 bs2b_set_srate(device->Bs2b, device->Frequency);
1856 bs2b_set_level(device->Bs2b, device->Bs2bLevel);
1857 TRACE("BS2B level %d\n", device->Bs2bLevel);
1859 else
1861 free(device->Bs2b);
1862 device->Bs2b = NULL;
1863 TRACE("BS2B disabled\n");
1866 device->Flags &= ~DEVICE_WIDE_STEREO;
1867 if(device->Type != Loopback && !device->Hrtf && GetConfigValueBool(NULL, "wide-stereo", AL_FALSE))
1868 device->Flags |= DEVICE_WIDE_STEREO;
1870 if(!device->Hrtf && (device->UpdateSize&3))
1872 if((CPUCapFlags&CPU_CAP_SSE))
1873 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1874 if((CPUCapFlags&CPU_CAP_NEON))
1875 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1878 SetMixerFPUMode(&oldMode);
1879 ALCdevice_Lock(device);
1880 context = ATOMIC_LOAD(&device->ContextList);
1881 while(context)
1883 ALsizei pos;
1885 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
1886 LockUIntMapRead(&context->EffectSlotMap);
1887 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
1889 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
1891 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
1893 UnlockUIntMapRead(&context->EffectSlotMap);
1894 ALCdevice_Unlock(device);
1895 RestoreFPUMode(&oldMode);
1896 return ALC_INVALID_DEVICE;
1898 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
1899 V(slot->EffectState,update)(device, slot);
1901 UnlockUIntMapRead(&context->EffectSlotMap);
1903 LockUIntMapRead(&context->SourceMap);
1904 for(pos = 0;pos < context->SourceMap.size;pos++)
1906 ALsource *source = context->SourceMap.array[pos].value;
1907 ALuint s = device->NumAuxSends;
1908 while(s < MAX_SENDS)
1910 if(source->Send[s].Slot)
1911 DecrementRef(&source->Send[s].Slot->ref);
1912 source->Send[s].Slot = NULL;
1913 source->Send[s].Gain = 1.0f;
1914 source->Send[s].GainHF = 1.0f;
1915 s++;
1917 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
1919 UnlockUIntMapRead(&context->SourceMap);
1921 for(pos = 0;pos < context->ActiveSourceCount;pos++)
1923 ALactivesource *src = context->ActiveSources[pos];
1924 ALsource *source = src->Source;
1925 ALuint s = device->NumAuxSends;
1926 while(s < MAX_SENDS)
1928 src->Send[s].Moving = AL_FALSE;
1929 src->Send[s].Counter = 0;
1930 s++;
1933 src->Update(src, context);
1934 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
1937 context = context->next;
1939 if(device->DefaultSlot)
1941 ALeffectslot *slot = device->DefaultSlot;
1943 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
1945 ALCdevice_Unlock(device);
1946 RestoreFPUMode(&oldMode);
1947 return ALC_INVALID_DEVICE;
1949 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
1950 V(slot->EffectState,update)(device, slot);
1952 ALCdevice_Unlock(device);
1953 RestoreFPUMode(&oldMode);
1955 if(!(device->Flags&DEVICE_PAUSED))
1957 if(V0(device->Backend,start)() == ALC_FALSE)
1958 return ALC_INVALID_DEVICE;
1959 device->Flags |= DEVICE_RUNNING;
1962 return ALC_NO_ERROR;
1965 /* FreeDevice
1967 * Frees the device structure, and destroys any objects the app failed to
1968 * delete. Called once there's no more references on the device.
1970 static ALCvoid FreeDevice(ALCdevice *device)
1972 TRACE("%p\n", device);
1974 V0(device->Backend,close)();
1975 DELETE_OBJ(device->Backend);
1976 device->Backend = NULL;
1978 DELETE_OBJ(device->Synth);
1979 device->Synth = NULL;
1981 if(device->DefaultSlot)
1983 ALeffectState *state = device->DefaultSlot->EffectState;
1984 device->DefaultSlot = NULL;
1985 DELETE_OBJ(state);
1988 if(device->DefaultSfont)
1989 ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
1990 device->DefaultSfont = NULL;
1992 if(device->BufferMap.size > 0)
1994 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
1995 ReleaseALBuffers(device);
1997 ResetUIntMap(&device->BufferMap);
1999 if(device->EffectMap.size > 0)
2001 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2002 ReleaseALEffects(device);
2004 ResetUIntMap(&device->EffectMap);
2006 if(device->FilterMap.size > 0)
2008 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2009 ReleaseALFilters(device);
2011 ResetUIntMap(&device->FilterMap);
2013 if(device->SfontMap.size > 0)
2015 WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size);
2016 ReleaseALSoundfonts(device);
2018 ResetUIntMap(&device->SfontMap);
2020 if(device->PresetMap.size > 0)
2022 WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size);
2023 ReleaseALPresets(device);
2025 ResetUIntMap(&device->PresetMap);
2027 if(device->FontsoundMap.size > 0)
2029 WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size);
2030 ReleaseALFontsounds(device);
2032 ResetUIntMap(&device->FontsoundMap);
2034 free(device->Bs2b);
2035 device->Bs2b = NULL;
2037 AL_STRING_DEINIT(device->DeviceName);
2039 al_free(device);
2043 void ALCdevice_IncRef(ALCdevice *device)
2045 uint ref;
2046 ref = IncrementRef(&device->ref);
2047 TRACEREF("%p increasing refcount to %u\n", device, ref);
2050 void ALCdevice_DecRef(ALCdevice *device)
2052 uint ref;
2053 ref = DecrementRef(&device->ref);
2054 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2055 if(ref == 0) FreeDevice(device);
2058 /* VerifyDevice
2060 * Checks if the device handle is valid, and increments its ref count if so.
2062 static ALCdevice *VerifyDevice(ALCdevice *device)
2064 ALCdevice *tmpDevice;
2066 if(!device)
2067 return NULL;
2069 LockLists();
2070 tmpDevice = ATOMIC_LOAD(&DeviceList);
2071 while(tmpDevice && tmpDevice != device)
2072 tmpDevice = tmpDevice->next;
2074 if(tmpDevice)
2075 ALCdevice_IncRef(tmpDevice);
2076 UnlockLists();
2077 return tmpDevice;
2081 /* InitContext
2083 * Initializes context fields
2085 static ALvoid InitContext(ALCcontext *Context)
2087 ALint i, j;
2089 //Initialise listener
2090 Context->Listener->Gain = 1.0f;
2091 Context->Listener->MetersPerUnit = 1.0f;
2092 Context->Listener->Position[0] = 0.0f;
2093 Context->Listener->Position[1] = 0.0f;
2094 Context->Listener->Position[2] = 0.0f;
2095 Context->Listener->Velocity[0] = 0.0f;
2096 Context->Listener->Velocity[1] = 0.0f;
2097 Context->Listener->Velocity[2] = 0.0f;
2098 Context->Listener->Forward[0] = 0.0f;
2099 Context->Listener->Forward[1] = 0.0f;
2100 Context->Listener->Forward[2] = -1.0f;
2101 Context->Listener->Up[0] = 0.0f;
2102 Context->Listener->Up[1] = 1.0f;
2103 Context->Listener->Up[2] = 0.0f;
2104 for(i = 0;i < 4;i++)
2106 for(j = 0;j < 4;j++)
2107 Context->Listener->Params.Matrix[i][j] = ((i==j) ? 1.0f : 0.0f);
2109 for(i = 0;i < 3;i++)
2110 Context->Listener->Params.Velocity[i] = 0.0f;
2112 //Validate Context
2113 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2114 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2115 Context->ActiveSourceCount = 0;
2116 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2117 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2119 //Set globals
2120 Context->DistanceModel = DefaultDistanceModel;
2121 Context->SourceDistanceModel = AL_FALSE;
2122 Context->DopplerFactor = 1.0f;
2123 Context->DopplerVelocity = 1.0f;
2124 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2125 Context->DeferUpdates = AL_FALSE;
2127 Context->ExtensionList = alExtList;
2131 /* FreeContext
2133 * Cleans up the context, and destroys any remaining objects the app failed to
2134 * delete. Called once there's no more references on the context.
2136 static ALCvoid FreeContext(ALCcontext *context)
2138 ALsizei i;
2140 TRACE("%p\n", context);
2142 if(context->SourceMap.size > 0)
2144 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2145 ReleaseALSources(context);
2147 ResetUIntMap(&context->SourceMap);
2149 if(context->EffectSlotMap.size > 0)
2151 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2152 ReleaseALAuxiliaryEffectSlots(context);
2154 ResetUIntMap(&context->EffectSlotMap);
2156 for(i = 0;i < context->MaxActiveSources;i++)
2158 al_free(context->ActiveSources[i]);
2159 context->ActiveSources[i] = NULL;
2161 free(context->ActiveSources);
2162 context->ActiveSources = NULL;
2163 context->ActiveSourceCount = 0;
2164 context->MaxActiveSources = 0;
2166 VECTOR_DEINIT(context->ActiveAuxSlots);
2168 ALCdevice_DecRef(context->Device);
2169 context->Device = NULL;
2171 //Invalidate context
2172 memset(context, 0, sizeof(ALCcontext));
2173 free(context);
2176 /* ReleaseContext
2178 * Removes the context reference from the given device and removes it from
2179 * being current on the running thread or globally.
2181 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2183 ALCcontext *nextctx;
2184 ALCcontext *origctx;
2186 if(altss_get(LocalContext) == context)
2188 WARN("%p released while current on thread\n", context);
2189 altss_set(LocalContext, NULL);
2190 ALCcontext_DecRef(context);
2193 origctx = context;
2194 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2195 ALCcontext_DecRef(context);
2197 ALCdevice_Lock(device);
2198 origctx = context;
2199 nextctx = context->next;
2200 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2202 ALCcontext *list;
2203 do {
2204 list = origctx;
2205 origctx = context;
2206 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2208 ALCdevice_Unlock(device);
2210 ALCcontext_DecRef(context);
2213 void ALCcontext_IncRef(ALCcontext *context)
2215 uint ref;
2216 ref = IncrementRef(&context->ref);
2217 TRACEREF("%p increasing refcount to %u\n", context, ref);
2220 void ALCcontext_DecRef(ALCcontext *context)
2222 uint ref;
2223 ref = DecrementRef(&context->ref);
2224 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2225 if(ref == 0) FreeContext(context);
2228 static void ReleaseThreadCtx(void *ptr)
2230 WARN("%p current for thread being destroyed\n", ptr);
2231 ALCcontext_DecRef(ptr);
2234 /* VerifyContext
2236 * Checks that the given context is valid, and increments its reference count.
2238 static ALCcontext *VerifyContext(ALCcontext *context)
2240 ALCdevice *dev;
2242 LockLists();
2243 dev = ATOMIC_LOAD(&DeviceList);
2244 while(dev)
2246 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2247 while(ctx)
2249 if(ctx == context)
2251 ALCcontext_IncRef(ctx);
2252 UnlockLists();
2253 return ctx;
2255 ctx = ctx->next;
2257 dev = dev->next;
2259 UnlockLists();
2261 return NULL;
2265 /* GetContextRef
2267 * Returns the currently active context for this thread, and adds a reference
2268 * without locking it.
2270 ALCcontext *GetContextRef(void)
2272 ALCcontext *context;
2274 context = altss_get(LocalContext);
2275 if(context)
2276 ALCcontext_IncRef(context);
2277 else
2279 LockLists();
2280 context = ATOMIC_LOAD(&GlobalContext);
2281 if(context)
2282 ALCcontext_IncRef(context);
2283 UnlockLists();
2286 return context;
2290 /************************************************
2291 * Standard ALC functions
2292 ************************************************/
2294 /* alcGetError
2296 * Return last ALC generated error code for the given device
2298 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2300 ALCenum errorCode;
2302 if(VerifyDevice(device))
2304 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2305 ALCdevice_DecRef(device);
2307 else
2308 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2310 return errorCode;
2314 /* alcSuspendContext
2316 * Not functional
2318 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *UNUSED(context))
2322 /* alcProcessContext
2324 * Not functional
2326 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *UNUSED(context))
2331 /* alcGetString
2333 * Returns information about the device, and error strings
2335 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2337 const ALCchar *value = NULL;
2339 switch(param)
2341 case ALC_NO_ERROR:
2342 value = alcNoError;
2343 break;
2345 case ALC_INVALID_ENUM:
2346 value = alcErrInvalidEnum;
2347 break;
2349 case ALC_INVALID_VALUE:
2350 value = alcErrInvalidValue;
2351 break;
2353 case ALC_INVALID_DEVICE:
2354 value = alcErrInvalidDevice;
2355 break;
2357 case ALC_INVALID_CONTEXT:
2358 value = alcErrInvalidContext;
2359 break;
2361 case ALC_OUT_OF_MEMORY:
2362 value = alcErrOutOfMemory;
2363 break;
2365 case ALC_DEVICE_SPECIFIER:
2366 value = alcDefaultName;
2367 break;
2369 case ALC_ALL_DEVICES_SPECIFIER:
2370 if(VerifyDevice(Device))
2372 value = al_string_get_cstr(Device->DeviceName);
2373 ALCdevice_DecRef(Device);
2375 else
2377 ProbeAllDevicesList();
2378 value = al_string_get_cstr(alcAllDevicesList);
2380 break;
2382 case ALC_CAPTURE_DEVICE_SPECIFIER:
2383 if(VerifyDevice(Device))
2385 value = al_string_get_cstr(Device->DeviceName);
2386 ALCdevice_DecRef(Device);
2388 else
2390 ProbeCaptureDeviceList();
2391 value = al_string_get_cstr(alcCaptureDeviceList);
2393 break;
2395 /* Default devices are always first in the list */
2396 case ALC_DEFAULT_DEVICE_SPECIFIER:
2397 value = alcDefaultName;
2398 break;
2400 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2401 if(al_string_empty(alcAllDevicesList))
2402 ProbeAllDevicesList();
2404 Device = VerifyDevice(Device);
2406 free(alcDefaultAllDevicesSpecifier);
2407 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2408 if(!alcDefaultAllDevicesSpecifier)
2409 alcSetError(Device, ALC_OUT_OF_MEMORY);
2411 value = alcDefaultAllDevicesSpecifier;
2412 if(Device) ALCdevice_DecRef(Device);
2413 break;
2415 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2416 if(al_string_empty(alcCaptureDeviceList))
2417 ProbeCaptureDeviceList();
2419 Device = VerifyDevice(Device);
2421 free(alcCaptureDefaultDeviceSpecifier);
2422 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2423 if(!alcCaptureDefaultDeviceSpecifier)
2424 alcSetError(Device, ALC_OUT_OF_MEMORY);
2426 value = alcCaptureDefaultDeviceSpecifier;
2427 if(Device) ALCdevice_DecRef(Device);
2428 break;
2430 case ALC_EXTENSIONS:
2431 if(!VerifyDevice(Device))
2432 value = alcNoDeviceExtList;
2433 else
2435 value = alcExtensionList;
2436 ALCdevice_DecRef(Device);
2438 break;
2440 default:
2441 Device = VerifyDevice(Device);
2442 alcSetError(Device, ALC_INVALID_ENUM);
2443 if(Device) ALCdevice_DecRef(Device);
2444 break;
2447 return value;
2451 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2453 ALCsizei i;
2455 if(size <= 0 || values == NULL)
2457 alcSetError(device, ALC_INVALID_VALUE);
2458 return 0;
2461 if(!device)
2463 switch(param)
2465 case ALC_MAJOR_VERSION:
2466 values[0] = alcMajorVersion;
2467 return 1;
2468 case ALC_MINOR_VERSION:
2469 values[0] = alcMinorVersion;
2470 return 1;
2472 case ALC_ATTRIBUTES_SIZE:
2473 case ALC_ALL_ATTRIBUTES:
2474 case ALC_FREQUENCY:
2475 case ALC_REFRESH:
2476 case ALC_SYNC:
2477 case ALC_MONO_SOURCES:
2478 case ALC_STEREO_SOURCES:
2479 case ALC_CAPTURE_SAMPLES:
2480 case ALC_FORMAT_CHANNELS_SOFT:
2481 case ALC_FORMAT_TYPE_SOFT:
2482 alcSetError(NULL, ALC_INVALID_DEVICE);
2483 return 0;
2485 default:
2486 alcSetError(NULL, ALC_INVALID_ENUM);
2487 return 0;
2489 return 0;
2492 if(device->Type == Capture)
2494 switch(param)
2496 case ALC_CAPTURE_SAMPLES:
2497 ALCdevice_Lock(device);
2498 values[0] = V0(device->Backend,availableSamples)();
2499 ALCdevice_Unlock(device);
2500 return 1;
2502 case ALC_CONNECTED:
2503 values[0] = device->Connected;
2504 return 1;
2506 default:
2507 alcSetError(device, ALC_INVALID_ENUM);
2508 return 0;
2510 return 0;
2513 /* render device */
2514 switch(param)
2516 case ALC_MAJOR_VERSION:
2517 values[0] = alcMajorVersion;
2518 return 1;
2520 case ALC_MINOR_VERSION:
2521 values[0] = alcMinorVersion;
2522 return 1;
2524 case ALC_EFX_MAJOR_VERSION:
2525 values[0] = alcEFXMajorVersion;
2526 return 1;
2528 case ALC_EFX_MINOR_VERSION:
2529 values[0] = alcEFXMinorVersion;
2530 return 1;
2532 case ALC_ATTRIBUTES_SIZE:
2533 values[0] = 15;
2534 return 1;
2536 case ALC_ALL_ATTRIBUTES:
2537 if(size < 15)
2539 alcSetError(device, ALC_INVALID_VALUE);
2540 return 0;
2543 i = 0;
2544 values[i++] = ALC_FREQUENCY;
2545 values[i++] = device->Frequency;
2547 if(device->Type != Loopback)
2549 values[i++] = ALC_REFRESH;
2550 values[i++] = device->Frequency / device->UpdateSize;
2552 values[i++] = ALC_SYNC;
2553 values[i++] = ALC_FALSE;
2555 else
2557 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2558 values[i++] = device->FmtChans;
2560 values[i++] = ALC_FORMAT_TYPE_SOFT;
2561 values[i++] = device->FmtType;
2564 values[i++] = ALC_MONO_SOURCES;
2565 values[i++] = device->NumMonoSources;
2567 values[i++] = ALC_STEREO_SOURCES;
2568 values[i++] = device->NumStereoSources;
2570 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2571 values[i++] = device->NumAuxSends;
2573 values[i++] = ALC_HRTF_SOFT;
2574 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2576 values[i++] = 0;
2577 return i;
2579 case ALC_FREQUENCY:
2580 values[0] = device->Frequency;
2581 return 1;
2583 case ALC_REFRESH:
2584 if(device->Type == Loopback)
2586 alcSetError(device, ALC_INVALID_DEVICE);
2587 return 0;
2589 values[0] = device->Frequency / device->UpdateSize;
2590 return 1;
2592 case ALC_SYNC:
2593 if(device->Type == Loopback)
2595 alcSetError(device, ALC_INVALID_DEVICE);
2596 return 0;
2598 values[0] = ALC_FALSE;
2599 return 1;
2601 case ALC_FORMAT_CHANNELS_SOFT:
2602 if(device->Type != Loopback)
2604 alcSetError(device, ALC_INVALID_DEVICE);
2605 return 0;
2607 values[0] = device->FmtChans;
2608 return 1;
2610 case ALC_FORMAT_TYPE_SOFT:
2611 if(device->Type != Loopback)
2613 alcSetError(device, ALC_INVALID_DEVICE);
2614 return 0;
2616 values[0] = device->FmtType;
2617 return 1;
2619 case ALC_MONO_SOURCES:
2620 values[0] = device->NumMonoSources;
2621 return 1;
2623 case ALC_STEREO_SOURCES:
2624 values[0] = device->NumStereoSources;
2625 return 1;
2627 case ALC_MAX_AUXILIARY_SENDS:
2628 values[0] = device->NumAuxSends;
2629 return 1;
2631 case ALC_CONNECTED:
2632 values[0] = device->Connected;
2633 return 1;
2635 case ALC_HRTF_SOFT:
2636 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2637 return 1;
2639 default:
2640 alcSetError(device, ALC_INVALID_ENUM);
2641 return 0;
2643 return 0;
2646 /* alcGetIntegerv
2648 * Returns information about the device and the version of OpenAL
2650 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2652 device = VerifyDevice(device);
2653 if(size <= 0 || values == NULL)
2654 alcSetError(device, ALC_INVALID_VALUE);
2655 else
2656 GetIntegerv(device, param, size, values);
2657 if(device) ALCdevice_DecRef(device);
2660 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2662 ALCint *ivals;
2663 ALsizei i;
2665 device = VerifyDevice(device);
2666 if(size <= 0 || values == NULL)
2667 alcSetError(device, ALC_INVALID_VALUE);
2668 else if(!device || device->Type == Capture)
2670 ivals = malloc(size * sizeof(ALCint));
2671 size = GetIntegerv(device, pname, size, ivals);
2672 for(i = 0;i < size;i++)
2673 values[i] = ivals[i];
2674 free(ivals);
2676 else /* render device */
2678 switch(pname)
2680 case ALC_ATTRIBUTES_SIZE:
2681 *values = 17;
2682 break;
2684 case ALC_ALL_ATTRIBUTES:
2685 if(size < 17)
2686 alcSetError(device, ALC_INVALID_VALUE);
2687 else
2689 int i = 0;
2691 V0(device->Backend,lock)();
2692 values[i++] = ALC_FREQUENCY;
2693 values[i++] = device->Frequency;
2695 if(device->Type != Loopback)
2697 values[i++] = ALC_REFRESH;
2698 values[i++] = device->Frequency / device->UpdateSize;
2700 values[i++] = ALC_SYNC;
2701 values[i++] = ALC_FALSE;
2703 else
2705 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2706 values[i++] = device->FmtChans;
2708 values[i++] = ALC_FORMAT_TYPE_SOFT;
2709 values[i++] = device->FmtType;
2712 values[i++] = ALC_MONO_SOURCES;
2713 values[i++] = device->NumMonoSources;
2715 values[i++] = ALC_STEREO_SOURCES;
2716 values[i++] = device->NumStereoSources;
2718 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2719 values[i++] = device->NumAuxSends;
2721 values[i++] = ALC_HRTF_SOFT;
2722 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2724 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2725 values[i++] = device->ClockBase +
2726 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2728 values[i++] = 0;
2729 V0(device->Backend,unlock)();
2731 break;
2733 case ALC_DEVICE_CLOCK_SOFT:
2734 V0(device->Backend,lock)();
2735 *values = device->ClockBase +
2736 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2737 V0(device->Backend,unlock)();
2738 break;
2740 default:
2741 ivals = malloc(size * sizeof(ALCint));
2742 size = GetIntegerv(device, pname, size, ivals);
2743 for(i = 0;i < size;i++)
2744 values[i] = ivals[i];
2745 free(ivals);
2746 break;
2749 if(device)
2750 ALCdevice_DecRef(device);
2754 /* alcIsExtensionPresent
2756 * Determines if there is support for a particular extension
2758 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2760 ALCboolean bResult = ALC_FALSE;
2762 device = VerifyDevice(device);
2764 if(!extName)
2765 alcSetError(device, ALC_INVALID_VALUE);
2766 else
2768 size_t len = strlen(extName);
2769 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2770 while(ptr && *ptr)
2772 if(strncasecmp(ptr, extName, len) == 0 &&
2773 (ptr[len] == '\0' || isspace(ptr[len])))
2775 bResult = ALC_TRUE;
2776 break;
2778 if((ptr=strchr(ptr, ' ')) != NULL)
2780 do {
2781 ++ptr;
2782 } while(isspace(*ptr));
2786 if(device)
2787 ALCdevice_DecRef(device);
2788 return bResult;
2792 /* alcGetProcAddress
2794 * Retrieves the function address for a particular extension function
2796 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2798 ALCvoid *ptr = NULL;
2800 if(!funcName)
2802 device = VerifyDevice(device);
2803 alcSetError(device, ALC_INVALID_VALUE);
2804 if(device) ALCdevice_DecRef(device);
2806 else
2808 ALsizei i = 0;
2809 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
2810 i++;
2811 ptr = alcFunctions[i].address;
2814 return ptr;
2818 /* alcGetEnumValue
2820 * Get the value for a particular ALC enumeration name
2822 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
2824 ALCenum val = 0;
2826 if(!enumName)
2828 device = VerifyDevice(device);
2829 alcSetError(device, ALC_INVALID_VALUE);
2830 if(device) ALCdevice_DecRef(device);
2832 else
2834 ALsizei i = 0;
2835 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
2836 i++;
2837 val = enumeration[i].value;
2840 return val;
2844 /* alcCreateContext
2846 * Create and attach a context to the given device.
2848 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
2850 ALCcontext *ALContext;
2851 ALCenum err;
2853 LockLists();
2854 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
2856 UnlockLists();
2857 alcSetError(device, ALC_INVALID_DEVICE);
2858 if(device) ALCdevice_DecRef(device);
2859 return NULL;
2862 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
2864 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
2866 UnlockLists();
2867 alcSetError(device, err);
2868 if(err == ALC_INVALID_DEVICE)
2870 ALCdevice_Lock(device);
2871 aluHandleDisconnect(device);
2872 ALCdevice_Unlock(device);
2874 ALCdevice_DecRef(device);
2875 return NULL;
2878 ALContext = calloc(1, sizeof(ALCcontext)+sizeof(ALlistener));
2879 if(ALContext)
2881 InitRef(&ALContext->ref, 1);
2882 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
2884 VECTOR_INIT(ALContext->ActiveAuxSlots);
2886 ALContext->MaxActiveSources = 256;
2887 ALContext->ActiveSources = calloc(ALContext->MaxActiveSources,
2888 sizeof(ALContext->ActiveSources[0]));
2890 if(!ALContext || !ALContext->ActiveSources)
2892 if(!ATOMIC_LOAD(&device->ContextList))
2894 V0(device->Backend,stop)();
2895 device->Flags &= ~DEVICE_RUNNING;
2897 UnlockLists();
2899 if(ALContext)
2901 free(ALContext->ActiveSources);
2902 ALContext->ActiveSources = NULL;
2904 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
2906 free(ALContext);
2907 ALContext = NULL;
2910 alcSetError(device, ALC_OUT_OF_MEMORY);
2911 ALCdevice_DecRef(device);
2912 return NULL;
2915 ALContext->Device = device;
2916 ALCdevice_IncRef(device);
2917 InitContext(ALContext);
2920 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
2921 do {
2922 ALContext->next = head;
2923 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
2925 UnlockLists();
2927 ALCdevice_DecRef(device);
2929 TRACE("Created context %p\n", ALContext);
2930 return ALContext;
2933 /* alcDestroyContext
2935 * Remove a context from its device
2937 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
2939 ALCdevice *Device;
2941 LockLists();
2942 /* alcGetContextsDevice sets an error for invalid contexts */
2943 Device = alcGetContextsDevice(context);
2944 if(Device)
2946 ReleaseContext(context, Device);
2947 if(!ATOMIC_LOAD(&Device->ContextList))
2949 V0(Device->Backend,stop)();
2950 Device->Flags &= ~DEVICE_RUNNING;
2953 UnlockLists();
2957 /* alcGetCurrentContext
2959 * Returns the currently active context on the calling thread
2961 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
2963 ALCcontext *Context = altss_get(LocalContext);
2964 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
2965 return Context;
2968 /* alcGetThreadContext
2970 * Returns the currently active thread-local context
2972 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
2974 return altss_get(LocalContext);
2978 /* alcMakeContextCurrent
2980 * Makes the given context the active process-wide context, and removes the
2981 * thread-local context for the calling thread.
2983 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
2985 /* context must be valid or NULL */
2986 if(context && !(context=VerifyContext(context)))
2988 alcSetError(NULL, ALC_INVALID_CONTEXT);
2989 return ALC_FALSE;
2991 /* context's reference count is already incremented */
2992 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
2993 if(context) ALCcontext_DecRef(context);
2995 if((context=altss_get(LocalContext)) != NULL)
2997 altss_set(LocalContext, NULL);
2998 ALCcontext_DecRef(context);
3001 return ALC_TRUE;
3004 /* alcSetThreadContext
3006 * Makes the given context the active context for the current thread
3008 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3010 ALCcontext *old;
3012 /* context must be valid or NULL */
3013 if(context && !(context=VerifyContext(context)))
3015 alcSetError(NULL, ALC_INVALID_CONTEXT);
3016 return ALC_FALSE;
3018 /* context's reference count is already incremented */
3019 old = altss_get(LocalContext);
3020 altss_set(LocalContext, context);
3021 if(old) ALCcontext_DecRef(old);
3023 return ALC_TRUE;
3027 /* alcGetContextsDevice
3029 * Returns the device that a particular context is attached to
3031 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3033 ALCdevice *Device;
3035 if(!(Context=VerifyContext(Context)))
3037 alcSetError(NULL, ALC_INVALID_CONTEXT);
3038 return NULL;
3040 Device = Context->Device;
3041 ALCcontext_DecRef(Context);
3043 return Device;
3047 /* alcOpenDevice
3049 * Opens the named device.
3051 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3053 const ALCchar *fmt;
3054 ALCdevice *device;
3055 ALCenum err;
3057 DO_INITCONFIG();
3059 if(!PlaybackBackend.name)
3061 alcSetError(NULL, ALC_INVALID_VALUE);
3062 return NULL;
3065 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3066 deviceName = NULL;
3068 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3069 if(!device)
3071 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3072 return NULL;
3075 //Validate device
3076 InitRef(&device->ref, 1);
3077 device->Connected = ALC_TRUE;
3078 device->Type = Playback;
3079 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3081 device->Flags = 0;
3082 device->Bs2b = NULL;
3083 device->Bs2bLevel = 0;
3084 AL_STRING_INIT(device->DeviceName);
3086 ATOMIC_INIT(&device->ContextList, NULL);
3088 device->ClockBase = 0;
3089 device->SamplesDone = 0;
3091 device->MaxNoOfSources = 256;
3092 device->AuxiliaryEffectSlotMax = 4;
3093 device->NumAuxSends = MAX_SENDS;
3095 InitUIntMap(&device->BufferMap, ~0);
3096 InitUIntMap(&device->EffectMap, ~0);
3097 InitUIntMap(&device->FilterMap, ~0);
3098 InitUIntMap(&device->SfontMap, ~0);
3099 InitUIntMap(&device->PresetMap, ~0);
3100 InitUIntMap(&device->FontsoundMap, ~0);
3102 //Set output format
3103 device->FmtChans = DevFmtChannelsDefault;
3104 device->FmtType = DevFmtTypeDefault;
3105 device->Frequency = DEFAULT_OUTPUT_RATE;
3106 device->NumUpdates = 4;
3107 device->UpdateSize = 1024;
3109 if(!PlaybackBackend.getFactory)
3110 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3111 ALCbackend_Playback);
3112 else
3114 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3115 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3117 if(!device->Backend)
3119 al_free(device);
3120 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3121 return NULL;
3125 if(ConfigValueStr(NULL, "channels", &fmt))
3127 static const struct {
3128 const char name[16];
3129 enum DevFmtChannels chans;
3130 } chanlist[] = {
3131 { "mono", DevFmtMono },
3132 { "stereo", DevFmtStereo },
3133 { "quad", DevFmtQuad },
3134 { "surround51", DevFmtX51 },
3135 { "surround61", DevFmtX61 },
3136 { "surround71", DevFmtX71 },
3138 size_t i;
3140 for(i = 0;i < COUNTOF(chanlist);i++)
3142 if(strcasecmp(chanlist[i].name, fmt) == 0)
3144 device->FmtChans = chanlist[i].chans;
3145 device->Flags |= DEVICE_CHANNELS_REQUEST;
3146 break;
3149 if(i == COUNTOF(chanlist))
3150 ERR("Unsupported channels: %s\n", fmt);
3152 if(ConfigValueStr(NULL, "sample-type", &fmt))
3154 static const struct {
3155 const char name[16];
3156 enum DevFmtType type;
3157 } typelist[] = {
3158 { "int8", DevFmtByte },
3159 { "uint8", DevFmtUByte },
3160 { "int16", DevFmtShort },
3161 { "uint16", DevFmtUShort },
3162 { "int32", DevFmtInt },
3163 { "uint32", DevFmtUInt },
3164 { "float32", DevFmtFloat },
3166 size_t i;
3168 for(i = 0;i < COUNTOF(typelist);i++)
3170 if(strcasecmp(typelist[i].name, fmt) == 0)
3172 device->FmtType = typelist[i].type;
3173 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3174 break;
3177 if(i == COUNTOF(typelist))
3178 ERR("Unsupported sample-type: %s\n", fmt);
3180 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3181 if((device->Flags&DEVICE_FORMAT_REQUEST) != DEVICE_FORMAT_REQUEST &&
3182 ConfigValueStr(NULL, "format", &fmt))
3184 static const struct {
3185 const char name[32];
3186 enum DevFmtChannels channels;
3187 enum DevFmtType type;
3188 } formats[] = {
3189 { "AL_FORMAT_MONO32", DevFmtMono, DevFmtFloat },
3190 { "AL_FORMAT_STEREO32", DevFmtStereo, DevFmtFloat },
3191 { "AL_FORMAT_QUAD32", DevFmtQuad, DevFmtFloat },
3192 { "AL_FORMAT_51CHN32", DevFmtX51, DevFmtFloat },
3193 { "AL_FORMAT_61CHN32", DevFmtX61, DevFmtFloat },
3194 { "AL_FORMAT_71CHN32", DevFmtX71, DevFmtFloat },
3196 { "AL_FORMAT_MONO16", DevFmtMono, DevFmtShort },
3197 { "AL_FORMAT_STEREO16", DevFmtStereo, DevFmtShort },
3198 { "AL_FORMAT_QUAD16", DevFmtQuad, DevFmtShort },
3199 { "AL_FORMAT_51CHN16", DevFmtX51, DevFmtShort },
3200 { "AL_FORMAT_61CHN16", DevFmtX61, DevFmtShort },
3201 { "AL_FORMAT_71CHN16", DevFmtX71, DevFmtShort },
3203 { "AL_FORMAT_MONO8", DevFmtMono, DevFmtByte },
3204 { "AL_FORMAT_STEREO8", DevFmtStereo, DevFmtByte },
3205 { "AL_FORMAT_QUAD8", DevFmtQuad, DevFmtByte },
3206 { "AL_FORMAT_51CHN8", DevFmtX51, DevFmtByte },
3207 { "AL_FORMAT_61CHN8", DevFmtX61, DevFmtByte },
3208 { "AL_FORMAT_71CHN8", DevFmtX71, DevFmtByte }
3210 size_t i;
3212 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3213 for(i = 0;i < COUNTOF(formats);i++)
3215 if(strcasecmp(fmt, formats[i].name) == 0)
3217 if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
3218 device->FmtChans = formats[i].channels;
3219 if(!(device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
3220 device->FmtType = formats[i].type;
3221 device->Flags |= DEVICE_FORMAT_REQUEST;
3222 break;
3225 if(i == COUNTOF(formats))
3226 ERR("Unsupported format: %s\n", fmt);
3228 #undef DEVICE_FORMAT_REQUEST
3230 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
3232 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3233 if(device->Frequency < MIN_OUTPUT_RATE)
3234 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3235 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3238 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
3239 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3241 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
3242 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3243 if((CPUCapFlags&CPU_CAP_SSE))
3244 device->UpdateSize = (device->UpdateSize+3)&~3;
3246 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3247 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3249 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3250 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3252 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3253 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3255 ConfigValueInt(NULL, "cf_level", &device->Bs2bLevel);
3257 device->NumStereoSources = 1;
3258 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3260 device->Synth = SynthCreate(device);
3261 if(!device->Synth)
3263 DELETE_OBJ(device->Backend);
3264 al_free(device);
3265 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3266 return NULL;
3269 // Find a playback device to open
3270 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3272 DELETE_OBJ(device->Synth);
3273 DELETE_OBJ(device->Backend);
3274 al_free(device);
3275 alcSetError(NULL, err);
3276 return NULL;
3279 if(DefaultEffect.type != AL_EFFECT_NULL)
3281 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3282 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3284 device->DefaultSlot = NULL;
3285 ERR("Failed to initialize the default effect slot\n");
3287 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3289 ALeffectState *state = device->DefaultSlot->EffectState;
3290 device->DefaultSlot = NULL;
3291 DELETE_OBJ(state);
3292 ERR("Failed to initialize the default effect\n");
3297 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3298 do {
3299 device->next = head;
3300 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3303 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3304 return device;
3307 /* alcCloseDevice
3309 * Closes the given device.
3311 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3313 ALCdevice *list, *origdev, *nextdev;
3314 ALCcontext *ctx;
3316 LockLists();
3317 list = ATOMIC_LOAD(&DeviceList);
3318 do {
3319 if(list == device)
3320 break;
3321 } while((list=list->next) != NULL);
3322 if(!list || list->Type == Capture)
3324 alcSetError(list, ALC_INVALID_DEVICE);
3325 UnlockLists();
3326 return ALC_FALSE;
3329 origdev = device;
3330 nextdev = device->next;
3331 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3333 do {
3334 list = origdev;
3335 origdev = device;
3336 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3338 UnlockLists();
3340 ctx = ATOMIC_LOAD(&device->ContextList);
3341 while(ctx != NULL)
3343 ALCcontext *next = ctx->next;
3344 WARN("Releasing context %p\n", ctx);
3345 ReleaseContext(ctx, device);
3346 ctx = next;
3348 if((device->Flags&DEVICE_RUNNING))
3349 V0(device->Backend,stop)();
3350 device->Flags &= ~DEVICE_RUNNING;
3352 ALCdevice_DecRef(device);
3354 return ALC_TRUE;
3358 /************************************************
3359 * ALC capture functions
3360 ************************************************/
3361 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3363 ALCdevice *device = NULL;
3364 ALCenum err;
3366 DO_INITCONFIG();
3368 if(!CaptureBackend.name)
3370 alcSetError(NULL, ALC_INVALID_VALUE);
3371 return NULL;
3374 if(samples <= 0)
3376 alcSetError(NULL, ALC_INVALID_VALUE);
3377 return NULL;
3380 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3381 deviceName = NULL;
3383 device = al_calloc(16, sizeof(ALCdevice));
3384 if(!device)
3386 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3387 return NULL;
3390 //Validate device
3391 InitRef(&device->ref, 1);
3392 device->Connected = ALC_TRUE;
3393 device->Type = Capture;
3395 AL_STRING_INIT(device->DeviceName);
3397 InitUIntMap(&device->BufferMap, ~0);
3398 InitUIntMap(&device->EffectMap, ~0);
3399 InitUIntMap(&device->FilterMap, ~0);
3400 InitUIntMap(&device->SfontMap, ~0);
3401 InitUIntMap(&device->PresetMap, ~0);
3402 InitUIntMap(&device->FontsoundMap, ~0);
3404 if(!CaptureBackend.getFactory)
3405 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3406 ALCbackend_Capture);
3407 else
3409 ALCbackendFactory *factory = CaptureBackend.getFactory();
3410 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3412 if(!device->Backend)
3414 al_free(device);
3415 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3416 return NULL;
3419 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3420 device->Frequency = frequency;
3422 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3423 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3425 al_free(device);
3426 alcSetError(NULL, ALC_INVALID_ENUM);
3427 return NULL;
3430 device->UpdateSize = samples;
3431 device->NumUpdates = 1;
3433 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3435 al_free(device);
3436 alcSetError(NULL, err);
3437 return NULL;
3441 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3442 do {
3443 device->next = head;
3444 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3447 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3448 return device;
3451 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3453 ALCdevice *list, *next, *nextdev;
3455 LockLists();
3456 list = ATOMIC_LOAD(&DeviceList);
3457 do {
3458 if(list == device)
3459 break;
3460 } while((list=list->next) != NULL);
3461 if(!list || list->Type != Capture)
3463 alcSetError(list, ALC_INVALID_DEVICE);
3464 UnlockLists();
3465 return ALC_FALSE;
3468 next = device;
3469 nextdev = device->next;
3470 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3472 do {
3473 list = next;
3474 next = device;
3475 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3477 UnlockLists();
3479 ALCdevice_DecRef(device);
3481 return ALC_TRUE;
3484 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3486 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3487 alcSetError(device, ALC_INVALID_DEVICE);
3488 else
3490 ALCdevice_Lock(device);
3491 if(device->Connected)
3493 if(!(device->Flags&DEVICE_RUNNING))
3494 V0(device->Backend,start)();
3495 device->Flags |= DEVICE_RUNNING;
3497 ALCdevice_Unlock(device);
3500 if(device) ALCdevice_DecRef(device);
3503 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3505 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3506 alcSetError(device, ALC_INVALID_DEVICE);
3507 else
3509 ALCdevice_Lock(device);
3510 if((device->Flags&DEVICE_RUNNING))
3511 V0(device->Backend,stop)();
3512 device->Flags &= ~DEVICE_RUNNING;
3513 ALCdevice_Unlock(device);
3516 if(device) ALCdevice_DecRef(device);
3519 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3521 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3522 alcSetError(device, ALC_INVALID_DEVICE);
3523 else
3525 ALCenum err = ALC_INVALID_VALUE;
3527 ALCdevice_Lock(device);
3528 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3529 err = V(device->Backend,captureSamples)(buffer, samples);
3530 ALCdevice_Unlock(device);
3532 if(err != ALC_NO_ERROR)
3533 alcSetError(device, err);
3535 if(device) ALCdevice_DecRef(device);
3539 /************************************************
3540 * ALC loopback functions
3541 ************************************************/
3543 /* alcLoopbackOpenDeviceSOFT
3545 * Open a loopback device, for manual rendering.
3547 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3549 ALCbackendFactory *factory;
3550 ALCdevice *device;
3552 DO_INITCONFIG();
3554 /* Make sure the device name, if specified, is us. */
3555 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3557 alcSetError(NULL, ALC_INVALID_VALUE);
3558 return NULL;
3561 device = al_calloc(16, sizeof(ALCdevice));
3562 if(!device)
3564 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3565 return NULL;
3568 //Validate device
3569 InitRef(&device->ref, 1);
3570 device->Connected = ALC_TRUE;
3571 device->Type = Loopback;
3572 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3574 device->Flags = 0;
3575 device->Bs2b = NULL;
3576 device->Bs2bLevel = 0;
3577 AL_STRING_INIT(device->DeviceName);
3579 ATOMIC_INIT(&device->ContextList, NULL);
3581 device->ClockBase = 0;
3582 device->SamplesDone = 0;
3584 device->MaxNoOfSources = 256;
3585 device->AuxiliaryEffectSlotMax = 4;
3586 device->NumAuxSends = MAX_SENDS;
3588 InitUIntMap(&device->BufferMap, ~0);
3589 InitUIntMap(&device->EffectMap, ~0);
3590 InitUIntMap(&device->FilterMap, ~0);
3591 InitUIntMap(&device->SfontMap, ~0);
3592 InitUIntMap(&device->PresetMap, ~0);
3593 InitUIntMap(&device->FontsoundMap, ~0);
3595 factory = ALCloopbackFactory_getFactory();
3596 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3597 if(!device->Backend)
3599 al_free(device);
3600 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3601 return NULL;
3604 //Set output format
3605 device->NumUpdates = 0;
3606 device->UpdateSize = 0;
3608 device->Frequency = DEFAULT_OUTPUT_RATE;
3609 device->FmtChans = DevFmtChannelsDefault;
3610 device->FmtType = DevFmtTypeDefault;
3612 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3613 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3615 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3616 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3618 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3619 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3621 device->NumStereoSources = 1;
3622 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3624 device->Synth = SynthCreate(device);
3625 if(!device->Synth)
3627 DELETE_OBJ(device->Backend);
3628 al_free(device);
3629 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3630 return NULL;
3633 // Open the "backend"
3634 V(device->Backend,open)("Loopback");
3637 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3638 do {
3639 device->next = head;
3640 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3643 TRACE("Created device %p\n", device);
3644 return device;
3647 /* alcIsRenderFormatSupportedSOFT
3649 * Determines if the loopback device supports the given format for rendering.
3651 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3653 ALCboolean ret = ALC_FALSE;
3655 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3656 alcSetError(device, ALC_INVALID_DEVICE);
3657 else if(freq <= 0)
3658 alcSetError(device, ALC_INVALID_VALUE);
3659 else
3661 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3662 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3663 freq >= MIN_OUTPUT_RATE)
3664 ret = ALC_TRUE;
3666 if(device) ALCdevice_DecRef(device);
3668 return ret;
3671 /* alcRenderSamplesSOFT
3673 * Renders some samples into a buffer, using the format last set by the
3674 * attributes given to alcCreateContext.
3676 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3678 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3679 alcSetError(device, ALC_INVALID_DEVICE);
3680 else if(samples < 0 || (samples > 0 && buffer == NULL))
3681 alcSetError(device, ALC_INVALID_VALUE);
3682 else
3683 aluMixData(device, buffer, samples);
3684 if(device) ALCdevice_DecRef(device);
3688 /************************************************
3689 * ALC DSP pause/resume functions
3690 ************************************************/
3692 /* alcDevicePauseSOFT
3694 * Pause the DSP to stop audio processing.
3696 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3698 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3699 alcSetError(device, ALC_INVALID_DEVICE);
3700 else
3702 LockLists();
3703 if((device->Flags&DEVICE_RUNNING))
3704 V0(device->Backend,stop)();
3705 device->Flags &= ~DEVICE_RUNNING;
3706 device->Flags |= DEVICE_PAUSED;
3707 UnlockLists();
3709 if(device) ALCdevice_DecRef(device);
3712 /* alcDeviceResumeSOFT
3714 * Resume the DSP to restart audio processing.
3716 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3718 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3719 alcSetError(device, ALC_INVALID_DEVICE);
3720 else
3722 LockLists();
3723 if((device->Flags&DEVICE_PAUSED))
3725 device->Flags &= ~DEVICE_PAUSED;
3726 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3728 if(V0(device->Backend,start)() != ALC_FALSE)
3729 device->Flags |= DEVICE_RUNNING;
3730 else
3732 alcSetError(device, ALC_INVALID_DEVICE);
3733 ALCdevice_Lock(device);
3734 aluHandleDisconnect(device);
3735 ALCdevice_Unlock(device);
3739 UnlockLists();
3741 if(device) ALCdevice_DecRef(device);