Initialize panning after setting up HRTF
[openal-soft.git] / Alc / ALc.c
blobf83a884cda2c9978ae497299c9525b8ca66a3f3c
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include <ctype.h>
28 #include <signal.h>
30 #include "alMain.h"
31 #include "alSource.h"
32 #include "alListener.h"
33 #include "alThunk.h"
34 #include "alSource.h"
35 #include "alBuffer.h"
36 #include "alAuxEffectSlot.h"
37 #include "alError.h"
38 #include "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 }
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", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, 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", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, 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),
500 DECL(AL_FORMAT_BFORMAT2D_8),
501 DECL(AL_FORMAT_BFORMAT2D_16),
502 DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
503 DECL(AL_FORMAT_BFORMAT2D_MULAW),
504 DECL(AL_FORMAT_BFORMAT3D_8),
505 DECL(AL_FORMAT_BFORMAT3D_16),
506 DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
507 DECL(AL_FORMAT_BFORMAT3D_MULAW),
509 DECL(AL_MONO_SOFT),
510 DECL(AL_STEREO_SOFT),
511 DECL(AL_QUAD_SOFT),
512 DECL(AL_REAR_SOFT),
513 DECL(AL_5POINT1_SOFT),
514 DECL(AL_6POINT1_SOFT),
515 DECL(AL_7POINT1_SOFT),
517 DECL(AL_BYTE_SOFT),
518 DECL(AL_UNSIGNED_BYTE_SOFT),
519 DECL(AL_SHORT_SOFT),
520 DECL(AL_UNSIGNED_SHORT_SOFT),
521 DECL(AL_INT_SOFT),
522 DECL(AL_UNSIGNED_INT_SOFT),
523 DECL(AL_FLOAT_SOFT),
524 DECL(AL_DOUBLE_SOFT),
525 DECL(AL_BYTE3_SOFT),
526 DECL(AL_UNSIGNED_BYTE3_SOFT),
528 DECL(AL_FREQUENCY),
529 DECL(AL_BITS),
530 DECL(AL_CHANNELS),
531 DECL(AL_SIZE),
532 DECL(AL_INTERNAL_FORMAT_SOFT),
533 DECL(AL_BYTE_LENGTH_SOFT),
534 DECL(AL_SAMPLE_LENGTH_SOFT),
535 DECL(AL_SEC_LENGTH_SOFT),
536 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
537 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
539 DECL(AL_UNUSED),
540 DECL(AL_PENDING),
541 DECL(AL_PROCESSED),
543 DECL(AL_NO_ERROR),
544 DECL(AL_INVALID_NAME),
545 DECL(AL_INVALID_ENUM),
546 DECL(AL_INVALID_VALUE),
547 DECL(AL_INVALID_OPERATION),
548 DECL(AL_OUT_OF_MEMORY),
550 DECL(AL_VENDOR),
551 DECL(AL_VERSION),
552 DECL(AL_RENDERER),
553 DECL(AL_EXTENSIONS),
555 DECL(AL_DOPPLER_FACTOR),
556 DECL(AL_DOPPLER_VELOCITY),
557 DECL(AL_DISTANCE_MODEL),
558 DECL(AL_SPEED_OF_SOUND),
559 DECL(AL_SOURCE_DISTANCE_MODEL),
560 DECL(AL_DEFERRED_UPDATES_SOFT),
562 DECL(AL_INVERSE_DISTANCE),
563 DECL(AL_INVERSE_DISTANCE_CLAMPED),
564 DECL(AL_LINEAR_DISTANCE),
565 DECL(AL_LINEAR_DISTANCE_CLAMPED),
566 DECL(AL_EXPONENT_DISTANCE),
567 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
569 DECL(AL_FILTER_TYPE),
570 DECL(AL_FILTER_NULL),
571 DECL(AL_FILTER_LOWPASS),
572 DECL(AL_FILTER_HIGHPASS),
573 DECL(AL_FILTER_BANDPASS),
575 DECL(AL_LOWPASS_GAIN),
576 DECL(AL_LOWPASS_GAINHF),
578 DECL(AL_HIGHPASS_GAIN),
579 DECL(AL_HIGHPASS_GAINLF),
581 DECL(AL_BANDPASS_GAIN),
582 DECL(AL_BANDPASS_GAINHF),
583 DECL(AL_BANDPASS_GAINLF),
585 DECL(AL_EFFECT_TYPE),
586 DECL(AL_EFFECT_NULL),
587 DECL(AL_EFFECT_REVERB),
588 DECL(AL_EFFECT_EAXREVERB),
589 DECL(AL_EFFECT_CHORUS),
590 DECL(AL_EFFECT_DISTORTION),
591 DECL(AL_EFFECT_ECHO),
592 DECL(AL_EFFECT_FLANGER),
593 #if 0
594 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
595 DECL(AL_EFFECT_VOCAL_MORPHER),
596 DECL(AL_EFFECT_PITCH_SHIFTER),
597 #endif
598 DECL(AL_EFFECT_RING_MODULATOR),
599 #if 0
600 DECL(AL_EFFECT_AUTOWAH),
601 #endif
602 DECL(AL_EFFECT_COMPRESSOR),
603 DECL(AL_EFFECT_EQUALIZER),
604 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
605 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
607 DECL(AL_EAXREVERB_DENSITY),
608 DECL(AL_EAXREVERB_DIFFUSION),
609 DECL(AL_EAXREVERB_GAIN),
610 DECL(AL_EAXREVERB_GAINHF),
611 DECL(AL_EAXREVERB_GAINLF),
612 DECL(AL_EAXREVERB_DECAY_TIME),
613 DECL(AL_EAXREVERB_DECAY_HFRATIO),
614 DECL(AL_EAXREVERB_DECAY_LFRATIO),
615 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
616 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
617 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
618 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
619 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
620 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
621 DECL(AL_EAXREVERB_ECHO_TIME),
622 DECL(AL_EAXREVERB_ECHO_DEPTH),
623 DECL(AL_EAXREVERB_MODULATION_TIME),
624 DECL(AL_EAXREVERB_MODULATION_DEPTH),
625 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
626 DECL(AL_EAXREVERB_HFREFERENCE),
627 DECL(AL_EAXREVERB_LFREFERENCE),
628 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
629 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
631 DECL(AL_REVERB_DENSITY),
632 DECL(AL_REVERB_DIFFUSION),
633 DECL(AL_REVERB_GAIN),
634 DECL(AL_REVERB_GAINHF),
635 DECL(AL_REVERB_DECAY_TIME),
636 DECL(AL_REVERB_DECAY_HFRATIO),
637 DECL(AL_REVERB_REFLECTIONS_GAIN),
638 DECL(AL_REVERB_REFLECTIONS_DELAY),
639 DECL(AL_REVERB_LATE_REVERB_GAIN),
640 DECL(AL_REVERB_LATE_REVERB_DELAY),
641 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
642 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
643 DECL(AL_REVERB_DECAY_HFLIMIT),
645 DECL(AL_CHORUS_WAVEFORM),
646 DECL(AL_CHORUS_PHASE),
647 DECL(AL_CHORUS_RATE),
648 DECL(AL_CHORUS_DEPTH),
649 DECL(AL_CHORUS_FEEDBACK),
650 DECL(AL_CHORUS_DELAY),
652 DECL(AL_DISTORTION_EDGE),
653 DECL(AL_DISTORTION_GAIN),
654 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
655 DECL(AL_DISTORTION_EQCENTER),
656 DECL(AL_DISTORTION_EQBANDWIDTH),
658 DECL(AL_ECHO_DELAY),
659 DECL(AL_ECHO_LRDELAY),
660 DECL(AL_ECHO_DAMPING),
661 DECL(AL_ECHO_FEEDBACK),
662 DECL(AL_ECHO_SPREAD),
664 DECL(AL_FLANGER_WAVEFORM),
665 DECL(AL_FLANGER_PHASE),
666 DECL(AL_FLANGER_RATE),
667 DECL(AL_FLANGER_DEPTH),
668 DECL(AL_FLANGER_FEEDBACK),
669 DECL(AL_FLANGER_DELAY),
671 DECL(AL_RING_MODULATOR_FREQUENCY),
672 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
673 DECL(AL_RING_MODULATOR_WAVEFORM),
675 #if 0
676 DECL(AL_AUTOWAH_ATTACK_TIME),
677 DECL(AL_AUTOWAH_PEAK_GAIN),
678 DECL(AL_AUTOWAH_RELEASE_TIME),
679 DECL(AL_AUTOWAH_RESONANCE),
680 #endif
682 DECL(AL_COMPRESSOR_ONOFF),
684 DECL(AL_EQUALIZER_LOW_GAIN),
685 DECL(AL_EQUALIZER_LOW_CUTOFF),
686 DECL(AL_EQUALIZER_MID1_GAIN),
687 DECL(AL_EQUALIZER_MID1_CENTER),
688 DECL(AL_EQUALIZER_MID1_WIDTH),
689 DECL(AL_EQUALIZER_MID2_GAIN),
690 DECL(AL_EQUALIZER_MID2_CENTER),
691 DECL(AL_EQUALIZER_MID2_WIDTH),
692 DECL(AL_EQUALIZER_HIGH_GAIN),
693 DECL(AL_EQUALIZER_HIGH_CUTOFF),
695 DECL(AL_DEDICATED_GAIN),
697 { NULL, (ALCenum)0 }
699 #undef DECL
701 static const ALCchar alcNoError[] = "No Error";
702 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
703 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
704 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
705 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
706 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
709 /************************************************
710 * Global variables
711 ************************************************/
713 /* Enumerated device names */
714 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
716 static al_string alcAllDevicesList;
717 static al_string alcCaptureDeviceList;
719 /* Default is always the first in the list */
720 static ALCchar *alcDefaultAllDevicesSpecifier;
721 static ALCchar *alcCaptureDefaultDeviceSpecifier;
723 /* Default context extensions */
724 static const ALchar alExtList[] =
725 "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
726 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
727 "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
728 "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
729 "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
730 "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
731 "AL_SOFT_source_latency AL_SOFT_source_length";
733 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
735 /* Thread-local current context */
736 static altss_t LocalContext;
737 /* Process-wide current context */
738 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
740 /* Mixing thread piority level */
741 ALint RTPrioLevel;
743 FILE *LogFile;
744 #ifdef _DEBUG
745 enum LogLevel LogLevel = LogWarning;
746 #else
747 enum LogLevel LogLevel = LogError;
748 #endif
750 /* Flag to trap ALC device errors */
751 static ALCboolean TrapALCError = ALC_FALSE;
753 /* One-time configuration init control */
754 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
756 /* Default effect that applies to sources that don't have an effect on send 0 */
757 static ALeffect DefaultEffect;
759 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
760 * updates.
762 static ALCboolean SuspendDefers = ALC_TRUE;
765 /************************************************
766 * ALC information
767 ************************************************/
768 static const ALCchar alcNoDeviceExtList[] =
769 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
770 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
771 static const ALCchar alcExtensionList[] =
772 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
773 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
774 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
775 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFT_pause_device";
776 static const ALCint alcMajorVersion = 1;
777 static const ALCint alcMinorVersion = 1;
779 static const ALCint alcEFXMajorVersion = 1;
780 static const ALCint alcEFXMinorVersion = 0;
783 /************************************************
784 * Device lists
785 ************************************************/
786 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
788 static almtx_t ListLock;
789 static inline void LockLists(void)
791 int lockret = almtx_lock(&ListLock);
792 assert(lockret == althrd_success);
794 static inline void UnlockLists(void)
796 int unlockret = almtx_unlock(&ListLock);
797 assert(unlockret == althrd_success);
800 /************************************************
801 * Library initialization
802 ************************************************/
803 #if defined(_WIN32)
804 static void alc_init(void);
805 static void alc_deinit(void);
806 static void alc_deinit_safe(void);
808 #ifndef AL_LIBTYPE_STATIC
809 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
811 switch(reason)
813 case DLL_PROCESS_ATTACH:
814 /* Pin the DLL so we won't get unloaded until the process terminates */
815 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
816 (WCHAR*)hModule, &hModule);
817 alc_init();
818 break;
820 case DLL_THREAD_DETACH:
821 break;
823 case DLL_PROCESS_DETACH:
824 if(!lpReserved)
825 alc_deinit();
826 else
827 alc_deinit_safe();
828 break;
830 return TRUE;
832 #elif defined(_MSC_VER)
833 #pragma section(".CRT$XCU",read)
834 static void alc_constructor(void);
835 static void alc_destructor(void);
836 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
838 static void alc_constructor(void)
840 atexit(alc_destructor);
841 alc_init();
844 static void alc_destructor(void)
846 alc_deinit();
848 #elif defined(HAVE_GCC_DESTRUCTOR)
849 static void alc_init(void) __attribute__((constructor));
850 static void alc_deinit(void) __attribute__((destructor));
851 #else
852 #error "No static initialization available on this platform!"
853 #endif
855 #elif defined(HAVE_GCC_DESTRUCTOR)
857 static void alc_init(void) __attribute__((constructor));
858 static void alc_deinit(void) __attribute__((destructor));
860 #else
861 #error "No global initialization available on this platform!"
862 #endif
864 static void ReleaseThreadCtx(void *ptr);
865 static void alc_init(void)
867 const char *str;
868 int ret;
870 LogFile = stderr;
872 AL_STRING_INIT(alcAllDevicesList);
873 AL_STRING_INIT(alcCaptureDeviceList);
875 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
876 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
877 ConeScale *= 0.5f;
879 str = getenv("__ALSOFT_REVERSE_Z");
880 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
881 ZScale *= -1.0f;
883 ret = altss_create(&LocalContext, ReleaseThreadCtx);
884 assert(ret == althrd_success);
886 ret = almtx_init(&ListLock, almtx_recursive);
887 assert(ret == althrd_success);
889 ThunkInit();
892 static void alc_initconfig(void)
894 const char *devs, *str;
895 ALuint capfilter;
896 float valf;
897 int i, n;
899 str = getenv("ALSOFT_LOGLEVEL");
900 if(str)
902 long lvl = strtol(str, NULL, 0);
903 if(lvl >= NoLog && lvl <= LogRef)
904 LogLevel = lvl;
907 str = getenv("ALSOFT_LOGFILE");
908 if(str && str[0])
910 FILE *logfile = al_fopen(str, "wt");
911 if(logfile) LogFile = logfile;
912 else ERR("Failed to open log file '%s'\n", str);
916 char buf[1024] = "";
917 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
918 for(i = 1;BackendList[i].name;i++)
919 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
920 TRACE("Supported backends: %s\n", buf);
922 ReadALConfig();
924 str = getenv("__ALSOFT_SUSPEND_CONTEXT");
925 if(str && *str)
927 if(strcasecmp(str, "ignore") == 0)
929 SuspendDefers = ALC_FALSE;
930 TRACE("Selected context suspend behavior, \"ignore\"\n");
932 else
933 ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
936 capfilter = 0;
937 #if defined(HAVE_SSE4_1)
938 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE4_1;
939 #elif defined(HAVE_SSE2)
940 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
941 #elif defined(HAVE_SSE)
942 capfilter |= CPU_CAP_SSE;
943 #endif
944 #ifdef HAVE_NEON
945 capfilter |= CPU_CAP_NEON;
946 #endif
947 if(ConfigValueStr(NULL, "disable-cpu-exts", &str))
949 if(strcasecmp(str, "all") == 0)
950 capfilter = 0;
951 else
953 size_t len;
954 const char *next = str;
956 do {
957 str = next;
958 while(isspace(str[0]))
959 str++;
960 next = strchr(str, ',');
962 if(!str[0] || str[0] == ',')
963 continue;
965 len = (next ? ((size_t)(next-str)) : strlen(str));
966 while(len > 0 && isspace(str[len-1]))
967 len--;
968 if(len == 3 && strncasecmp(str, "sse", len) == 0)
969 capfilter &= ~CPU_CAP_SSE;
970 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
971 capfilter &= ~CPU_CAP_SSE2;
972 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
973 capfilter &= ~CPU_CAP_SSE4_1;
974 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
975 capfilter &= ~CPU_CAP_NEON;
976 else
977 WARN("Invalid CPU extension \"%s\"\n", str);
978 } while(next++);
981 FillCPUCaps(capfilter);
983 #ifdef _WIN32
984 RTPrioLevel = 1;
985 #else
986 RTPrioLevel = 0;
987 #endif
988 ConfigValueInt(NULL, "rt-prio", &RTPrioLevel);
990 if(ConfigValueStr(NULL, "resampler", &str))
992 if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
993 DefaultResampler = PointResampler;
994 else if(strcasecmp(str, "linear") == 0)
995 DefaultResampler = LinearResampler;
996 else if(strcasecmp(str, "cubic") == 0)
997 DefaultResampler = CubicResampler;
998 else
1000 char *end;
1002 n = strtol(str, &end, 0);
1003 if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == CubicResampler))
1004 DefaultResampler = n;
1005 else
1006 WARN("Invalid resampler: %s\n", str);
1010 str = getenv("ALSOFT_TRAP_ERROR");
1011 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1013 TrapALError = AL_TRUE;
1014 TrapALCError = AL_TRUE;
1016 else
1018 str = getenv("ALSOFT_TRAP_AL_ERROR");
1019 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1020 TrapALError = AL_TRUE;
1021 TrapALError = GetConfigValueBool(NULL, "trap-al-error", TrapALError);
1023 str = getenv("ALSOFT_TRAP_ALC_ERROR");
1024 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1025 TrapALCError = ALC_TRUE;
1026 TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", TrapALCError);
1029 if(ConfigValueFloat("reverb", "boost", &valf))
1030 ReverbBoost *= powf(10.0f, valf / 20.0f);
1032 EmulateEAXReverb = GetConfigValueBool("reverb", "emulate-eax", AL_FALSE);
1034 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1035 ConfigValueStr(NULL, "drivers", &devs))
1037 int n;
1038 size_t len;
1039 const char *next = devs;
1040 int endlist, delitem;
1042 i = 0;
1043 do {
1044 devs = next;
1045 while(isspace(devs[0]))
1046 devs++;
1047 next = strchr(devs, ',');
1049 delitem = (devs[0] == '-');
1050 if(devs[0] == '-') devs++;
1052 if(!devs[0] || devs[0] == ',')
1054 endlist = 0;
1055 continue;
1057 endlist = 1;
1059 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1060 while(len > 0 && isspace(devs[len-1]))
1061 len--;
1062 for(n = i;BackendList[n].name;n++)
1064 if(len == strlen(BackendList[n].name) &&
1065 strncmp(BackendList[n].name, devs, len) == 0)
1067 if(delitem)
1069 do {
1070 BackendList[n] = BackendList[n+1];
1071 ++n;
1072 } while(BackendList[n].name);
1074 else
1076 struct BackendInfo Bkp = BackendList[n];
1077 while(n > i)
1079 BackendList[n] = BackendList[n-1];
1080 --n;
1082 BackendList[n] = Bkp;
1084 i++;
1086 break;
1089 } while(next++);
1091 if(endlist)
1093 BackendList[i].name = NULL;
1094 BackendList[i].getFactory = NULL;
1095 BackendList[i].Init = NULL;
1096 BackendList[i].Deinit = NULL;
1097 BackendList[i].Probe = NULL;
1101 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1103 if(BackendList[i].getFactory)
1105 ALCbackendFactory *factory = BackendList[i].getFactory();
1106 if(!V0(factory,init)())
1108 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1109 continue;
1112 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1113 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1115 PlaybackBackend = BackendList[i];
1116 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1118 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1120 CaptureBackend = BackendList[i];
1121 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1124 continue;
1127 if(!BackendList[i].Init(&BackendList[i].Funcs))
1129 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1130 continue;
1133 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1134 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1136 PlaybackBackend = BackendList[i];
1137 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1139 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1141 CaptureBackend = BackendList[i];
1142 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1146 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1147 V0(factory,init)();
1150 if(ConfigValueStr(NULL, "excludefx", &str))
1152 size_t len;
1153 const char *next = str;
1155 do {
1156 str = next;
1157 next = strchr(str, ',');
1159 if(!str[0] || next == str)
1160 continue;
1162 len = (next ? ((size_t)(next-str)) : strlen(str));
1163 for(n = 0;EffectList[n].name;n++)
1165 if(len == strlen(EffectList[n].name) &&
1166 strncmp(EffectList[n].name, str, len) == 0)
1167 DisabledEffects[EffectList[n].type] = AL_TRUE;
1169 } while(next++);
1172 InitEffectFactoryMap();
1174 InitEffect(&DefaultEffect);
1175 str = getenv("ALSOFT_DEFAULT_REVERB");
1176 if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str))
1177 LoadReverbPreset(str, &DefaultEffect);
1179 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1182 /************************************************
1183 * Library deinitialization
1184 ************************************************/
1185 static void alc_cleanup(void)
1187 ALCdevice *dev;
1189 AL_STRING_DEINIT(alcAllDevicesList);
1190 AL_STRING_DEINIT(alcCaptureDeviceList);
1192 free(alcDefaultAllDevicesSpecifier);
1193 alcDefaultAllDevicesSpecifier = NULL;
1194 free(alcCaptureDefaultDeviceSpecifier);
1195 alcCaptureDefaultDeviceSpecifier = NULL;
1197 if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1199 ALCuint num = 0;
1200 do {
1201 num++;
1202 } while((dev=dev->next) != NULL);
1203 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1206 DeinitEffectFactoryMap();
1209 static void alc_deinit_safe(void)
1211 alc_cleanup();
1213 FreeHrtfs();
1214 FreeALConfig();
1216 ThunkExit();
1217 almtx_destroy(&ListLock);
1218 altss_delete(LocalContext);
1220 if(LogFile != stderr)
1221 fclose(LogFile);
1222 LogFile = NULL;
1225 static void alc_deinit(void)
1227 int i;
1229 alc_cleanup();
1231 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1232 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1234 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1236 if(!BackendList[i].getFactory)
1237 BackendList[i].Deinit();
1238 else
1240 ALCbackendFactory *factory = BackendList[i].getFactory();
1241 V0(factory,deinit)();
1245 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1246 V0(factory,deinit)();
1249 alc_deinit_safe();
1253 /************************************************
1254 * Device enumeration
1255 ************************************************/
1256 static void ProbeDevices(al_string *list, enum DevProbe type)
1258 DO_INITCONFIG();
1260 LockLists();
1261 al_string_clear(list);
1263 if(type == ALL_DEVICE_PROBE && (PlaybackBackend.Probe || PlaybackBackend.getFactory))
1265 if(!PlaybackBackend.getFactory)
1266 PlaybackBackend.Probe(type);
1267 else
1269 ALCbackendFactory *factory = PlaybackBackend.getFactory();
1270 V(factory,probe)(type);
1273 else if(type == CAPTURE_DEVICE_PROBE && (CaptureBackend.Probe || CaptureBackend.getFactory))
1275 if(!CaptureBackend.getFactory)
1276 CaptureBackend.Probe(type);
1277 else
1279 ALCbackendFactory *factory = CaptureBackend.getFactory();
1280 V(factory,probe)(type);
1283 UnlockLists();
1285 static void ProbeAllDevicesList(void)
1286 { ProbeDevices(&alcAllDevicesList, ALL_DEVICE_PROBE); }
1287 static void ProbeCaptureDeviceList(void)
1288 { ProbeDevices(&alcCaptureDeviceList, CAPTURE_DEVICE_PROBE); }
1290 static void AppendDevice(const ALCchar *name, al_string *devnames)
1292 size_t len = strlen(name);
1293 if(len > 0)
1294 al_string_append_range(devnames, name, name+len+1);
1296 void AppendAllDevicesList(const ALCchar *name)
1297 { AppendDevice(name, &alcAllDevicesList); }
1298 void AppendCaptureDeviceList(const ALCchar *name)
1299 { AppendDevice(name, &alcCaptureDeviceList); }
1302 /************************************************
1303 * Device format information
1304 ************************************************/
1305 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1307 switch(type)
1309 case DevFmtByte: return "Signed Byte";
1310 case DevFmtUByte: return "Unsigned Byte";
1311 case DevFmtShort: return "Signed Short";
1312 case DevFmtUShort: return "Unsigned Short";
1313 case DevFmtInt: return "Signed Int";
1314 case DevFmtUInt: return "Unsigned Int";
1315 case DevFmtFloat: return "Float";
1317 return "(unknown type)";
1319 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1321 switch(chans)
1323 case DevFmtMono: return "Mono";
1324 case DevFmtStereo: return "Stereo";
1325 case DevFmtQuad: return "Quadraphonic";
1326 case DevFmtX51: return "5.1 Surround";
1327 case DevFmtX51Rear: return "5.1 Surround (Rear)";
1328 case DevFmtX61: return "6.1 Surround";
1329 case DevFmtX71: return "7.1 Surround";
1331 return "(unknown channels)";
1334 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1335 ALuint BytesFromDevFmt(enum DevFmtType type)
1337 switch(type)
1339 case DevFmtByte: return sizeof(ALbyte);
1340 case DevFmtUByte: return sizeof(ALubyte);
1341 case DevFmtShort: return sizeof(ALshort);
1342 case DevFmtUShort: return sizeof(ALushort);
1343 case DevFmtInt: return sizeof(ALint);
1344 case DevFmtUInt: return sizeof(ALuint);
1345 case DevFmtFloat: return sizeof(ALfloat);
1347 return 0;
1349 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1351 switch(chans)
1353 case DevFmtMono: return 1;
1354 case DevFmtStereo: return 2;
1355 case DevFmtQuad: return 4;
1356 case DevFmtX51: return 6;
1357 case DevFmtX51Rear: return 6;
1358 case DevFmtX61: return 7;
1359 case DevFmtX71: return 8;
1361 return 0;
1364 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1365 enum DevFmtChannels *chans, enum DevFmtType *type)
1367 static const struct {
1368 ALenum format;
1369 enum DevFmtChannels channels;
1370 enum DevFmtType type;
1371 } list[] = {
1372 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1373 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1374 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1376 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1377 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1378 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1380 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1381 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1382 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1384 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1385 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1386 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1388 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1389 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1390 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1392 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1393 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1394 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1396 ALuint i;
1398 for(i = 0;i < COUNTOF(list);i++)
1400 if(list[i].format == format)
1402 *chans = list[i].channels;
1403 *type = list[i].type;
1404 return AL_TRUE;
1408 return AL_FALSE;
1411 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1413 switch(type)
1415 case ALC_BYTE_SOFT:
1416 case ALC_UNSIGNED_BYTE_SOFT:
1417 case ALC_SHORT_SOFT:
1418 case ALC_UNSIGNED_SHORT_SOFT:
1419 case ALC_INT_SOFT:
1420 case ALC_UNSIGNED_INT_SOFT:
1421 case ALC_FLOAT_SOFT:
1422 return ALC_TRUE;
1424 return ALC_FALSE;
1427 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1429 switch(channels)
1431 case ALC_MONO_SOFT:
1432 case ALC_STEREO_SOFT:
1433 case ALC_QUAD_SOFT:
1434 case ALC_5POINT1_SOFT:
1435 case ALC_6POINT1_SOFT:
1436 case ALC_7POINT1_SOFT:
1437 return ALC_TRUE;
1439 return ALC_FALSE;
1443 /************************************************
1444 * Miscellaneous ALC helpers
1445 ************************************************/
1446 extern inline void LockContext(ALCcontext *context);
1447 extern inline void UnlockContext(ALCcontext *context);
1449 ALint64 ALCdevice_GetLatency(ALCdevice *device)
1451 return V0(device->Backend,getLatency)();
1454 void ALCdevice_Lock(ALCdevice *device)
1456 V0(device->Backend,lock)();
1459 void ALCdevice_Unlock(ALCdevice *device)
1461 V0(device->Backend,unlock)();
1465 /* SetDefaultWFXChannelOrder
1467 * Sets the default channel order used by WaveFormatEx.
1469 void SetDefaultWFXChannelOrder(ALCdevice *device)
1471 ALuint i;
1473 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1474 device->ChannelName[i] = InvalidChannel;
1476 switch(device->FmtChans)
1478 case DevFmtMono:
1479 device->ChannelName[0] = FrontCenter;
1480 break;
1481 case DevFmtStereo:
1482 device->ChannelName[0] = FrontLeft;
1483 device->ChannelName[1] = FrontRight;
1484 break;
1485 case DevFmtQuad:
1486 device->ChannelName[0] = FrontLeft;
1487 device->ChannelName[1] = FrontRight;
1488 device->ChannelName[2] = BackLeft;
1489 device->ChannelName[3] = BackRight;
1490 break;
1491 case DevFmtX51:
1492 device->ChannelName[0] = FrontLeft;
1493 device->ChannelName[1] = FrontRight;
1494 device->ChannelName[2] = FrontCenter;
1495 device->ChannelName[3] = LFE;
1496 device->ChannelName[4] = SideLeft;
1497 device->ChannelName[5] = SideRight;
1498 break;
1499 case DevFmtX51Rear:
1500 device->ChannelName[0] = FrontLeft;
1501 device->ChannelName[1] = FrontRight;
1502 device->ChannelName[2] = FrontCenter;
1503 device->ChannelName[3] = LFE;
1504 device->ChannelName[4] = BackLeft;
1505 device->ChannelName[5] = BackRight;
1506 break;
1507 case DevFmtX61:
1508 device->ChannelName[0] = FrontLeft;
1509 device->ChannelName[1] = FrontRight;
1510 device->ChannelName[2] = FrontCenter;
1511 device->ChannelName[3] = LFE;
1512 device->ChannelName[4] = BackCenter;
1513 device->ChannelName[5] = SideLeft;
1514 device->ChannelName[6] = SideRight;
1515 break;
1516 case DevFmtX71:
1517 device->ChannelName[0] = FrontLeft;
1518 device->ChannelName[1] = FrontRight;
1519 device->ChannelName[2] = FrontCenter;
1520 device->ChannelName[3] = LFE;
1521 device->ChannelName[4] = BackLeft;
1522 device->ChannelName[5] = BackRight;
1523 device->ChannelName[6] = SideLeft;
1524 device->ChannelName[7] = SideRight;
1525 break;
1529 /* SetDefaultChannelOrder
1531 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1533 void SetDefaultChannelOrder(ALCdevice *device)
1535 ALuint i;
1537 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1538 device->ChannelName[i] = InvalidChannel;
1540 switch(device->FmtChans)
1542 case DevFmtX51Rear:
1543 device->ChannelName[0] = FrontLeft;
1544 device->ChannelName[1] = FrontRight;
1545 device->ChannelName[2] = BackLeft;
1546 device->ChannelName[3] = BackRight;
1547 device->ChannelName[4] = FrontCenter;
1548 device->ChannelName[5] = LFE;
1549 return;
1550 case DevFmtX71:
1551 device->ChannelName[0] = FrontLeft;
1552 device->ChannelName[1] = FrontRight;
1553 device->ChannelName[2] = BackLeft;
1554 device->ChannelName[3] = BackRight;
1555 device->ChannelName[4] = FrontCenter;
1556 device->ChannelName[5] = LFE;
1557 device->ChannelName[6] = SideLeft;
1558 device->ChannelName[7] = SideRight;
1559 return;
1561 /* Same as WFX order */
1562 case DevFmtMono:
1563 case DevFmtStereo:
1564 case DevFmtQuad:
1565 case DevFmtX51:
1566 case DevFmtX61:
1567 SetDefaultWFXChannelOrder(device);
1568 break;
1572 extern inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan);
1575 /* ALCcontext_DeferUpdates
1577 * Defers/suspends updates for the given context's listener and sources. This
1578 * does *NOT* stop mixing, but rather prevents certain property changes from
1579 * taking effect.
1581 void ALCcontext_DeferUpdates(ALCcontext *context)
1583 ALCdevice *device = context->Device;
1584 FPUCtl oldMode;
1586 SetMixerFPUMode(&oldMode);
1588 V0(device->Backend,lock)();
1589 if(!ExchangeInt(&context->DeferUpdates, AL_TRUE))
1591 ALboolean UpdateSources;
1592 ALvoice *voice, *voice_end;
1593 ALeffectslot **slot, **slot_end;
1594 /* Make sure all pending updates are performed */
1595 UpdateSources = ATOMIC_EXCHANGE(ALenum, &context->UpdateSources, AL_FALSE);
1597 voice = context->Voices;
1598 voice_end = voice + context->VoiceCount;
1599 while(voice != voice_end)
1601 ALsource *source = voice->Source;
1602 if(!source) goto next;
1604 if(source->state != AL_PLAYING && source->state != AL_PAUSED)
1606 voice->Source = NULL;
1607 goto next;
1610 if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || UpdateSources)
1611 voice->Update(voice, source, context);
1612 next:
1613 voice++;
1616 slot = VECTOR_ITER_BEGIN(context->ActiveAuxSlots);
1617 slot_end = VECTOR_ITER_END(context->ActiveAuxSlots);
1618 while(slot != slot_end)
1620 if(ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE))
1621 V((*slot)->EffectState,update)(context->Device, *slot);
1622 slot++;
1625 V0(device->Backend,unlock)();
1627 RestoreFPUMode(&oldMode);
1630 /* ALCcontext_ProcessUpdates
1632 * Resumes update processing after being deferred.
1634 void ALCcontext_ProcessUpdates(ALCcontext *context)
1636 ALCdevice *device = context->Device;
1638 V0(device->Backend,lock)();
1639 if(ExchangeInt(&context->DeferUpdates, AL_FALSE))
1641 ALsizei pos;
1643 LockUIntMapRead(&context->SourceMap);
1644 for(pos = 0;pos < context->SourceMap.size;pos++)
1646 ALsource *Source = context->SourceMap.array[pos].value;
1647 ALenum new_state;
1649 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1650 Source->Offset >= 0.0)
1652 ReadLock(&Source->queue_lock);
1653 ApplyOffset(Source);
1654 ReadUnlock(&Source->queue_lock);
1657 new_state = ExchangeInt(&Source->new_state, AL_NONE);
1658 if(new_state)
1659 SetSourceState(Source, context, new_state);
1661 UnlockUIntMapRead(&context->SourceMap);
1663 V0(device->Backend,unlock)();
1667 /* alcSetError
1669 * Stores the latest ALC device error
1671 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1673 if(TrapALCError)
1675 #ifdef _WIN32
1676 /* DebugBreak() will cause an exception if there is no debugger */
1677 if(IsDebuggerPresent())
1678 DebugBreak();
1679 #elif defined(SIGTRAP)
1680 raise(SIGTRAP);
1681 #endif
1684 if(device)
1685 ATOMIC_STORE(&device->LastError, errorCode);
1686 else
1687 ATOMIC_STORE(&LastNullDeviceError, errorCode);
1691 /* UpdateClockBase
1693 * Updates the device's base clock time with however many samples have been
1694 * done. This is used so frequency changes on the device don't cause the time
1695 * to jump forward or back.
1697 static inline void UpdateClockBase(ALCdevice *device)
1699 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1700 device->SamplesDone = 0;
1703 /* UpdateDeviceParams
1705 * Updates device parameters according to the attribute list (caller is
1706 * responsible for holding the list lock).
1708 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1710 ALCcontext *context;
1711 enum DevFmtChannels oldChans;
1712 enum DevFmtType oldType;
1713 ALCuint oldFreq;
1714 FPUCtl oldMode;
1716 // Check for attributes
1717 if(device->Type == Loopback)
1719 enum {
1720 GotFreq = 1<<0,
1721 GotChans = 1<<1,
1722 GotType = 1<<2,
1723 GotAll = GotFreq|GotChans|GotType
1725 ALCuint freq, numMono, numStereo, numSends, flags;
1726 enum DevFmtChannels schans;
1727 enum DevFmtType stype;
1728 ALCuint attrIdx = 0;
1729 ALCint gotFmt = 0;
1731 if(!attrList)
1733 WARN("Missing attributes for loopback device\n");
1734 return ALC_INVALID_VALUE;
1737 numMono = device->NumMonoSources;
1738 numStereo = device->NumStereoSources;
1739 numSends = device->NumAuxSends;
1740 schans = device->FmtChans;
1741 stype = device->FmtType;
1742 freq = device->Frequency;
1743 flags = device->Flags;
1745 while(attrList[attrIdx])
1747 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1749 ALCint val = attrList[attrIdx + 1];
1750 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1751 return ALC_INVALID_VALUE;
1752 schans = val;
1753 gotFmt |= GotChans;
1756 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1758 ALCint val = attrList[attrIdx + 1];
1759 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1760 return ALC_INVALID_VALUE;
1761 stype = val;
1762 gotFmt |= GotType;
1765 if(attrList[attrIdx] == ALC_FREQUENCY)
1767 freq = attrList[attrIdx + 1];
1768 if(freq < MIN_OUTPUT_RATE)
1769 return ALC_INVALID_VALUE;
1770 gotFmt |= GotFreq;
1773 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1775 numStereo = attrList[attrIdx + 1];
1776 if(numStereo > device->MaxNoOfSources)
1777 numStereo = device->MaxNoOfSources;
1779 numMono = device->MaxNoOfSources - numStereo;
1782 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1783 numSends = attrList[attrIdx + 1];
1785 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1787 if(attrList[attrIdx + 1] != ALC_FALSE)
1788 flags |= DEVICE_HRTF_REQUEST;
1789 else
1790 flags &= ~DEVICE_HRTF_REQUEST;
1793 attrIdx += 2;
1796 if(gotFmt != GotAll)
1798 WARN("Missing format for loopback device\n");
1799 return ALC_INVALID_VALUE;
1802 ConfigValueUInt(NULL, "sends", &numSends);
1803 numSends = minu(MAX_SENDS, numSends);
1805 if((device->Flags&DEVICE_RUNNING))
1806 V0(device->Backend,stop)();
1807 device->Flags = (flags & ~DEVICE_RUNNING);
1809 UpdateClockBase(device);
1811 device->Frequency = freq;
1812 device->FmtChans = schans;
1813 device->FmtType = stype;
1814 device->NumMonoSources = numMono;
1815 device->NumStereoSources = numStereo;
1816 device->NumAuxSends = numSends;
1818 else if(attrList && attrList[0])
1820 ALCuint freq, numMono, numStereo, numSends;
1821 ALCuint attrIdx = 0;
1823 /* If a context is already running on the device, stop playback so the
1824 * device attributes can be updated. */
1825 if((device->Flags&DEVICE_RUNNING))
1826 V0(device->Backend,stop)();
1827 device->Flags &= ~DEVICE_RUNNING;
1829 freq = device->Frequency;
1830 numMono = device->NumMonoSources;
1831 numStereo = device->NumStereoSources;
1832 numSends = device->NumAuxSends;
1834 while(attrList[attrIdx])
1836 if(attrList[attrIdx] == ALC_FREQUENCY)
1838 freq = attrList[attrIdx + 1];
1839 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1842 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1844 numStereo = attrList[attrIdx + 1];
1845 if(numStereo > device->MaxNoOfSources)
1846 numStereo = device->MaxNoOfSources;
1848 numMono = device->MaxNoOfSources - numStereo;
1851 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1852 numSends = attrList[attrIdx + 1];
1854 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1856 if(attrList[attrIdx + 1] != ALC_FALSE)
1857 device->Flags |= DEVICE_HRTF_REQUEST;
1858 else
1859 device->Flags &= ~DEVICE_HRTF_REQUEST;
1862 attrIdx += 2;
1865 ConfigValueUInt(NULL, "frequency", &freq);
1866 freq = maxu(freq, MIN_OUTPUT_RATE);
1868 ConfigValueUInt(NULL, "sends", &numSends);
1869 numSends = minu(MAX_SENDS, numSends);
1871 UpdateClockBase(device);
1873 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1874 device->Frequency;
1875 /* SSE and Neon do best with the update size being a multiple of 4 */
1876 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1877 device->UpdateSize = (device->UpdateSize+3)&~3;
1879 device->Frequency = freq;
1880 device->NumMonoSources = numMono;
1881 device->NumStereoSources = numStereo;
1882 device->NumAuxSends = numSends;
1885 if((device->Flags&DEVICE_RUNNING))
1886 return ALC_NO_ERROR;
1888 UpdateClockBase(device);
1890 if(device->Type != Loopback)
1892 bool usehrtf = !!(device->Flags&DEVICE_HRTF_REQUEST);
1893 if(GetConfigValueBool(NULL, "hrtf", usehrtf))
1894 device->Flags |= DEVICE_HRTF_REQUEST;
1895 else
1896 device->Flags &= ~DEVICE_HRTF_REQUEST;
1898 if((device->Flags&DEVICE_HRTF_REQUEST))
1900 enum DevFmtChannels chans = device->FmtChans;
1901 ALCuint freq = device->Frequency;
1902 if(FindHrtfFormat(&chans, &freq))
1904 if(device->Type != Loopback)
1906 device->Frequency = freq;
1907 device->FmtChans = chans;
1908 device->Flags |= DEVICE_CHANNELS_REQUEST |
1909 DEVICE_FREQUENCY_REQUEST;
1911 else if(device->Frequency != freq || device->FmtChans != chans)
1913 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1914 DevFmtChannelsString(device->FmtChans), device->Frequency);
1915 device->Flags &= ~DEVICE_HRTF_REQUEST;
1920 oldFreq = device->Frequency;
1921 oldChans = device->FmtChans;
1922 oldType = device->FmtType;
1924 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1925 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"",
1926 DevFmtChannelsString(device->FmtChans),
1927 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"",
1928 DevFmtTypeString(device->FmtType),
1929 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"",
1930 device->Frequency,
1931 device->UpdateSize, device->NumUpdates);
1933 if(V0(device->Backend,reset)() == ALC_FALSE)
1934 return ALC_INVALID_DEVICE;
1936 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1938 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1939 DevFmtChannelsString(device->FmtChans));
1940 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1942 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1944 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1945 DevFmtTypeString(device->FmtType));
1946 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1948 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1950 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1951 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1954 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1955 DevFmtChannelsString(device->FmtChans),
1956 DevFmtTypeString(device->FmtType), device->Frequency,
1957 device->UpdateSize, device->NumUpdates);
1959 device->Hrtf = NULL;
1960 if((device->Flags&DEVICE_HRTF_REQUEST))
1962 device->Hrtf = GetHrtf(device->FmtChans, device->Frequency);
1963 if(!device->Hrtf)
1964 device->Flags &= ~DEVICE_HRTF_REQUEST;
1966 TRACE("HRTF %s\n", device->Hrtf?"enabled":"disabled");
1968 if(!device->Hrtf && device->Bs2bLevel > 0 && device->Bs2bLevel <= 6 &&
1969 device->FmtChans == DevFmtStereo)
1971 if(!device->Bs2b)
1973 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
1974 bs2b_clear(device->Bs2b);
1976 bs2b_set_srate(device->Bs2b, device->Frequency);
1977 bs2b_set_level(device->Bs2b, device->Bs2bLevel);
1978 TRACE("BS2B level %d\n", device->Bs2bLevel);
1980 else
1982 free(device->Bs2b);
1983 device->Bs2b = NULL;
1984 TRACE("BS2B disabled\n");
1987 if(!device->Hrtf && (device->UpdateSize&3))
1989 if((CPUCapFlags&CPU_CAP_SSE))
1990 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1991 if((CPUCapFlags&CPU_CAP_NEON))
1992 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1995 aluInitPanning(device);
1997 al_free(device->DryBuffer);
1998 device->DryBuffer = al_calloc(16, sizeof(device->DryBuffer[0]) * device->NumChannels);
1999 if(!device->DryBuffer)
2001 ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", sizeof(device->DryBuffer[0]) * device->NumChannels);
2002 return ALC_INVALID_DEVICE;
2005 V(device->Synth,update)(device);
2007 SetMixerFPUMode(&oldMode);
2008 V0(device->Backend,lock)();
2009 context = ATOMIC_LOAD(&device->ContextList);
2010 while(context)
2012 ALsizei pos;
2014 ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2015 LockUIntMapRead(&context->EffectSlotMap);
2016 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2018 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2020 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2022 UnlockUIntMapRead(&context->EffectSlotMap);
2023 V0(device->Backend,unlock)();
2024 RestoreFPUMode(&oldMode);
2025 return ALC_INVALID_DEVICE;
2027 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2028 V(slot->EffectState,update)(device, slot);
2030 UnlockUIntMapRead(&context->EffectSlotMap);
2032 LockUIntMapRead(&context->SourceMap);
2033 for(pos = 0;pos < context->SourceMap.size;pos++)
2035 ALsource *source = context->SourceMap.array[pos].value;
2036 ALuint s = device->NumAuxSends;
2037 while(s < MAX_SENDS)
2039 if(source->Send[s].Slot)
2040 DecrementRef(&source->Send[s].Slot->ref);
2041 source->Send[s].Slot = NULL;
2042 source->Send[s].Gain = 1.0f;
2043 source->Send[s].GainHF = 1.0f;
2044 s++;
2046 ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2048 UnlockUIntMapRead(&context->SourceMap);
2050 for(pos = 0;pos < context->VoiceCount;pos++)
2052 ALvoice *voice = &context->Voices[pos];
2053 ALsource *source = voice->Source;
2054 ALuint s = device->NumAuxSends;
2056 while(s < MAX_SENDS)
2058 voice->Send[s].Moving = AL_FALSE;
2059 voice->Send[s].Counter = 0;
2060 s++;
2063 if(source)
2065 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2066 voice->Update(voice, source, context);
2070 context = context->next;
2072 if(device->DefaultSlot)
2074 ALeffectslot *slot = device->DefaultSlot;
2076 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2078 V0(device->Backend,unlock)();
2079 RestoreFPUMode(&oldMode);
2080 return ALC_INVALID_DEVICE;
2082 ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2083 V(slot->EffectState,update)(device, slot);
2085 V0(device->Backend,unlock)();
2086 RestoreFPUMode(&oldMode);
2088 if(!(device->Flags&DEVICE_PAUSED))
2090 if(V0(device->Backend,start)() == ALC_FALSE)
2091 return ALC_INVALID_DEVICE;
2092 device->Flags |= DEVICE_RUNNING;
2095 return ALC_NO_ERROR;
2098 /* FreeDevice
2100 * Frees the device structure, and destroys any objects the app failed to
2101 * delete. Called once there's no more references on the device.
2103 static ALCvoid FreeDevice(ALCdevice *device)
2105 TRACE("%p\n", device);
2107 V0(device->Backend,close)();
2108 DELETE_OBJ(device->Backend);
2109 device->Backend = NULL;
2111 DELETE_OBJ(device->Synth);
2112 device->Synth = NULL;
2114 if(device->DefaultSlot)
2116 ALeffectState *state = device->DefaultSlot->EffectState;
2117 device->DefaultSlot = NULL;
2118 DELETE_OBJ(state);
2121 if(device->DefaultSfont)
2122 ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
2123 device->DefaultSfont = NULL;
2125 if(device->BufferMap.size > 0)
2127 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2128 ReleaseALBuffers(device);
2130 ResetUIntMap(&device->BufferMap);
2132 if(device->EffectMap.size > 0)
2134 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2135 ReleaseALEffects(device);
2137 ResetUIntMap(&device->EffectMap);
2139 if(device->FilterMap.size > 0)
2141 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2142 ReleaseALFilters(device);
2144 ResetUIntMap(&device->FilterMap);
2146 if(device->SfontMap.size > 0)
2148 WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size);
2149 ReleaseALSoundfonts(device);
2151 ResetUIntMap(&device->SfontMap);
2153 if(device->PresetMap.size > 0)
2155 WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size);
2156 ReleaseALPresets(device);
2158 ResetUIntMap(&device->PresetMap);
2160 if(device->FontsoundMap.size > 0)
2162 WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size);
2163 ReleaseALFontsounds(device);
2165 ResetUIntMap(&device->FontsoundMap);
2167 free(device->Bs2b);
2168 device->Bs2b = NULL;
2170 AL_STRING_DEINIT(device->DeviceName);
2172 al_free(device->DryBuffer);
2173 device->DryBuffer = NULL;
2175 al_free(device);
2179 void ALCdevice_IncRef(ALCdevice *device)
2181 uint ref;
2182 ref = IncrementRef(&device->ref);
2183 TRACEREF("%p increasing refcount to %u\n", device, ref);
2186 void ALCdevice_DecRef(ALCdevice *device)
2188 uint ref;
2189 ref = DecrementRef(&device->ref);
2190 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2191 if(ref == 0) FreeDevice(device);
2194 /* VerifyDevice
2196 * Checks if the device handle is valid, and increments its ref count if so.
2198 static ALCdevice *VerifyDevice(ALCdevice *device)
2200 ALCdevice *tmpDevice;
2202 if(!device)
2203 return NULL;
2205 LockLists();
2206 tmpDevice = ATOMIC_LOAD(&DeviceList);
2207 while(tmpDevice && tmpDevice != device)
2208 tmpDevice = tmpDevice->next;
2210 if(tmpDevice)
2211 ALCdevice_IncRef(tmpDevice);
2212 UnlockLists();
2213 return tmpDevice;
2217 /* InitContext
2219 * Initializes context fields
2221 static ALvoid InitContext(ALCcontext *Context)
2223 ALint i, j;
2225 //Initialise listener
2226 Context->Listener->Gain = 1.0f;
2227 Context->Listener->MetersPerUnit = 1.0f;
2228 Context->Listener->Position[0] = 0.0f;
2229 Context->Listener->Position[1] = 0.0f;
2230 Context->Listener->Position[2] = 0.0f;
2231 Context->Listener->Velocity[0] = 0.0f;
2232 Context->Listener->Velocity[1] = 0.0f;
2233 Context->Listener->Velocity[2] = 0.0f;
2234 Context->Listener->Forward[0] = 0.0f;
2235 Context->Listener->Forward[1] = 0.0f;
2236 Context->Listener->Forward[2] = -1.0f;
2237 Context->Listener->Up[0] = 0.0f;
2238 Context->Listener->Up[1] = 1.0f;
2239 Context->Listener->Up[2] = 0.0f;
2240 for(i = 0;i < 4;i++)
2242 for(j = 0;j < 4;j++)
2243 Context->Listener->Params.Matrix[i][j] = ((i==j) ? 1.0f : 0.0f);
2245 for(i = 0;i < 3;i++)
2246 Context->Listener->Params.Velocity[i] = 0.0f;
2248 //Validate Context
2249 ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2250 ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2251 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2252 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2254 //Set globals
2255 Context->DistanceModel = DefaultDistanceModel;
2256 Context->SourceDistanceModel = AL_FALSE;
2257 Context->DopplerFactor = 1.0f;
2258 Context->DopplerVelocity = 1.0f;
2259 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2260 Context->DeferUpdates = AL_FALSE;
2262 Context->ExtensionList = alExtList;
2266 /* FreeContext
2268 * Cleans up the context, and destroys any remaining objects the app failed to
2269 * delete. Called once there's no more references on the context.
2271 static void FreeContext(ALCcontext *context)
2273 TRACE("%p\n", context);
2275 if(context->SourceMap.size > 0)
2277 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2278 ReleaseALSources(context);
2280 ResetUIntMap(&context->SourceMap);
2282 if(context->EffectSlotMap.size > 0)
2284 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2285 ReleaseALAuxiliaryEffectSlots(context);
2287 ResetUIntMap(&context->EffectSlotMap);
2289 al_free(context->Voices);
2290 context->Voices = NULL;
2291 context->VoiceCount = 0;
2292 context->MaxVoices = 0;
2294 VECTOR_DEINIT(context->ActiveAuxSlots);
2296 ALCdevice_DecRef(context->Device);
2297 context->Device = NULL;
2299 //Invalidate context
2300 memset(context, 0, sizeof(ALCcontext));
2301 al_free(context);
2304 /* ReleaseContext
2306 * Removes the context reference from the given device and removes it from
2307 * being current on the running thread or globally.
2309 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2311 ALCcontext *nextctx;
2312 ALCcontext *origctx;
2314 if(altss_get(LocalContext) == context)
2316 WARN("%p released while current on thread\n", context);
2317 altss_set(LocalContext, NULL);
2318 ALCcontext_DecRef(context);
2321 origctx = context;
2322 if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2323 ALCcontext_DecRef(context);
2325 ALCdevice_Lock(device);
2326 origctx = context;
2327 nextctx = context->next;
2328 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2330 ALCcontext *list;
2331 do {
2332 list = origctx;
2333 origctx = context;
2334 } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2336 ALCdevice_Unlock(device);
2338 ALCcontext_DecRef(context);
2341 void ALCcontext_IncRef(ALCcontext *context)
2343 uint ref;
2344 ref = IncrementRef(&context->ref);
2345 TRACEREF("%p increasing refcount to %u\n", context, ref);
2348 void ALCcontext_DecRef(ALCcontext *context)
2350 uint ref;
2351 ref = DecrementRef(&context->ref);
2352 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2353 if(ref == 0) FreeContext(context);
2356 static void ReleaseThreadCtx(void *ptr)
2358 WARN("%p current for thread being destroyed\n", ptr);
2359 ALCcontext_DecRef(ptr);
2362 /* VerifyContext
2364 * Checks that the given context is valid, and increments its reference count.
2366 static ALCcontext *VerifyContext(ALCcontext *context)
2368 ALCdevice *dev;
2370 LockLists();
2371 dev = ATOMIC_LOAD(&DeviceList);
2372 while(dev)
2374 ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2375 while(ctx)
2377 if(ctx == context)
2379 ALCcontext_IncRef(ctx);
2380 UnlockLists();
2381 return ctx;
2383 ctx = ctx->next;
2385 dev = dev->next;
2387 UnlockLists();
2389 return NULL;
2393 /* GetContextRef
2395 * Returns the currently active context for this thread, and adds a reference
2396 * without locking it.
2398 ALCcontext *GetContextRef(void)
2400 ALCcontext *context;
2402 context = altss_get(LocalContext);
2403 if(context)
2404 ALCcontext_IncRef(context);
2405 else
2407 LockLists();
2408 context = ATOMIC_LOAD(&GlobalContext);
2409 if(context)
2410 ALCcontext_IncRef(context);
2411 UnlockLists();
2414 return context;
2418 /************************************************
2419 * Standard ALC functions
2420 ************************************************/
2422 /* alcGetError
2424 * Return last ALC generated error code for the given device
2426 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2428 ALCenum errorCode;
2430 if(VerifyDevice(device))
2432 errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2433 ALCdevice_DecRef(device);
2435 else
2436 errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2438 return errorCode;
2442 /* alcSuspendContext
2444 * Suspends updates for the given context
2446 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2448 if(!SuspendDefers)
2449 return;
2451 context = VerifyContext(context);
2452 if(!context)
2453 alcSetError(NULL, ALC_INVALID_CONTEXT);
2454 else
2456 ALCcontext_DeferUpdates(context);
2457 ALCcontext_DecRef(context);
2461 /* alcProcessContext
2463 * Resumes processing updates for the given context
2465 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2467 if(!SuspendDefers)
2468 return;
2470 context = VerifyContext(context);
2471 if(!context)
2472 alcSetError(NULL, ALC_INVALID_CONTEXT);
2473 else
2475 ALCcontext_ProcessUpdates(context);
2476 ALCcontext_DecRef(context);
2481 /* alcGetString
2483 * Returns information about the device, and error strings
2485 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2487 const ALCchar *value = NULL;
2489 switch(param)
2491 case ALC_NO_ERROR:
2492 value = alcNoError;
2493 break;
2495 case ALC_INVALID_ENUM:
2496 value = alcErrInvalidEnum;
2497 break;
2499 case ALC_INVALID_VALUE:
2500 value = alcErrInvalidValue;
2501 break;
2503 case ALC_INVALID_DEVICE:
2504 value = alcErrInvalidDevice;
2505 break;
2507 case ALC_INVALID_CONTEXT:
2508 value = alcErrInvalidContext;
2509 break;
2511 case ALC_OUT_OF_MEMORY:
2512 value = alcErrOutOfMemory;
2513 break;
2515 case ALC_DEVICE_SPECIFIER:
2516 value = alcDefaultName;
2517 break;
2519 case ALC_ALL_DEVICES_SPECIFIER:
2520 if(VerifyDevice(Device))
2522 value = al_string_get_cstr(Device->DeviceName);
2523 ALCdevice_DecRef(Device);
2525 else
2527 ProbeAllDevicesList();
2528 value = al_string_get_cstr(alcAllDevicesList);
2530 break;
2532 case ALC_CAPTURE_DEVICE_SPECIFIER:
2533 if(VerifyDevice(Device))
2535 value = al_string_get_cstr(Device->DeviceName);
2536 ALCdevice_DecRef(Device);
2538 else
2540 ProbeCaptureDeviceList();
2541 value = al_string_get_cstr(alcCaptureDeviceList);
2543 break;
2545 /* Default devices are always first in the list */
2546 case ALC_DEFAULT_DEVICE_SPECIFIER:
2547 value = alcDefaultName;
2548 break;
2550 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2551 if(al_string_empty(alcAllDevicesList))
2552 ProbeAllDevicesList();
2554 Device = VerifyDevice(Device);
2556 free(alcDefaultAllDevicesSpecifier);
2557 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2558 if(!alcDefaultAllDevicesSpecifier)
2559 alcSetError(Device, ALC_OUT_OF_MEMORY);
2561 value = alcDefaultAllDevicesSpecifier;
2562 if(Device) ALCdevice_DecRef(Device);
2563 break;
2565 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2566 if(al_string_empty(alcCaptureDeviceList))
2567 ProbeCaptureDeviceList();
2569 Device = VerifyDevice(Device);
2571 free(alcCaptureDefaultDeviceSpecifier);
2572 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2573 if(!alcCaptureDefaultDeviceSpecifier)
2574 alcSetError(Device, ALC_OUT_OF_MEMORY);
2576 value = alcCaptureDefaultDeviceSpecifier;
2577 if(Device) ALCdevice_DecRef(Device);
2578 break;
2580 case ALC_EXTENSIONS:
2581 if(!VerifyDevice(Device))
2582 value = alcNoDeviceExtList;
2583 else
2585 value = alcExtensionList;
2586 ALCdevice_DecRef(Device);
2588 break;
2590 default:
2591 Device = VerifyDevice(Device);
2592 alcSetError(Device, ALC_INVALID_ENUM);
2593 if(Device) ALCdevice_DecRef(Device);
2594 break;
2597 return value;
2601 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2603 ALCsizei i;
2605 if(size <= 0 || values == NULL)
2607 alcSetError(device, ALC_INVALID_VALUE);
2608 return 0;
2611 if(!device)
2613 switch(param)
2615 case ALC_MAJOR_VERSION:
2616 values[0] = alcMajorVersion;
2617 return 1;
2618 case ALC_MINOR_VERSION:
2619 values[0] = alcMinorVersion;
2620 return 1;
2622 case ALC_ATTRIBUTES_SIZE:
2623 case ALC_ALL_ATTRIBUTES:
2624 case ALC_FREQUENCY:
2625 case ALC_REFRESH:
2626 case ALC_SYNC:
2627 case ALC_MONO_SOURCES:
2628 case ALC_STEREO_SOURCES:
2629 case ALC_CAPTURE_SAMPLES:
2630 case ALC_FORMAT_CHANNELS_SOFT:
2631 case ALC_FORMAT_TYPE_SOFT:
2632 alcSetError(NULL, ALC_INVALID_DEVICE);
2633 return 0;
2635 default:
2636 alcSetError(NULL, ALC_INVALID_ENUM);
2637 return 0;
2639 return 0;
2642 if(device->Type == Capture)
2644 switch(param)
2646 case ALC_CAPTURE_SAMPLES:
2647 ALCdevice_Lock(device);
2648 values[0] = V0(device->Backend,availableSamples)();
2649 ALCdevice_Unlock(device);
2650 return 1;
2652 case ALC_CONNECTED:
2653 values[0] = device->Connected;
2654 return 1;
2656 default:
2657 alcSetError(device, ALC_INVALID_ENUM);
2658 return 0;
2660 return 0;
2663 /* render device */
2664 switch(param)
2666 case ALC_MAJOR_VERSION:
2667 values[0] = alcMajorVersion;
2668 return 1;
2670 case ALC_MINOR_VERSION:
2671 values[0] = alcMinorVersion;
2672 return 1;
2674 case ALC_EFX_MAJOR_VERSION:
2675 values[0] = alcEFXMajorVersion;
2676 return 1;
2678 case ALC_EFX_MINOR_VERSION:
2679 values[0] = alcEFXMinorVersion;
2680 return 1;
2682 case ALC_ATTRIBUTES_SIZE:
2683 values[0] = 15;
2684 return 1;
2686 case ALC_ALL_ATTRIBUTES:
2687 if(size < 15)
2689 alcSetError(device, ALC_INVALID_VALUE);
2690 return 0;
2693 i = 0;
2694 values[i++] = ALC_FREQUENCY;
2695 values[i++] = device->Frequency;
2697 if(device->Type != Loopback)
2699 values[i++] = ALC_REFRESH;
2700 values[i++] = device->Frequency / device->UpdateSize;
2702 values[i++] = ALC_SYNC;
2703 values[i++] = ALC_FALSE;
2705 else
2707 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2708 values[i++] = device->FmtChans;
2710 values[i++] = ALC_FORMAT_TYPE_SOFT;
2711 values[i++] = device->FmtType;
2714 values[i++] = ALC_MONO_SOURCES;
2715 values[i++] = device->NumMonoSources;
2717 values[i++] = ALC_STEREO_SOURCES;
2718 values[i++] = device->NumStereoSources;
2720 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2721 values[i++] = device->NumAuxSends;
2723 values[i++] = ALC_HRTF_SOFT;
2724 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2726 values[i++] = 0;
2727 return i;
2729 case ALC_FREQUENCY:
2730 values[0] = device->Frequency;
2731 return 1;
2733 case ALC_REFRESH:
2734 if(device->Type == Loopback)
2736 alcSetError(device, ALC_INVALID_DEVICE);
2737 return 0;
2739 values[0] = device->Frequency / device->UpdateSize;
2740 return 1;
2742 case ALC_SYNC:
2743 if(device->Type == Loopback)
2745 alcSetError(device, ALC_INVALID_DEVICE);
2746 return 0;
2748 values[0] = ALC_FALSE;
2749 return 1;
2751 case ALC_FORMAT_CHANNELS_SOFT:
2752 if(device->Type != Loopback)
2754 alcSetError(device, ALC_INVALID_DEVICE);
2755 return 0;
2757 values[0] = device->FmtChans;
2758 return 1;
2760 case ALC_FORMAT_TYPE_SOFT:
2761 if(device->Type != Loopback)
2763 alcSetError(device, ALC_INVALID_DEVICE);
2764 return 0;
2766 values[0] = device->FmtType;
2767 return 1;
2769 case ALC_MONO_SOURCES:
2770 values[0] = device->NumMonoSources;
2771 return 1;
2773 case ALC_STEREO_SOURCES:
2774 values[0] = device->NumStereoSources;
2775 return 1;
2777 case ALC_MAX_AUXILIARY_SENDS:
2778 values[0] = device->NumAuxSends;
2779 return 1;
2781 case ALC_CONNECTED:
2782 values[0] = device->Connected;
2783 return 1;
2785 case ALC_HRTF_SOFT:
2786 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2787 return 1;
2789 default:
2790 alcSetError(device, ALC_INVALID_ENUM);
2791 return 0;
2793 return 0;
2796 /* alcGetIntegerv
2798 * Returns information about the device and the version of OpenAL
2800 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2802 device = VerifyDevice(device);
2803 if(size <= 0 || values == NULL)
2804 alcSetError(device, ALC_INVALID_VALUE);
2805 else
2806 GetIntegerv(device, param, size, values);
2807 if(device) ALCdevice_DecRef(device);
2810 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2812 ALCint *ivals;
2813 ALsizei i;
2815 device = VerifyDevice(device);
2816 if(size <= 0 || values == NULL)
2817 alcSetError(device, ALC_INVALID_VALUE);
2818 else if(!device || device->Type == Capture)
2820 ivals = malloc(size * sizeof(ALCint));
2821 size = GetIntegerv(device, pname, size, ivals);
2822 for(i = 0;i < size;i++)
2823 values[i] = ivals[i];
2824 free(ivals);
2826 else /* render device */
2828 switch(pname)
2830 case ALC_ATTRIBUTES_SIZE:
2831 *values = 17;
2832 break;
2834 case ALC_ALL_ATTRIBUTES:
2835 if(size < 17)
2836 alcSetError(device, ALC_INVALID_VALUE);
2837 else
2839 int i = 0;
2841 V0(device->Backend,lock)();
2842 values[i++] = ALC_FREQUENCY;
2843 values[i++] = device->Frequency;
2845 if(device->Type != Loopback)
2847 values[i++] = ALC_REFRESH;
2848 values[i++] = device->Frequency / device->UpdateSize;
2850 values[i++] = ALC_SYNC;
2851 values[i++] = ALC_FALSE;
2853 else
2855 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2856 values[i++] = device->FmtChans;
2858 values[i++] = ALC_FORMAT_TYPE_SOFT;
2859 values[i++] = device->FmtType;
2862 values[i++] = ALC_MONO_SOURCES;
2863 values[i++] = device->NumMonoSources;
2865 values[i++] = ALC_STEREO_SOURCES;
2866 values[i++] = device->NumStereoSources;
2868 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2869 values[i++] = device->NumAuxSends;
2871 values[i++] = ALC_HRTF_SOFT;
2872 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2874 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2875 values[i++] = device->ClockBase +
2876 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2878 values[i++] = 0;
2879 V0(device->Backend,unlock)();
2881 break;
2883 case ALC_DEVICE_CLOCK_SOFT:
2884 V0(device->Backend,lock)();
2885 *values = device->ClockBase +
2886 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2887 V0(device->Backend,unlock)();
2888 break;
2890 default:
2891 ivals = malloc(size * sizeof(ALCint));
2892 size = GetIntegerv(device, pname, size, ivals);
2893 for(i = 0;i < size;i++)
2894 values[i] = ivals[i];
2895 free(ivals);
2896 break;
2899 if(device)
2900 ALCdevice_DecRef(device);
2904 /* alcIsExtensionPresent
2906 * Determines if there is support for a particular extension
2908 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2910 ALCboolean bResult = ALC_FALSE;
2912 device = VerifyDevice(device);
2914 if(!extName)
2915 alcSetError(device, ALC_INVALID_VALUE);
2916 else
2918 size_t len = strlen(extName);
2919 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2920 while(ptr && *ptr)
2922 if(strncasecmp(ptr, extName, len) == 0 &&
2923 (ptr[len] == '\0' || isspace(ptr[len])))
2925 bResult = ALC_TRUE;
2926 break;
2928 if((ptr=strchr(ptr, ' ')) != NULL)
2930 do {
2931 ++ptr;
2932 } while(isspace(*ptr));
2936 if(device)
2937 ALCdevice_DecRef(device);
2938 return bResult;
2942 /* alcGetProcAddress
2944 * Retrieves the function address for a particular extension function
2946 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2948 ALCvoid *ptr = NULL;
2950 if(!funcName)
2952 device = VerifyDevice(device);
2953 alcSetError(device, ALC_INVALID_VALUE);
2954 if(device) ALCdevice_DecRef(device);
2956 else
2958 ALsizei i = 0;
2959 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
2960 i++;
2961 ptr = alcFunctions[i].address;
2964 return ptr;
2968 /* alcGetEnumValue
2970 * Get the value for a particular ALC enumeration name
2972 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
2974 ALCenum val = 0;
2976 if(!enumName)
2978 device = VerifyDevice(device);
2979 alcSetError(device, ALC_INVALID_VALUE);
2980 if(device) ALCdevice_DecRef(device);
2982 else
2984 ALsizei i = 0;
2985 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
2986 i++;
2987 val = enumeration[i].value;
2990 return val;
2994 /* alcCreateContext
2996 * Create and attach a context to the given device.
2998 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3000 ALCcontext *ALContext;
3001 ALCenum err;
3003 LockLists();
3004 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
3006 UnlockLists();
3007 alcSetError(device, ALC_INVALID_DEVICE);
3008 if(device) ALCdevice_DecRef(device);
3009 return NULL;
3012 ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3014 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3016 UnlockLists();
3017 alcSetError(device, err);
3018 if(err == ALC_INVALID_DEVICE)
3020 ALCdevice_Lock(device);
3021 aluHandleDisconnect(device);
3022 ALCdevice_Unlock(device);
3024 ALCdevice_DecRef(device);
3025 return NULL;
3028 ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3029 if(ALContext)
3031 InitRef(&ALContext->ref, 1);
3032 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3034 VECTOR_INIT(ALContext->ActiveAuxSlots);
3036 ALContext->VoiceCount = 0;
3037 ALContext->MaxVoices = 256;
3038 ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3040 if(!ALContext || !ALContext->Voices)
3042 if(!ATOMIC_LOAD(&device->ContextList))
3044 V0(device->Backend,stop)();
3045 device->Flags &= ~DEVICE_RUNNING;
3047 UnlockLists();
3049 if(ALContext)
3051 al_free(ALContext->Voices);
3052 ALContext->Voices = NULL;
3054 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3056 al_free(ALContext);
3057 ALContext = NULL;
3060 alcSetError(device, ALC_OUT_OF_MEMORY);
3061 ALCdevice_DecRef(device);
3062 return NULL;
3065 ALContext->Device = device;
3066 ALCdevice_IncRef(device);
3067 InitContext(ALContext);
3070 ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3071 do {
3072 ALContext->next = head;
3073 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3075 UnlockLists();
3077 ALCdevice_DecRef(device);
3079 TRACE("Created context %p\n", ALContext);
3080 return ALContext;
3083 /* alcDestroyContext
3085 * Remove a context from its device
3087 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3089 ALCdevice *Device;
3091 LockLists();
3092 /* alcGetContextsDevice sets an error for invalid contexts */
3093 Device = alcGetContextsDevice(context);
3094 if(Device)
3096 ReleaseContext(context, Device);
3097 if(!ATOMIC_LOAD(&Device->ContextList))
3099 V0(Device->Backend,stop)();
3100 Device->Flags &= ~DEVICE_RUNNING;
3103 UnlockLists();
3107 /* alcGetCurrentContext
3109 * Returns the currently active context on the calling thread
3111 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3113 ALCcontext *Context = altss_get(LocalContext);
3114 if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3115 return Context;
3118 /* alcGetThreadContext
3120 * Returns the currently active thread-local context
3122 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3124 return altss_get(LocalContext);
3128 /* alcMakeContextCurrent
3130 * Makes the given context the active process-wide context, and removes the
3131 * thread-local context for the calling thread.
3133 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3135 /* context must be valid or NULL */
3136 if(context && !(context=VerifyContext(context)))
3138 alcSetError(NULL, ALC_INVALID_CONTEXT);
3139 return ALC_FALSE;
3141 /* context's reference count is already incremented */
3142 context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3143 if(context) ALCcontext_DecRef(context);
3145 if((context=altss_get(LocalContext)) != NULL)
3147 altss_set(LocalContext, NULL);
3148 ALCcontext_DecRef(context);
3151 return ALC_TRUE;
3154 /* alcSetThreadContext
3156 * Makes the given context the active context for the current thread
3158 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3160 ALCcontext *old;
3162 /* context must be valid or NULL */
3163 if(context && !(context=VerifyContext(context)))
3165 alcSetError(NULL, ALC_INVALID_CONTEXT);
3166 return ALC_FALSE;
3168 /* context's reference count is already incremented */
3169 old = altss_get(LocalContext);
3170 altss_set(LocalContext, context);
3171 if(old) ALCcontext_DecRef(old);
3173 return ALC_TRUE;
3177 /* alcGetContextsDevice
3179 * Returns the device that a particular context is attached to
3181 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3183 ALCdevice *Device;
3185 if(!(Context=VerifyContext(Context)))
3187 alcSetError(NULL, ALC_INVALID_CONTEXT);
3188 return NULL;
3190 Device = Context->Device;
3191 ALCcontext_DecRef(Context);
3193 return Device;
3197 /* alcOpenDevice
3199 * Opens the named device.
3201 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3203 const ALCchar *fmt;
3204 ALCdevice *device;
3205 ALCenum err;
3207 DO_INITCONFIG();
3209 if(!PlaybackBackend.name)
3211 alcSetError(NULL, ALC_INVALID_VALUE);
3212 return NULL;
3215 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3216 deviceName = NULL;
3218 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3219 if(!device)
3221 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3222 return NULL;
3225 //Validate device
3226 InitRef(&device->ref, 1);
3227 device->Connected = ALC_TRUE;
3228 device->Type = Playback;
3229 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3231 device->Flags = 0;
3232 device->Bs2b = NULL;
3233 device->Bs2bLevel = 0;
3234 AL_STRING_INIT(device->DeviceName);
3235 device->DryBuffer = NULL;
3237 ATOMIC_INIT(&device->ContextList, NULL);
3239 device->ClockBase = 0;
3240 device->SamplesDone = 0;
3242 device->MaxNoOfSources = 256;
3243 device->AuxiliaryEffectSlotMax = 4;
3244 device->NumAuxSends = MAX_SENDS;
3246 InitUIntMap(&device->BufferMap, ~0);
3247 InitUIntMap(&device->EffectMap, ~0);
3248 InitUIntMap(&device->FilterMap, ~0);
3249 InitUIntMap(&device->SfontMap, ~0);
3250 InitUIntMap(&device->PresetMap, ~0);
3251 InitUIntMap(&device->FontsoundMap, ~0);
3253 //Set output format
3254 device->FmtChans = DevFmtChannelsDefault;
3255 device->FmtType = DevFmtTypeDefault;
3256 device->Frequency = DEFAULT_OUTPUT_RATE;
3257 device->NumUpdates = 4;
3258 device->UpdateSize = 1024;
3260 if(!PlaybackBackend.getFactory)
3261 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3262 ALCbackend_Playback);
3263 else
3265 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3266 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3268 if(!device->Backend)
3270 al_free(device);
3271 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3272 return NULL;
3276 if(ConfigValueStr(NULL, "channels", &fmt))
3278 static const struct {
3279 const char name[16];
3280 enum DevFmtChannels chans;
3281 } chanlist[] = {
3282 { "mono", DevFmtMono },
3283 { "stereo", DevFmtStereo },
3284 { "quad", DevFmtQuad },
3285 { "surround51", DevFmtX51 },
3286 { "surround61", DevFmtX61 },
3287 { "surround71", DevFmtX71 },
3288 { "surround51rear", DevFmtX51Rear },
3290 size_t i;
3292 for(i = 0;i < COUNTOF(chanlist);i++)
3294 if(strcasecmp(chanlist[i].name, fmt) == 0)
3296 device->FmtChans = chanlist[i].chans;
3297 device->Flags |= DEVICE_CHANNELS_REQUEST;
3298 break;
3301 if(i == COUNTOF(chanlist))
3302 ERR("Unsupported channels: %s\n", fmt);
3304 if(ConfigValueStr(NULL, "sample-type", &fmt))
3306 static const struct {
3307 const char name[16];
3308 enum DevFmtType type;
3309 } typelist[] = {
3310 { "int8", DevFmtByte },
3311 { "uint8", DevFmtUByte },
3312 { "int16", DevFmtShort },
3313 { "uint16", DevFmtUShort },
3314 { "int32", DevFmtInt },
3315 { "uint32", DevFmtUInt },
3316 { "float32", DevFmtFloat },
3318 size_t i;
3320 for(i = 0;i < COUNTOF(typelist);i++)
3322 if(strcasecmp(typelist[i].name, fmt) == 0)
3324 device->FmtType = typelist[i].type;
3325 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3326 break;
3329 if(i == COUNTOF(typelist))
3330 ERR("Unsupported sample-type: %s\n", fmt);
3333 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
3335 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3336 if(device->Frequency < MIN_OUTPUT_RATE)
3337 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3338 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3341 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
3342 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3344 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
3345 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3346 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3347 device->UpdateSize = (device->UpdateSize+3)&~3;
3349 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3350 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3352 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3353 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3355 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3356 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3358 ConfigValueInt(NULL, "cf_level", &device->Bs2bLevel);
3360 device->NumStereoSources = 1;
3361 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3363 device->Synth = SynthCreate(device);
3364 if(!device->Synth)
3366 DELETE_OBJ(device->Backend);
3367 al_free(device);
3368 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3369 return NULL;
3372 // Find a playback device to open
3373 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3375 DELETE_OBJ(device->Synth);
3376 DELETE_OBJ(device->Backend);
3377 al_free(device);
3378 alcSetError(NULL, err);
3379 return NULL;
3382 if(DefaultEffect.type != AL_EFFECT_NULL)
3384 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3385 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3387 device->DefaultSlot = NULL;
3388 ERR("Failed to initialize the default effect slot\n");
3390 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3392 ALeffectState *state = device->DefaultSlot->EffectState;
3393 device->DefaultSlot = NULL;
3394 DELETE_OBJ(state);
3395 ERR("Failed to initialize the default effect\n");
3400 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3401 do {
3402 device->next = head;
3403 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3406 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3407 return device;
3410 /* alcCloseDevice
3412 * Closes the given device.
3414 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3416 ALCdevice *list, *origdev, *nextdev;
3417 ALCcontext *ctx;
3419 LockLists();
3420 list = ATOMIC_LOAD(&DeviceList);
3421 do {
3422 if(list == device)
3423 break;
3424 } while((list=list->next) != NULL);
3425 if(!list || list->Type == Capture)
3427 alcSetError(list, ALC_INVALID_DEVICE);
3428 UnlockLists();
3429 return ALC_FALSE;
3432 origdev = device;
3433 nextdev = device->next;
3434 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3436 do {
3437 list = origdev;
3438 origdev = device;
3439 } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3441 UnlockLists();
3443 ctx = ATOMIC_LOAD(&device->ContextList);
3444 while(ctx != NULL)
3446 ALCcontext *next = ctx->next;
3447 WARN("Releasing context %p\n", ctx);
3448 ReleaseContext(ctx, device);
3449 ctx = next;
3451 if((device->Flags&DEVICE_RUNNING))
3452 V0(device->Backend,stop)();
3453 device->Flags &= ~DEVICE_RUNNING;
3455 ALCdevice_DecRef(device);
3457 return ALC_TRUE;
3461 /************************************************
3462 * ALC capture functions
3463 ************************************************/
3464 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3466 ALCdevice *device = NULL;
3467 ALCenum err;
3469 DO_INITCONFIG();
3471 if(!CaptureBackend.name)
3473 alcSetError(NULL, ALC_INVALID_VALUE);
3474 return NULL;
3477 if(samples <= 0)
3479 alcSetError(NULL, ALC_INVALID_VALUE);
3480 return NULL;
3483 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3484 deviceName = NULL;
3486 device = al_calloc(16, sizeof(ALCdevice));
3487 if(!device)
3489 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3490 return NULL;
3493 //Validate device
3494 InitRef(&device->ref, 1);
3495 device->Connected = ALC_TRUE;
3496 device->Type = Capture;
3498 AL_STRING_INIT(device->DeviceName);
3499 device->DryBuffer = NULL;
3501 InitUIntMap(&device->BufferMap, ~0);
3502 InitUIntMap(&device->EffectMap, ~0);
3503 InitUIntMap(&device->FilterMap, ~0);
3504 InitUIntMap(&device->SfontMap, ~0);
3505 InitUIntMap(&device->PresetMap, ~0);
3506 InitUIntMap(&device->FontsoundMap, ~0);
3508 if(!CaptureBackend.getFactory)
3509 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3510 ALCbackend_Capture);
3511 else
3513 ALCbackendFactory *factory = CaptureBackend.getFactory();
3514 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3516 if(!device->Backend)
3518 al_free(device);
3519 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3520 return NULL;
3523 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3524 device->Frequency = frequency;
3526 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3527 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3529 al_free(device);
3530 alcSetError(NULL, ALC_INVALID_ENUM);
3531 return NULL;
3534 device->UpdateSize = samples;
3535 device->NumUpdates = 1;
3537 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3539 al_free(device);
3540 alcSetError(NULL, err);
3541 return NULL;
3545 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3546 do {
3547 device->next = head;
3548 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3551 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3552 return device;
3555 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3557 ALCdevice *list, *next, *nextdev;
3559 LockLists();
3560 list = ATOMIC_LOAD(&DeviceList);
3561 do {
3562 if(list == device)
3563 break;
3564 } while((list=list->next) != NULL);
3565 if(!list || list->Type != Capture)
3567 alcSetError(list, ALC_INVALID_DEVICE);
3568 UnlockLists();
3569 return ALC_FALSE;
3572 next = device;
3573 nextdev = device->next;
3574 if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3576 do {
3577 list = next;
3578 next = device;
3579 } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3581 UnlockLists();
3583 ALCdevice_DecRef(device);
3585 return ALC_TRUE;
3588 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3590 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3591 alcSetError(device, ALC_INVALID_DEVICE);
3592 else
3594 ALCdevice_Lock(device);
3595 if(device->Connected)
3597 if(!(device->Flags&DEVICE_RUNNING))
3598 V0(device->Backend,start)();
3599 device->Flags |= DEVICE_RUNNING;
3601 ALCdevice_Unlock(device);
3604 if(device) ALCdevice_DecRef(device);
3607 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3609 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3610 alcSetError(device, ALC_INVALID_DEVICE);
3611 else
3613 ALCdevice_Lock(device);
3614 if((device->Flags&DEVICE_RUNNING))
3615 V0(device->Backend,stop)();
3616 device->Flags &= ~DEVICE_RUNNING;
3617 ALCdevice_Unlock(device);
3620 if(device) ALCdevice_DecRef(device);
3623 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3625 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3626 alcSetError(device, ALC_INVALID_DEVICE);
3627 else
3629 ALCenum err = ALC_INVALID_VALUE;
3631 ALCdevice_Lock(device);
3632 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3633 err = V(device->Backend,captureSamples)(buffer, samples);
3634 ALCdevice_Unlock(device);
3636 if(err != ALC_NO_ERROR)
3637 alcSetError(device, err);
3639 if(device) ALCdevice_DecRef(device);
3643 /************************************************
3644 * ALC loopback functions
3645 ************************************************/
3647 /* alcLoopbackOpenDeviceSOFT
3649 * Open a loopback device, for manual rendering.
3651 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3653 ALCbackendFactory *factory;
3654 ALCdevice *device;
3656 DO_INITCONFIG();
3658 /* Make sure the device name, if specified, is us. */
3659 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3661 alcSetError(NULL, ALC_INVALID_VALUE);
3662 return NULL;
3665 device = al_calloc(16, sizeof(ALCdevice));
3666 if(!device)
3668 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3669 return NULL;
3672 //Validate device
3673 InitRef(&device->ref, 1);
3674 device->Connected = ALC_TRUE;
3675 device->Type = Loopback;
3676 ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3678 device->Flags = 0;
3679 device->Bs2b = NULL;
3680 device->Bs2bLevel = 0;
3681 AL_STRING_INIT(device->DeviceName);
3682 device->DryBuffer = NULL;
3684 ATOMIC_INIT(&device->ContextList, NULL);
3686 device->ClockBase = 0;
3687 device->SamplesDone = 0;
3689 device->MaxNoOfSources = 256;
3690 device->AuxiliaryEffectSlotMax = 4;
3691 device->NumAuxSends = MAX_SENDS;
3693 InitUIntMap(&device->BufferMap, ~0);
3694 InitUIntMap(&device->EffectMap, ~0);
3695 InitUIntMap(&device->FilterMap, ~0);
3696 InitUIntMap(&device->SfontMap, ~0);
3697 InitUIntMap(&device->PresetMap, ~0);
3698 InitUIntMap(&device->FontsoundMap, ~0);
3700 factory = ALCloopbackFactory_getFactory();
3701 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3702 if(!device->Backend)
3704 al_free(device);
3705 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3706 return NULL;
3709 //Set output format
3710 device->NumUpdates = 0;
3711 device->UpdateSize = 0;
3713 device->Frequency = DEFAULT_OUTPUT_RATE;
3714 device->FmtChans = DevFmtChannelsDefault;
3715 device->FmtType = DevFmtTypeDefault;
3717 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3718 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3720 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3721 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3723 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3724 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3726 device->NumStereoSources = 1;
3727 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3729 device->Synth = SynthCreate(device);
3730 if(!device->Synth)
3732 DELETE_OBJ(device->Backend);
3733 al_free(device);
3734 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3735 return NULL;
3738 // Open the "backend"
3739 V(device->Backend,open)("Loopback");
3742 ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3743 do {
3744 device->next = head;
3745 } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3748 TRACE("Created device %p\n", device);
3749 return device;
3752 /* alcIsRenderFormatSupportedSOFT
3754 * Determines if the loopback device supports the given format for rendering.
3756 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3758 ALCboolean ret = ALC_FALSE;
3760 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3761 alcSetError(device, ALC_INVALID_DEVICE);
3762 else if(freq <= 0)
3763 alcSetError(device, ALC_INVALID_VALUE);
3764 else
3766 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3767 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3768 freq >= MIN_OUTPUT_RATE)
3769 ret = ALC_TRUE;
3771 if(device) ALCdevice_DecRef(device);
3773 return ret;
3776 /* alcRenderSamplesSOFT
3778 * Renders some samples into a buffer, using the format last set by the
3779 * attributes given to alcCreateContext.
3781 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3783 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3784 alcSetError(device, ALC_INVALID_DEVICE);
3785 else if(samples < 0 || (samples > 0 && buffer == NULL))
3786 alcSetError(device, ALC_INVALID_VALUE);
3787 else
3788 aluMixData(device, buffer, samples);
3789 if(device) ALCdevice_DecRef(device);
3793 /************************************************
3794 * ALC DSP pause/resume functions
3795 ************************************************/
3797 /* alcDevicePauseSOFT
3799 * Pause the DSP to stop audio processing.
3801 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3803 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3804 alcSetError(device, ALC_INVALID_DEVICE);
3805 else
3807 LockLists();
3808 if((device->Flags&DEVICE_RUNNING))
3809 V0(device->Backend,stop)();
3810 device->Flags &= ~DEVICE_RUNNING;
3811 device->Flags |= DEVICE_PAUSED;
3812 UnlockLists();
3814 if(device) ALCdevice_DecRef(device);
3817 /* alcDeviceResumeSOFT
3819 * Resume the DSP to restart audio processing.
3821 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3823 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3824 alcSetError(device, ALC_INVALID_DEVICE);
3825 else
3827 LockLists();
3828 if((device->Flags&DEVICE_PAUSED))
3830 device->Flags &= ~DEVICE_PAUSED;
3831 if(ATOMIC_LOAD(&device->ContextList) != NULL)
3833 if(V0(device->Backend,start)() != ALC_FALSE)
3834 device->Flags |= DEVICE_RUNNING;
3835 else
3837 alcSetError(device, ALC_INVALID_DEVICE);
3838 ALCdevice_Lock(device);
3839 aluHandleDisconnect(device);
3840 ALCdevice_Unlock(device);
3844 UnlockLists();
3846 if(device) ALCdevice_DecRef(device);