Added support of AL_LOOP_COUNT Source parameter
[platform/upstream/openal-soft.git] / Alc / ALc.c
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.
8  *
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.
13  *
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
19  */
20
21 #include "config.h"
22
23 #include <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include <ctype.h>
28 #include <signal.h>
29
30 #include "alMain.h"
31 #include "alSource.h"
32 #include "alListener.h"
33 #include "alThunk.h"
34 #include "alSource.h"
35 #include "alBuffer.h"
36 #include "alAuxEffectSlot.h"
37 #include "alError.h"
38 #include "bs2b.h"
39 #include "alu.h"
40
41 #include "compat.h"
42 #include "threads.h"
43 #include "alstring.h"
44
45 #include "backends/base.h"
46
47
48 /************************************************
49  * Backends
50  ************************************************/
51 struct BackendInfo {
52     const char *name;
53     ALCbackendFactory* (*getFactory)(void);
54     ALCboolean (*Init)(BackendFuncs*);
55     void (*Deinit)(void);
56     void (*Probe)(enum DevProbe);
57     BackendFuncs Funcs;
58 };
59
60 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
61 static struct BackendInfo BackendList[] = {
62 #ifdef HAVE_JACK
63     { "jack", ALCjackBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
64 #endif
65 #ifdef HAVE_PULSEAUDIO
66     { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
67 #endif
68 #ifdef HAVE_ALSA
69     { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
70 #endif
71 #ifdef HAVE_COREAUDIO
72     { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
73 #endif
74 #ifdef HAVE_OSS
75     { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
76 #endif
77 #ifdef HAVE_SOLARIS
78     { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
79 #endif
80 #ifdef HAVE_SNDIO
81     { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
82 #endif
83 #ifdef HAVE_QSA
84     { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
85 #endif
86 #ifdef HAVE_MMDEVAPI
87     { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
88 #endif
89 #ifdef HAVE_DSOUND
90     { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
91 #endif
92 #ifdef HAVE_WINMM
93     { "winmm", ALCwinmmBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
94 #endif
95 #ifdef HAVE_PORTAUDIO
96     { "port", ALCportBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
97 #endif
98 #ifdef HAVE_OPENSL
99     { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
100 #endif
101
102     { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
103 #ifdef HAVE_WAVE
104     { "wave", ALCwaveBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
105 #endif
106
107     { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
108 };
109 #undef EmptyFuncs
110
111 static struct BackendInfo PlaybackBackend;
112 static struct BackendInfo CaptureBackend;
113
114
115 /************************************************
116  * Functions, enums, and errors
117  ************************************************/
118 typedef struct ALCfunction {
119     const ALCchar *funcName;
120     ALCvoid *address;
121 } ALCfunction;
122
123 typedef struct ALCenums {
124     const ALCchar *enumName;
125     ALCenum value;
126 } ALCenums;
127
128 #define DECL(x) { #x, (ALCvoid*)(x) }
129 static const ALCfunction alcFunctions[] = {
130     DECL(alcCreateContext),
131     DECL(alcMakeContextCurrent),
132     DECL(alcProcessContext),
133     DECL(alcSuspendContext),
134     DECL(alcDestroyContext),
135     DECL(alcGetCurrentContext),
136     DECL(alcGetContextsDevice),
137     DECL(alcOpenDevice),
138     DECL(alcCloseDevice),
139     DECL(alcGetError),
140     DECL(alcIsExtensionPresent),
141     DECL(alcGetProcAddress),
142     DECL(alcGetEnumValue),
143     DECL(alcGetString),
144     DECL(alcGetIntegerv),
145     DECL(alcCaptureOpenDevice),
146     DECL(alcCaptureCloseDevice),
147     DECL(alcCaptureStart),
148     DECL(alcCaptureStop),
149     DECL(alcCaptureSamples),
150
151     DECL(alcSetThreadContext),
152     DECL(alcGetThreadContext),
153
154     DECL(alcLoopbackOpenDeviceSOFT),
155     DECL(alcIsRenderFormatSupportedSOFT),
156     DECL(alcRenderSamplesSOFT),
157
158     DECL(alcDevicePauseSOFT),
159     DECL(alcDeviceResumeSOFT),
160
161     DECL(alcGetStringiSOFT),
162     DECL(alcResetDeviceSOFT),
163
164     DECL(alcGetInteger64vSOFT),
165
166     DECL(alEnable),
167     DECL(alDisable),
168     DECL(alIsEnabled),
169     DECL(alGetString),
170     DECL(alGetBooleanv),
171     DECL(alGetIntegerv),
172     DECL(alGetFloatv),
173     DECL(alGetDoublev),
174     DECL(alGetBoolean),
175     DECL(alGetInteger),
176     DECL(alGetFloat),
177     DECL(alGetDouble),
178     DECL(alGetError),
179     DECL(alIsExtensionPresent),
180     DECL(alGetProcAddress),
181     DECL(alGetEnumValue),
182     DECL(alListenerf),
183     DECL(alListener3f),
184     DECL(alListenerfv),
185     DECL(alListeneri),
186     DECL(alListener3i),
187     DECL(alListeneriv),
188     DECL(alGetListenerf),
189     DECL(alGetListener3f),
190     DECL(alGetListenerfv),
191     DECL(alGetListeneri),
192     DECL(alGetListener3i),
193     DECL(alGetListeneriv),
194     DECL(alGenSources),
195     DECL(alDeleteSources),
196     DECL(alIsSource),
197     DECL(alSourcef),
198     DECL(alSource3f),
199     DECL(alSourcefv),
200     DECL(alSourcei),
201     DECL(alSource3i),
202     DECL(alSourceiv),
203     DECL(alGetSourcef),
204     DECL(alGetSource3f),
205     DECL(alGetSourcefv),
206     DECL(alGetSourcei),
207     DECL(alGetSource3i),
208     DECL(alGetSourceiv),
209     DECL(alSourcePlayv),
210     DECL(alSourceStopv),
211     DECL(alSourceRewindv),
212     DECL(alSourcePausev),
213     DECL(alSourcePlay),
214     DECL(alSourceStop),
215     DECL(alSourceRewind),
216     DECL(alSourcePause),
217     DECL(alSourceQueueBuffers),
218     DECL(alSourceUnqueueBuffers),
219     DECL(alGenBuffers),
220     DECL(alDeleteBuffers),
221     DECL(alIsBuffer),
222     DECL(alBufferData),
223     DECL(alBufferf),
224     DECL(alBuffer3f),
225     DECL(alBufferfv),
226     DECL(alBufferi),
227     DECL(alBuffer3i),
228     DECL(alBufferiv),
229     DECL(alGetBufferf),
230     DECL(alGetBuffer3f),
231     DECL(alGetBufferfv),
232     DECL(alGetBufferi),
233     DECL(alGetBuffer3i),
234     DECL(alGetBufferiv),
235     DECL(alDopplerFactor),
236     DECL(alDopplerVelocity),
237     DECL(alSpeedOfSound),
238     DECL(alDistanceModel),
239
240     DECL(alGenFilters),
241     DECL(alDeleteFilters),
242     DECL(alIsFilter),
243     DECL(alFilteri),
244     DECL(alFilteriv),
245     DECL(alFilterf),
246     DECL(alFilterfv),
247     DECL(alGetFilteri),
248     DECL(alGetFilteriv),
249     DECL(alGetFilterf),
250     DECL(alGetFilterfv),
251     DECL(alGenEffects),
252     DECL(alDeleteEffects),
253     DECL(alIsEffect),
254     DECL(alEffecti),
255     DECL(alEffectiv),
256     DECL(alEffectf),
257     DECL(alEffectfv),
258     DECL(alGetEffecti),
259     DECL(alGetEffectiv),
260     DECL(alGetEffectf),
261     DECL(alGetEffectfv),
262     DECL(alGenAuxiliaryEffectSlots),
263     DECL(alDeleteAuxiliaryEffectSlots),
264     DECL(alIsAuxiliaryEffectSlot),
265     DECL(alAuxiliaryEffectSloti),
266     DECL(alAuxiliaryEffectSlotiv),
267     DECL(alAuxiliaryEffectSlotf),
268     DECL(alAuxiliaryEffectSlotfv),
269     DECL(alGetAuxiliaryEffectSloti),
270     DECL(alGetAuxiliaryEffectSlotiv),
271     DECL(alGetAuxiliaryEffectSlotf),
272     DECL(alGetAuxiliaryEffectSlotfv),
273
274     DECL(alBufferSubDataSOFT),
275
276     DECL(alBufferSamplesSOFT),
277     DECL(alBufferSubSamplesSOFT),
278     DECL(alGetBufferSamplesSOFT),
279     DECL(alIsBufferFormatSupportedSOFT),
280
281     DECL(alDeferUpdatesSOFT),
282     DECL(alProcessUpdatesSOFT),
283
284     DECL(alSourcedSOFT),
285     DECL(alSource3dSOFT),
286     DECL(alSourcedvSOFT),
287     DECL(alGetSourcedSOFT),
288     DECL(alGetSource3dSOFT),
289     DECL(alGetSourcedvSOFT),
290     DECL(alSourcei64SOFT),
291     DECL(alSource3i64SOFT),
292     DECL(alSourcei64vSOFT),
293     DECL(alGetSourcei64SOFT),
294     DECL(alGetSource3i64SOFT),
295     DECL(alGetSourcei64vSOFT),
296
297     { NULL, NULL }
298 };
299 #undef DECL
300
301 #define DECL(x) { #x, (x) }
302 static const ALCenums enumeration[] = {
303     DECL(ALC_INVALID),
304     DECL(ALC_FALSE),
305     DECL(ALC_TRUE),
306
307     DECL(ALC_MAJOR_VERSION),
308     DECL(ALC_MINOR_VERSION),
309     DECL(ALC_ATTRIBUTES_SIZE),
310     DECL(ALC_ALL_ATTRIBUTES),
311     DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
312     DECL(ALC_DEVICE_SPECIFIER),
313     DECL(ALC_ALL_DEVICES_SPECIFIER),
314     DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
315     DECL(ALC_EXTENSIONS),
316     DECL(ALC_FREQUENCY),
317     DECL(ALC_REFRESH),
318     DECL(ALC_SYNC),
319     DECL(ALC_MONO_SOURCES),
320     DECL(ALC_STEREO_SOURCES),
321     DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
322     DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
323     DECL(ALC_CAPTURE_SAMPLES),
324     DECL(ALC_CONNECTED),
325
326     DECL(ALC_EFX_MAJOR_VERSION),
327     DECL(ALC_EFX_MINOR_VERSION),
328     DECL(ALC_MAX_AUXILIARY_SENDS),
329
330     DECL(ALC_FORMAT_CHANNELS_SOFT),
331     DECL(ALC_FORMAT_TYPE_SOFT),
332
333     DECL(ALC_MONO_SOFT),
334     DECL(ALC_STEREO_SOFT),
335     DECL(ALC_QUAD_SOFT),
336     DECL(ALC_5POINT1_SOFT),
337     DECL(ALC_6POINT1_SOFT),
338     DECL(ALC_7POINT1_SOFT),
339
340     DECL(ALC_BYTE_SOFT),
341     DECL(ALC_UNSIGNED_BYTE_SOFT),
342     DECL(ALC_SHORT_SOFT),
343     DECL(ALC_UNSIGNED_SHORT_SOFT),
344     DECL(ALC_INT_SOFT),
345     DECL(ALC_UNSIGNED_INT_SOFT),
346     DECL(ALC_FLOAT_SOFT),
347
348     DECL(ALC_HRTF_SOFT),
349     DECL(ALC_DONT_CARE_SOFT),
350     DECL(ALC_HRTF_STATUS_SOFT),
351     DECL(ALC_HRTF_DISABLED_SOFT),
352     DECL(ALC_HRTF_ENABLED_SOFT),
353     DECL(ALC_HRTF_DENIED_SOFT),
354     DECL(ALC_HRTF_REQUIRED_SOFT),
355     DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
356     DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
357     DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
358     DECL(ALC_HRTF_SPECIFIER_SOFT),
359     DECL(ALC_HRTF_ID_SOFT),
360
361     DECL(ALC_NO_ERROR),
362     DECL(ALC_INVALID_DEVICE),
363     DECL(ALC_INVALID_CONTEXT),
364     DECL(ALC_INVALID_ENUM),
365     DECL(ALC_INVALID_VALUE),
366     DECL(ALC_OUT_OF_MEMORY),
367
368
369     DECL(AL_INVALID),
370     DECL(AL_NONE),
371     DECL(AL_FALSE),
372     DECL(AL_TRUE),
373
374     DECL(AL_SOURCE_RELATIVE),
375     DECL(AL_CONE_INNER_ANGLE),
376     DECL(AL_CONE_OUTER_ANGLE),
377     DECL(AL_PITCH),
378     DECL(AL_POSITION),
379     DECL(AL_DIRECTION),
380     DECL(AL_VELOCITY),
381     DECL(AL_LOOPING),
382 #ifdef __TIZEN__
383     DECL(AL_LOOP_COUNT),
384 #endif
385     DECL(AL_BUFFER),
386     DECL(AL_GAIN),
387     DECL(AL_MIN_GAIN),
388     DECL(AL_MAX_GAIN),
389     DECL(AL_ORIENTATION),
390     DECL(AL_REFERENCE_DISTANCE),
391     DECL(AL_ROLLOFF_FACTOR),
392     DECL(AL_CONE_OUTER_GAIN),
393     DECL(AL_MAX_DISTANCE),
394     DECL(AL_SEC_OFFSET),
395     DECL(AL_SAMPLE_OFFSET),
396     DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
397     DECL(AL_BYTE_OFFSET),
398     DECL(AL_BYTE_RW_OFFSETS_SOFT),
399     DECL(AL_SOURCE_TYPE),
400     DECL(AL_STATIC),
401     DECL(AL_STREAMING),
402     DECL(AL_UNDETERMINED),
403     DECL(AL_METERS_PER_UNIT),
404     DECL(AL_LOOP_POINTS_SOFT),
405     DECL(AL_DIRECT_CHANNELS_SOFT),
406
407     DECL(AL_DIRECT_FILTER),
408     DECL(AL_AUXILIARY_SEND_FILTER),
409     DECL(AL_AIR_ABSORPTION_FACTOR),
410     DECL(AL_ROOM_ROLLOFF_FACTOR),
411     DECL(AL_CONE_OUTER_GAINHF),
412     DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
413     DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
414     DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
415
416     DECL(AL_SOURCE_STATE),
417     DECL(AL_INITIAL),
418     DECL(AL_PLAYING),
419     DECL(AL_PAUSED),
420     DECL(AL_STOPPED),
421
422     DECL(AL_BUFFERS_QUEUED),
423     DECL(AL_BUFFERS_PROCESSED),
424
425     DECL(AL_FORMAT_MONO8),
426     DECL(AL_FORMAT_MONO16),
427     DECL(AL_FORMAT_MONO_FLOAT32),
428     DECL(AL_FORMAT_MONO_DOUBLE_EXT),
429     DECL(AL_FORMAT_STEREO8),
430     DECL(AL_FORMAT_STEREO16),
431     DECL(AL_FORMAT_STEREO_FLOAT32),
432     DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
433     DECL(AL_FORMAT_MONO_IMA4),
434     DECL(AL_FORMAT_STEREO_IMA4),
435     DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
436     DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
437     DECL(AL_FORMAT_QUAD8_LOKI),
438     DECL(AL_FORMAT_QUAD16_LOKI),
439     DECL(AL_FORMAT_QUAD8),
440     DECL(AL_FORMAT_QUAD16),
441     DECL(AL_FORMAT_QUAD32),
442     DECL(AL_FORMAT_51CHN8),
443     DECL(AL_FORMAT_51CHN16),
444     DECL(AL_FORMAT_51CHN32),
445     DECL(AL_FORMAT_61CHN8),
446     DECL(AL_FORMAT_61CHN16),
447     DECL(AL_FORMAT_61CHN32),
448     DECL(AL_FORMAT_71CHN8),
449     DECL(AL_FORMAT_71CHN16),
450     DECL(AL_FORMAT_71CHN32),
451     DECL(AL_FORMAT_REAR8),
452     DECL(AL_FORMAT_REAR16),
453     DECL(AL_FORMAT_REAR32),
454     DECL(AL_FORMAT_MONO_MULAW),
455     DECL(AL_FORMAT_MONO_MULAW_EXT),
456     DECL(AL_FORMAT_STEREO_MULAW),
457     DECL(AL_FORMAT_STEREO_MULAW_EXT),
458     DECL(AL_FORMAT_QUAD_MULAW),
459     DECL(AL_FORMAT_51CHN_MULAW),
460     DECL(AL_FORMAT_61CHN_MULAW),
461     DECL(AL_FORMAT_71CHN_MULAW),
462     DECL(AL_FORMAT_REAR_MULAW),
463     DECL(AL_FORMAT_MONO_ALAW_EXT),
464     DECL(AL_FORMAT_STEREO_ALAW_EXT),
465
466     DECL(AL_MONO8_SOFT),
467     DECL(AL_MONO16_SOFT),
468     DECL(AL_MONO32F_SOFT),
469     DECL(AL_STEREO8_SOFT),
470     DECL(AL_STEREO16_SOFT),
471     DECL(AL_STEREO32F_SOFT),
472     DECL(AL_QUAD8_SOFT),
473     DECL(AL_QUAD16_SOFT),
474     DECL(AL_QUAD32F_SOFT),
475     DECL(AL_REAR8_SOFT),
476     DECL(AL_REAR16_SOFT),
477     DECL(AL_REAR32F_SOFT),
478     DECL(AL_5POINT1_8_SOFT),
479     DECL(AL_5POINT1_16_SOFT),
480     DECL(AL_5POINT1_32F_SOFT),
481     DECL(AL_6POINT1_8_SOFT),
482     DECL(AL_6POINT1_16_SOFT),
483     DECL(AL_6POINT1_32F_SOFT),
484     DECL(AL_7POINT1_8_SOFT),
485     DECL(AL_7POINT1_16_SOFT),
486     DECL(AL_7POINT1_32F_SOFT),
487     DECL(AL_FORMAT_BFORMAT2D_8),
488     DECL(AL_FORMAT_BFORMAT2D_16),
489     DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
490     DECL(AL_FORMAT_BFORMAT2D_MULAW),
491     DECL(AL_FORMAT_BFORMAT3D_8),
492     DECL(AL_FORMAT_BFORMAT3D_16),
493     DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
494     DECL(AL_FORMAT_BFORMAT3D_MULAW),
495
496     DECL(AL_MONO_SOFT),
497     DECL(AL_STEREO_SOFT),
498     DECL(AL_QUAD_SOFT),
499     DECL(AL_REAR_SOFT),
500     DECL(AL_5POINT1_SOFT),
501     DECL(AL_6POINT1_SOFT),
502     DECL(AL_7POINT1_SOFT),
503
504     DECL(AL_BYTE_SOFT),
505     DECL(AL_UNSIGNED_BYTE_SOFT),
506     DECL(AL_SHORT_SOFT),
507     DECL(AL_UNSIGNED_SHORT_SOFT),
508     DECL(AL_INT_SOFT),
509     DECL(AL_UNSIGNED_INT_SOFT),
510     DECL(AL_FLOAT_SOFT),
511     DECL(AL_DOUBLE_SOFT),
512     DECL(AL_BYTE3_SOFT),
513     DECL(AL_UNSIGNED_BYTE3_SOFT),
514
515     DECL(AL_FREQUENCY),
516     DECL(AL_BITS),
517     DECL(AL_CHANNELS),
518     DECL(AL_SIZE),
519     DECL(AL_INTERNAL_FORMAT_SOFT),
520     DECL(AL_BYTE_LENGTH_SOFT),
521     DECL(AL_SAMPLE_LENGTH_SOFT),
522     DECL(AL_SEC_LENGTH_SOFT),
523     DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
524     DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
525
526     DECL(AL_UNUSED),
527     DECL(AL_PENDING),
528     DECL(AL_PROCESSED),
529
530     DECL(AL_NO_ERROR),
531     DECL(AL_INVALID_NAME),
532     DECL(AL_INVALID_ENUM),
533     DECL(AL_INVALID_VALUE),
534     DECL(AL_INVALID_OPERATION),
535     DECL(AL_OUT_OF_MEMORY),
536
537     DECL(AL_VENDOR),
538     DECL(AL_VERSION),
539     DECL(AL_RENDERER),
540     DECL(AL_EXTENSIONS),
541
542     DECL(AL_DOPPLER_FACTOR),
543     DECL(AL_DOPPLER_VELOCITY),
544     DECL(AL_DISTANCE_MODEL),
545     DECL(AL_SPEED_OF_SOUND),
546     DECL(AL_SOURCE_DISTANCE_MODEL),
547     DECL(AL_DEFERRED_UPDATES_SOFT),
548
549     DECL(AL_INVERSE_DISTANCE),
550     DECL(AL_INVERSE_DISTANCE_CLAMPED),
551     DECL(AL_LINEAR_DISTANCE),
552     DECL(AL_LINEAR_DISTANCE_CLAMPED),
553     DECL(AL_EXPONENT_DISTANCE),
554     DECL(AL_EXPONENT_DISTANCE_CLAMPED),
555
556     DECL(AL_FILTER_TYPE),
557     DECL(AL_FILTER_NULL),
558     DECL(AL_FILTER_LOWPASS),
559     DECL(AL_FILTER_HIGHPASS),
560     DECL(AL_FILTER_BANDPASS),
561
562     DECL(AL_LOWPASS_GAIN),
563     DECL(AL_LOWPASS_GAINHF),
564
565     DECL(AL_HIGHPASS_GAIN),
566     DECL(AL_HIGHPASS_GAINLF),
567
568     DECL(AL_BANDPASS_GAIN),
569     DECL(AL_BANDPASS_GAINHF),
570     DECL(AL_BANDPASS_GAINLF),
571
572     DECL(AL_EFFECT_TYPE),
573     DECL(AL_EFFECT_NULL),
574     DECL(AL_EFFECT_REVERB),
575     DECL(AL_EFFECT_EAXREVERB),
576     DECL(AL_EFFECT_CHORUS),
577     DECL(AL_EFFECT_DISTORTION),
578     DECL(AL_EFFECT_ECHO),
579     DECL(AL_EFFECT_FLANGER),
580 #if 0
581     DECL(AL_EFFECT_FREQUENCY_SHIFTER),
582     DECL(AL_EFFECT_VOCAL_MORPHER),
583     DECL(AL_EFFECT_PITCH_SHIFTER),
584 #endif
585     DECL(AL_EFFECT_RING_MODULATOR),
586 #if 0
587     DECL(AL_EFFECT_AUTOWAH),
588 #endif
589     DECL(AL_EFFECT_COMPRESSOR),
590     DECL(AL_EFFECT_EQUALIZER),
591     DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
592     DECL(AL_EFFECT_DEDICATED_DIALOGUE),
593
594     DECL(AL_EAXREVERB_DENSITY),
595     DECL(AL_EAXREVERB_DIFFUSION),
596     DECL(AL_EAXREVERB_GAIN),
597     DECL(AL_EAXREVERB_GAINHF),
598     DECL(AL_EAXREVERB_GAINLF),
599     DECL(AL_EAXREVERB_DECAY_TIME),
600     DECL(AL_EAXREVERB_DECAY_HFRATIO),
601     DECL(AL_EAXREVERB_DECAY_LFRATIO),
602     DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
603     DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
604     DECL(AL_EAXREVERB_REFLECTIONS_PAN),
605     DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
606     DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
607     DECL(AL_EAXREVERB_LATE_REVERB_PAN),
608     DECL(AL_EAXREVERB_ECHO_TIME),
609     DECL(AL_EAXREVERB_ECHO_DEPTH),
610     DECL(AL_EAXREVERB_MODULATION_TIME),
611     DECL(AL_EAXREVERB_MODULATION_DEPTH),
612     DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
613     DECL(AL_EAXREVERB_HFREFERENCE),
614     DECL(AL_EAXREVERB_LFREFERENCE),
615     DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
616     DECL(AL_EAXREVERB_DECAY_HFLIMIT),
617
618     DECL(AL_REVERB_DENSITY),
619     DECL(AL_REVERB_DIFFUSION),
620     DECL(AL_REVERB_GAIN),
621     DECL(AL_REVERB_GAINHF),
622     DECL(AL_REVERB_DECAY_TIME),
623     DECL(AL_REVERB_DECAY_HFRATIO),
624     DECL(AL_REVERB_REFLECTIONS_GAIN),
625     DECL(AL_REVERB_REFLECTIONS_DELAY),
626     DECL(AL_REVERB_LATE_REVERB_GAIN),
627     DECL(AL_REVERB_LATE_REVERB_DELAY),
628     DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
629     DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
630     DECL(AL_REVERB_DECAY_HFLIMIT),
631
632     DECL(AL_CHORUS_WAVEFORM),
633     DECL(AL_CHORUS_PHASE),
634     DECL(AL_CHORUS_RATE),
635     DECL(AL_CHORUS_DEPTH),
636     DECL(AL_CHORUS_FEEDBACK),
637     DECL(AL_CHORUS_DELAY),
638
639     DECL(AL_DISTORTION_EDGE),
640     DECL(AL_DISTORTION_GAIN),
641     DECL(AL_DISTORTION_LOWPASS_CUTOFF),
642     DECL(AL_DISTORTION_EQCENTER),
643     DECL(AL_DISTORTION_EQBANDWIDTH),
644
645     DECL(AL_ECHO_DELAY),
646     DECL(AL_ECHO_LRDELAY),
647     DECL(AL_ECHO_DAMPING),
648     DECL(AL_ECHO_FEEDBACK),
649     DECL(AL_ECHO_SPREAD),
650
651     DECL(AL_FLANGER_WAVEFORM),
652     DECL(AL_FLANGER_PHASE),
653     DECL(AL_FLANGER_RATE),
654     DECL(AL_FLANGER_DEPTH),
655     DECL(AL_FLANGER_FEEDBACK),
656     DECL(AL_FLANGER_DELAY),
657
658     DECL(AL_RING_MODULATOR_FREQUENCY),
659     DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
660     DECL(AL_RING_MODULATOR_WAVEFORM),
661
662 #if 0
663     DECL(AL_AUTOWAH_ATTACK_TIME),
664     DECL(AL_AUTOWAH_PEAK_GAIN),
665     DECL(AL_AUTOWAH_RELEASE_TIME),
666     DECL(AL_AUTOWAH_RESONANCE),
667 #endif
668
669     DECL(AL_COMPRESSOR_ONOFF),
670
671     DECL(AL_EQUALIZER_LOW_GAIN),
672     DECL(AL_EQUALIZER_LOW_CUTOFF),
673     DECL(AL_EQUALIZER_MID1_GAIN),
674     DECL(AL_EQUALIZER_MID1_CENTER),
675     DECL(AL_EQUALIZER_MID1_WIDTH),
676     DECL(AL_EQUALIZER_MID2_GAIN),
677     DECL(AL_EQUALIZER_MID2_CENTER),
678     DECL(AL_EQUALIZER_MID2_WIDTH),
679     DECL(AL_EQUALIZER_HIGH_GAIN),
680     DECL(AL_EQUALIZER_HIGH_CUTOFF),
681
682     DECL(AL_DEDICATED_GAIN),
683
684     { NULL, (ALCenum)0 }
685 };
686 #undef DECL
687
688 static const ALCchar alcNoError[] = "No Error";
689 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
690 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
691 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
692 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
693 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
694
695
696 /************************************************
697  * Global variables
698  ************************************************/
699
700 /* Enumerated device names */
701 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
702
703 static al_string alcAllDevicesList;
704 static al_string alcCaptureDeviceList;
705
706 /* Default is always the first in the list */
707 static ALCchar *alcDefaultAllDevicesSpecifier;
708 static ALCchar *alcCaptureDefaultDeviceSpecifier;
709
710 /* Default context extensions */
711 static const ALchar alExtList[] =
712     "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
713     "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
714     "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
715     "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment "
716     "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates "
717     "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM "
718     "AL_SOFT_source_latency AL_SOFT_source_length";
719
720 static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR);
721
722 /* Thread-local current context */
723 static altss_t LocalContext;
724 /* Process-wide current context */
725 static ATOMIC(ALCcontext*) GlobalContext = ATOMIC_INIT_STATIC(NULL);
726
727 /* Mixing thread piority level */
728 ALint RTPrioLevel;
729
730 FILE *LogFile;
731 #ifdef _DEBUG
732 enum LogLevel LogLevel = LogWarning;
733 #else
734 enum LogLevel LogLevel = LogError;
735 #endif
736
737 /* Flag to trap ALC device errors */
738 static ALCboolean TrapALCError = ALC_FALSE;
739
740 /* One-time configuration init control */
741 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
742
743 /* Default effect that applies to sources that don't have an effect on send 0 */
744 static ALeffect DefaultEffect;
745
746 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
747  * updates.
748  */
749 static ALCboolean SuspendDefers = ALC_TRUE;
750
751
752 /************************************************
753  * ALC information
754  ************************************************/
755 static const ALCchar alcNoDeviceExtList[] =
756     "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
757     "ALC_EXT_thread_local_context ALC_SOFT_loopback";
758 static const ALCchar alcExtensionList[] =
759     "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
760     "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
761     "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFT_HRTF "
762     "ALC_SOFT_loopback ALC_SOFT_pause_device";
763 static const ALCint alcMajorVersion = 1;
764 static const ALCint alcMinorVersion = 1;
765
766 static const ALCint alcEFXMajorVersion = 1;
767 static const ALCint alcEFXMinorVersion = 0;
768
769
770 /************************************************
771  * Device lists
772  ************************************************/
773 static ATOMIC(ALCdevice*) DeviceList = ATOMIC_INIT_STATIC(NULL);
774
775 static almtx_t ListLock;
776 static inline void LockLists(void)
777 {
778     int lockret = almtx_lock(&ListLock);
779     assert(lockret == althrd_success);
780 }
781 static inline void UnlockLists(void)
782 {
783     int unlockret = almtx_unlock(&ListLock);
784     assert(unlockret == althrd_success);
785 }
786
787 /************************************************
788  * Library initialization
789  ************************************************/
790 #if defined(_WIN32)
791 static void alc_init(void);
792 static void alc_deinit(void);
793 static void alc_deinit_safe(void);
794
795 #ifndef AL_LIBTYPE_STATIC
796 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
797 {
798     switch(reason)
799     {
800         case DLL_PROCESS_ATTACH:
801             /* Pin the DLL so we won't get unloaded until the process terminates */
802             GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
803                                (WCHAR*)hModule, &hModule);
804             alc_init();
805             break;
806
807         case DLL_THREAD_DETACH:
808             break;
809
810         case DLL_PROCESS_DETACH:
811             if(!lpReserved)
812                 alc_deinit();
813             else
814                 alc_deinit_safe();
815             break;
816     }
817     return TRUE;
818 }
819 #elif defined(_MSC_VER)
820 #pragma section(".CRT$XCU",read)
821 static void alc_constructor(void);
822 static void alc_destructor(void);
823 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
824
825 static void alc_constructor(void)
826 {
827     atexit(alc_destructor);
828     alc_init();
829 }
830
831 static void alc_destructor(void)
832 {
833     alc_deinit();
834 }
835 #elif defined(HAVE_GCC_DESTRUCTOR)
836 static void alc_init(void) __attribute__((constructor));
837 static void alc_deinit(void) __attribute__((destructor));
838 #else
839 #error "No static initialization available on this platform!"
840 #endif
841
842 #elif defined(HAVE_GCC_DESTRUCTOR)
843
844 static void alc_init(void) __attribute__((constructor));
845 static void alc_deinit(void) __attribute__((destructor));
846
847 #else
848 #error "No global initialization available on this platform!"
849 #endif
850
851 static void ReleaseThreadCtx(void *ptr);
852 static void alc_init(void)
853 {
854     const char *str;
855     int ret;
856
857     LogFile = stderr;
858
859     AL_STRING_INIT(alcAllDevicesList);
860     AL_STRING_INIT(alcCaptureDeviceList);
861
862     str = getenv("__ALSOFT_HALF_ANGLE_CONES");
863     if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
864         ConeScale *= 0.5f;
865
866     str = getenv("__ALSOFT_REVERSE_Z");
867     if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
868         ZScale *= -1.0f;
869
870     ret = altss_create(&LocalContext, ReleaseThreadCtx);
871     assert(ret == althrd_success);
872
873     ret = almtx_init(&ListLock, almtx_recursive);
874     assert(ret == althrd_success);
875
876     ThunkInit();
877 }
878
879 static void alc_initconfig(void)
880 {
881     const char *devs, *str;
882     ALuint capfilter;
883     float valf;
884     int i, n;
885
886     str = getenv("ALSOFT_LOGLEVEL");
887     if(str)
888     {
889         long lvl = strtol(str, NULL, 0);
890         if(lvl >= NoLog && lvl <= LogRef)
891             LogLevel = lvl;
892     }
893
894     str = getenv("ALSOFT_LOGFILE");
895     if(str && str[0])
896     {
897         FILE *logfile = al_fopen(str, "wt");
898         if(logfile) LogFile = logfile;
899         else ERR("Failed to open log file '%s'\n", str);
900     }
901
902     {
903         char buf[1024] = "";
904         int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
905         for(i = 1;BackendList[i].name;i++)
906             len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
907         TRACE("Supported backends: %s\n", buf);
908     }
909     ReadALConfig();
910
911     str = getenv("__ALSOFT_SUSPEND_CONTEXT");
912     if(str && *str)
913     {
914         if(strcasecmp(str, "ignore") == 0)
915         {
916             SuspendDefers = ALC_FALSE;
917             TRACE("Selected context suspend behavior, \"ignore\"\n");
918         }
919         else
920             ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
921     }
922
923     capfilter = 0;
924 #if defined(HAVE_SSE4_1)
925     capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
926 #elif defined(HAVE_SSE3)
927     capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
928 #elif defined(HAVE_SSE2)
929     capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
930 #elif defined(HAVE_SSE)
931     capfilter |= CPU_CAP_SSE;
932 #endif
933 #ifdef HAVE_NEON
934     capfilter |= CPU_CAP_NEON;
935 #endif
936     if(ConfigValueStr(NULL, NULL, "disable-cpu-exts", &str))
937     {
938         if(strcasecmp(str, "all") == 0)
939             capfilter = 0;
940         else
941         {
942             size_t len;
943             const char *next = str;
944
945             do {
946                 str = next;
947                 while(isspace(str[0]))
948                     str++;
949                 next = strchr(str, ',');
950
951                 if(!str[0] || str[0] == ',')
952                     continue;
953
954                 len = (next ? ((size_t)(next-str)) : strlen(str));
955                 while(len > 0 && isspace(str[len-1]))
956                     len--;
957                 if(len == 3 && strncasecmp(str, "sse", len) == 0)
958                     capfilter &= ~CPU_CAP_SSE;
959                 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
960                     capfilter &= ~CPU_CAP_SSE2;
961                 else if(len == 4 && strncasecmp(str, "sse3", len) == 0)
962                     capfilter &= ~CPU_CAP_SSE3;
963                 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
964                     capfilter &= ~CPU_CAP_SSE4_1;
965                 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
966                     capfilter &= ~CPU_CAP_NEON;
967                 else
968                     WARN("Invalid CPU extension \"%s\"\n", str);
969             } while(next++);
970         }
971     }
972     FillCPUCaps(capfilter);
973
974 #ifdef _WIN32
975     RTPrioLevel = 1;
976 #else
977     RTPrioLevel = 0;
978 #endif
979     ConfigValueInt(NULL, NULL, "rt-prio", &RTPrioLevel);
980
981     aluInitMixer();
982
983     str = getenv("ALSOFT_TRAP_ERROR");
984     if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
985     {
986         TrapALError  = AL_TRUE;
987         TrapALCError = AL_TRUE;
988     }
989     else
990     {
991         str = getenv("ALSOFT_TRAP_AL_ERROR");
992         if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
993             TrapALError = AL_TRUE;
994         TrapALError = GetConfigValueBool(NULL, NULL, "trap-al-error", TrapALError);
995
996         str = getenv("ALSOFT_TRAP_ALC_ERROR");
997         if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
998             TrapALCError = ALC_TRUE;
999         TrapALCError = GetConfigValueBool(NULL, NULL, "trap-alc-error", TrapALCError);
1000     }
1001
1002     if(ConfigValueFloat(NULL, "reverb", "boost", &valf))
1003         ReverbBoost *= powf(10.0f, valf / 20.0f);
1004
1005     EmulateEAXReverb = GetConfigValueBool(NULL, "reverb", "emulate-eax", AL_FALSE);
1006
1007     if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1008        ConfigValueStr(NULL, NULL, "drivers", &devs))
1009     {
1010         int n;
1011         size_t len;
1012         const char *next = devs;
1013         int endlist, delitem;
1014
1015         i = 0;
1016         do {
1017             devs = next;
1018             while(isspace(devs[0]))
1019                 devs++;
1020             next = strchr(devs, ',');
1021
1022             delitem = (devs[0] == '-');
1023             if(devs[0] == '-') devs++;
1024
1025             if(!devs[0] || devs[0] == ',')
1026             {
1027                 endlist = 0;
1028                 continue;
1029             }
1030             endlist = 1;
1031
1032             len = (next ? ((size_t)(next-devs)) : strlen(devs));
1033             while(len > 0 && isspace(devs[len-1]))
1034                 len--;
1035             for(n = i;BackendList[n].name;n++)
1036             {
1037                 if(len == strlen(BackendList[n].name) &&
1038                    strncmp(BackendList[n].name, devs, len) == 0)
1039                 {
1040                     if(delitem)
1041                     {
1042                         do {
1043                             BackendList[n] = BackendList[n+1];
1044                             ++n;
1045                         } while(BackendList[n].name);
1046                     }
1047                     else
1048                     {
1049                         struct BackendInfo Bkp = BackendList[n];
1050                         while(n > i)
1051                         {
1052                             BackendList[n] = BackendList[n-1];
1053                             --n;
1054                         }
1055                         BackendList[n] = Bkp;
1056
1057                         i++;
1058                     }
1059                     break;
1060                 }
1061             }
1062         } while(next++);
1063
1064         if(endlist)
1065         {
1066             BackendList[i].name = NULL;
1067             BackendList[i].getFactory = NULL;
1068             BackendList[i].Init = NULL;
1069             BackendList[i].Deinit = NULL;
1070             BackendList[i].Probe = NULL;
1071         }
1072     }
1073
1074     for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1075     {
1076         if(BackendList[i].getFactory)
1077         {
1078             ALCbackendFactory *factory = BackendList[i].getFactory();
1079             if(!V0(factory,init)())
1080             {
1081                 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1082                 continue;
1083             }
1084
1085             TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1086             if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1087             {
1088                 PlaybackBackend = BackendList[i];
1089                 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1090             }
1091             if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1092             {
1093                 CaptureBackend = BackendList[i];
1094                 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1095             }
1096
1097             continue;
1098         }
1099
1100         if(!BackendList[i].Init(&BackendList[i].Funcs))
1101         {
1102             WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1103             continue;
1104         }
1105
1106         TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1107         if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1108         {
1109             PlaybackBackend = BackendList[i];
1110             TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1111         }
1112         if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1113         {
1114             CaptureBackend = BackendList[i];
1115             TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1116         }
1117     }
1118     {
1119         ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1120         V0(factory,init)();
1121     }
1122
1123     if(ConfigValueStr(NULL, NULL, "excludefx", &str))
1124     {
1125         size_t len;
1126         const char *next = str;
1127
1128         do {
1129             str = next;
1130             next = strchr(str, ',');
1131
1132             if(!str[0] || next == str)
1133                 continue;
1134
1135             len = (next ? ((size_t)(next-str)) : strlen(str));
1136             for(n = 0;EffectList[n].name;n++)
1137             {
1138                 if(len == strlen(EffectList[n].name) &&
1139                    strncmp(EffectList[n].name, str, len) == 0)
1140                     DisabledEffects[EffectList[n].type] = AL_TRUE;
1141             }
1142         } while(next++);
1143     }
1144
1145     InitEffectFactoryMap();
1146
1147     InitEffect(&DefaultEffect);
1148     str = getenv("ALSOFT_DEFAULT_REVERB");
1149     if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str))
1150         LoadReverbPreset(str, &DefaultEffect);
1151 }
1152 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1153
1154
1155 /************************************************
1156  * Library deinitialization
1157  ************************************************/
1158 static void alc_cleanup(void)
1159 {
1160     ALCdevice *dev;
1161
1162     AL_STRING_DEINIT(alcAllDevicesList);
1163     AL_STRING_DEINIT(alcCaptureDeviceList);
1164
1165     free(alcDefaultAllDevicesSpecifier);
1166     alcDefaultAllDevicesSpecifier = NULL;
1167     free(alcCaptureDefaultDeviceSpecifier);
1168     alcCaptureDefaultDeviceSpecifier = NULL;
1169
1170     if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL)
1171     {
1172         ALCuint num = 0;
1173         do {
1174             num++;
1175         } while((dev=dev->next) != NULL);
1176         ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1177     }
1178
1179     DeinitEffectFactoryMap();
1180 }
1181
1182 static void alc_deinit_safe(void)
1183 {
1184     alc_cleanup();
1185
1186     FreeHrtfs();
1187     FreeALConfig();
1188
1189     ThunkExit();
1190     almtx_destroy(&ListLock);
1191     altss_delete(LocalContext);
1192
1193     if(LogFile != stderr)
1194         fclose(LogFile);
1195     LogFile = NULL;
1196 }
1197
1198 static void alc_deinit(void)
1199 {
1200     int i;
1201
1202     alc_cleanup();
1203
1204     memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1205     memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1206
1207     for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1208     {
1209         if(!BackendList[i].getFactory)
1210             BackendList[i].Deinit();
1211         else
1212         {
1213             ALCbackendFactory *factory = BackendList[i].getFactory();
1214             V0(factory,deinit)();
1215         }
1216     }
1217     {
1218         ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1219         V0(factory,deinit)();
1220     }
1221
1222     alc_deinit_safe();
1223 }
1224
1225
1226 /************************************************
1227  * Device enumeration
1228  ************************************************/
1229 static void ProbeDevices(al_string *list, struct BackendInfo *backendinfo, enum DevProbe type)
1230 {
1231     DO_INITCONFIG();
1232
1233     LockLists();
1234     al_string_clear(list);
1235
1236     if(!backendinfo->getFactory)
1237         backendinfo->Probe(type);
1238     else
1239     {
1240         ALCbackendFactory *factory = backendinfo->getFactory();
1241         V(factory,probe)(type);
1242     }
1243
1244     UnlockLists();
1245 }
1246 static void ProbeAllDevicesList(void)
1247 { ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
1248 static void ProbeCaptureDeviceList(void)
1249 { ProbeDevices(&alcCaptureDeviceList, &CaptureBackend, CAPTURE_DEVICE_PROBE); }
1250
1251 static void AppendDevice(const ALCchar *name, al_string *devnames)
1252 {
1253     size_t len = strlen(name);
1254     if(len > 0)
1255         al_string_append_range(devnames, name, name+len+1);
1256 }
1257 void AppendAllDevicesList(const ALCchar *name)
1258 { AppendDevice(name, &alcAllDevicesList); }
1259 void AppendCaptureDeviceList(const ALCchar *name)
1260 { AppendDevice(name, &alcCaptureDeviceList); }
1261
1262
1263 /************************************************
1264  * Device format information
1265  ************************************************/
1266 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1267 {
1268     switch(type)
1269     {
1270     case DevFmtByte: return "Signed Byte";
1271     case DevFmtUByte: return "Unsigned Byte";
1272     case DevFmtShort: return "Signed Short";
1273     case DevFmtUShort: return "Unsigned Short";
1274     case DevFmtInt: return "Signed Int";
1275     case DevFmtUInt: return "Unsigned Int";
1276     case DevFmtFloat: return "Float";
1277     }
1278     return "(unknown type)";
1279 }
1280 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1281 {
1282     switch(chans)
1283     {
1284     case DevFmtMono: return "Mono";
1285     case DevFmtStereo: return "Stereo";
1286     case DevFmtQuad: return "Quadraphonic";
1287     case DevFmtX51: return "5.1 Surround";
1288     case DevFmtX51Rear: return "5.1 Surround (Rear)";
1289     case DevFmtX61: return "6.1 Surround";
1290     case DevFmtX71: return "7.1 Surround";
1291     case DevFmtBFormat3D: return "B-Format 3D";
1292     }
1293     return "(unknown channels)";
1294 }
1295
1296 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1297 ALuint BytesFromDevFmt(enum DevFmtType type)
1298 {
1299     switch(type)
1300     {
1301     case DevFmtByte: return sizeof(ALbyte);
1302     case DevFmtUByte: return sizeof(ALubyte);
1303     case DevFmtShort: return sizeof(ALshort);
1304     case DevFmtUShort: return sizeof(ALushort);
1305     case DevFmtInt: return sizeof(ALint);
1306     case DevFmtUInt: return sizeof(ALuint);
1307     case DevFmtFloat: return sizeof(ALfloat);
1308     }
1309     return 0;
1310 }
1311 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1312 {
1313     switch(chans)
1314     {
1315     case DevFmtMono: return 1;
1316     case DevFmtStereo: return 2;
1317     case DevFmtQuad: return 4;
1318     case DevFmtX51: return 6;
1319     case DevFmtX51Rear: return 6;
1320     case DevFmtX61: return 7;
1321     case DevFmtX71: return 8;
1322     case DevFmtBFormat3D: return 4;
1323     }
1324     return 0;
1325 }
1326
1327 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1328   enum DevFmtChannels *chans, enum DevFmtType *type)
1329 {
1330     static const struct {
1331         ALenum format;
1332         enum DevFmtChannels channels;
1333         enum DevFmtType type;
1334     } list[] = {
1335         { AL_FORMAT_MONO8,        DevFmtMono, DevFmtUByte },
1336         { AL_FORMAT_MONO16,       DevFmtMono, DevFmtShort },
1337         { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1338
1339         { AL_FORMAT_STEREO8,        DevFmtStereo, DevFmtUByte },
1340         { AL_FORMAT_STEREO16,       DevFmtStereo, DevFmtShort },
1341         { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1342
1343         { AL_FORMAT_QUAD8,  DevFmtQuad, DevFmtUByte },
1344         { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1345         { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1346
1347         { AL_FORMAT_51CHN8,  DevFmtX51, DevFmtUByte },
1348         { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1349         { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1350
1351         { AL_FORMAT_61CHN8,  DevFmtX61, DevFmtUByte },
1352         { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1353         { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1354
1355         { AL_FORMAT_71CHN8,  DevFmtX71, DevFmtUByte },
1356         { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1357         { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1358     };
1359     ALuint i;
1360
1361     for(i = 0;i < COUNTOF(list);i++)
1362     {
1363         if(list[i].format == format)
1364         {
1365             *chans = list[i].channels;
1366             *type  = list[i].type;
1367             return AL_TRUE;
1368         }
1369     }
1370
1371     return AL_FALSE;
1372 }
1373
1374 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1375 {
1376     switch(type)
1377     {
1378         case ALC_BYTE_SOFT:
1379         case ALC_UNSIGNED_BYTE_SOFT:
1380         case ALC_SHORT_SOFT:
1381         case ALC_UNSIGNED_SHORT_SOFT:
1382         case ALC_INT_SOFT:
1383         case ALC_UNSIGNED_INT_SOFT:
1384         case ALC_FLOAT_SOFT:
1385             return ALC_TRUE;
1386     }
1387     return ALC_FALSE;
1388 }
1389
1390 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1391 {
1392     switch(channels)
1393     {
1394         case ALC_MONO_SOFT:
1395         case ALC_STEREO_SOFT:
1396         case ALC_QUAD_SOFT:
1397         case ALC_5POINT1_SOFT:
1398         case ALC_6POINT1_SOFT:
1399         case ALC_7POINT1_SOFT:
1400             return ALC_TRUE;
1401     }
1402     return ALC_FALSE;
1403 }
1404
1405
1406 /************************************************
1407  * Miscellaneous ALC helpers
1408  ************************************************/
1409 enum HrtfRequestMode {
1410     Hrtf_Default = 0,
1411     Hrtf_Enable = 1,
1412     Hrtf_Disable = 2,
1413 };
1414
1415 extern inline void LockContext(ALCcontext *context);
1416 extern inline void UnlockContext(ALCcontext *context);
1417
1418 void ALCdevice_Lock(ALCdevice *device)
1419 {
1420     V0(device->Backend,lock)();
1421 }
1422
1423 void ALCdevice_Unlock(ALCdevice *device)
1424 {
1425     V0(device->Backend,unlock)();
1426 }
1427
1428
1429 /* SetDefaultWFXChannelOrder
1430  *
1431  * Sets the default channel order used by WaveFormatEx.
1432  */
1433 void SetDefaultWFXChannelOrder(ALCdevice *device)
1434 {
1435     ALuint i;
1436
1437     for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1438         device->ChannelName[i] = InvalidChannel;
1439
1440     switch(device->FmtChans)
1441     {
1442     case DevFmtMono:
1443         device->ChannelName[0] = FrontCenter;
1444         break;
1445     case DevFmtStereo:
1446         device->ChannelName[0] = FrontLeft;
1447         device->ChannelName[1] = FrontRight;
1448         break;
1449     case DevFmtQuad:
1450         device->ChannelName[0] = FrontLeft;
1451         device->ChannelName[1] = FrontRight;
1452         device->ChannelName[2] = BackLeft;
1453         device->ChannelName[3] = BackRight;
1454         break;
1455     case DevFmtX51:
1456         device->ChannelName[0] = FrontLeft;
1457         device->ChannelName[1] = FrontRight;
1458         device->ChannelName[2] = FrontCenter;
1459         device->ChannelName[3] = LFE;
1460         device->ChannelName[4] = SideLeft;
1461         device->ChannelName[5] = SideRight;
1462         break;
1463     case DevFmtX51Rear:
1464         device->ChannelName[0] = FrontLeft;
1465         device->ChannelName[1] = FrontRight;
1466         device->ChannelName[2] = FrontCenter;
1467         device->ChannelName[3] = LFE;
1468         device->ChannelName[4] = BackLeft;
1469         device->ChannelName[5] = BackRight;
1470         break;
1471     case DevFmtX61:
1472         device->ChannelName[0] = FrontLeft;
1473         device->ChannelName[1] = FrontRight;
1474         device->ChannelName[2] = FrontCenter;
1475         device->ChannelName[3] = LFE;
1476         device->ChannelName[4] = BackCenter;
1477         device->ChannelName[5] = SideLeft;
1478         device->ChannelName[6] = SideRight;
1479         break;
1480     case DevFmtX71:
1481         device->ChannelName[0] = FrontLeft;
1482         device->ChannelName[1] = FrontRight;
1483         device->ChannelName[2] = FrontCenter;
1484         device->ChannelName[3] = LFE;
1485         device->ChannelName[4] = BackLeft;
1486         device->ChannelName[5] = BackRight;
1487         device->ChannelName[6] = SideLeft;
1488         device->ChannelName[7] = SideRight;
1489         break;
1490     case DevFmtBFormat3D:
1491         device->ChannelName[0] = BFormatW;
1492         device->ChannelName[1] = BFormatX;
1493         device->ChannelName[2] = BFormatY;
1494         device->ChannelName[3] = BFormatZ;
1495         break;
1496     }
1497 }
1498
1499 /* SetDefaultChannelOrder
1500  *
1501  * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1502  */
1503 void SetDefaultChannelOrder(ALCdevice *device)
1504 {
1505     ALuint i;
1506
1507     for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
1508         device->ChannelName[i] = InvalidChannel;
1509
1510     switch(device->FmtChans)
1511     {
1512     case DevFmtX51Rear:
1513         device->ChannelName[0] = FrontLeft;
1514         device->ChannelName[1] = FrontRight;
1515         device->ChannelName[2] = BackLeft;
1516         device->ChannelName[3] = BackRight;
1517         device->ChannelName[4] = FrontCenter;
1518         device->ChannelName[5] = LFE;
1519         return;
1520     case DevFmtX71:
1521         device->ChannelName[0] = FrontLeft;
1522         device->ChannelName[1] = FrontRight;
1523         device->ChannelName[2] = BackLeft;
1524         device->ChannelName[3] = BackRight;
1525         device->ChannelName[4] = FrontCenter;
1526         device->ChannelName[5] = LFE;
1527         device->ChannelName[6] = SideLeft;
1528         device->ChannelName[7] = SideRight;
1529         return;
1530
1531     /* Same as WFX order */
1532     case DevFmtMono:
1533     case DevFmtStereo:
1534     case DevFmtQuad:
1535     case DevFmtX51:
1536     case DevFmtX61:
1537     case DevFmtBFormat3D:
1538         SetDefaultWFXChannelOrder(device);
1539         break;
1540     }
1541 }
1542
1543 extern inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan);
1544
1545
1546 /* ALCcontext_DeferUpdates
1547  *
1548  * Defers/suspends updates for the given context's listener and sources. This
1549  * does *NOT* stop mixing, but rather prevents certain property changes from
1550  * taking effect.
1551  */
1552 void ALCcontext_DeferUpdates(ALCcontext *context)
1553 {
1554     ALCdevice *device = context->Device;
1555     FPUCtl oldMode;
1556
1557     SetMixerFPUMode(&oldMode);
1558
1559     V0(device->Backend,lock)();
1560     if(!context->DeferUpdates)
1561     {
1562         context->DeferUpdates = AL_TRUE;
1563
1564         /* Make sure all pending updates are performed */
1565         UpdateContextSources(context);
1566 #define UPDATE_SLOT(iter) do {                                   \
1567     if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \
1568         V((*iter)->EffectState,update)(device, *iter);           \
1569 } while(0)
1570         VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT);
1571 #undef UPDATE_SLOT
1572     }
1573     V0(device->Backend,unlock)();
1574
1575     RestoreFPUMode(&oldMode);
1576 }
1577
1578 /* ALCcontext_ProcessUpdates
1579  *
1580  * Resumes update processing after being deferred.
1581  */
1582 void ALCcontext_ProcessUpdates(ALCcontext *context)
1583 {
1584     ALCdevice *device = context->Device;
1585
1586     V0(device->Backend,lock)();
1587     if(context->DeferUpdates)
1588     {
1589         ALsizei pos;
1590
1591         context->DeferUpdates = AL_FALSE;
1592
1593         LockUIntMapRead(&context->SourceMap);
1594         for(pos = 0;pos < context->SourceMap.size;pos++)
1595         {
1596             ALsource *Source = context->SourceMap.array[pos].value;
1597             ALenum new_state;
1598
1599             if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
1600                Source->Offset >= 0.0)
1601             {
1602                 WriteLock(&Source->queue_lock);
1603                 ApplyOffset(Source);
1604                 WriteUnlock(&Source->queue_lock);
1605             }
1606
1607             new_state = Source->new_state;
1608             Source->new_state = AL_NONE;
1609             if(new_state)
1610                 SetSourceState(Source, context, new_state);
1611         }
1612         UnlockUIntMapRead(&context->SourceMap);
1613     }
1614     V0(device->Backend,unlock)();
1615 }
1616
1617
1618 /* alcSetError
1619  *
1620  * Stores the latest ALC device error
1621  */
1622 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1623 {
1624     if(TrapALCError)
1625     {
1626 #ifdef _WIN32
1627         /* DebugBreak() will cause an exception if there is no debugger */
1628         if(IsDebuggerPresent())
1629             DebugBreak();
1630 #elif defined(SIGTRAP)
1631         raise(SIGTRAP);
1632 #endif
1633     }
1634
1635     if(device)
1636         ATOMIC_STORE(&device->LastError, errorCode);
1637     else
1638         ATOMIC_STORE(&LastNullDeviceError, errorCode);
1639 }
1640
1641
1642 /* UpdateClockBase
1643  *
1644  * Updates the device's base clock time with however many samples have been
1645  * done. This is used so frequency changes on the device don't cause the time
1646  * to jump forward or back.
1647  */
1648 static inline void UpdateClockBase(ALCdevice *device)
1649 {
1650     device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1651     device->SamplesDone = 0;
1652 }
1653
1654 /* UpdateDeviceParams
1655  *
1656  * Updates device parameters according to the attribute list (caller is
1657  * responsible for holding the list lock).
1658  */
1659 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1660 {
1661     ALCcontext *context;
1662     enum HrtfRequestMode hrtf_appreq = Hrtf_Default;
1663     enum HrtfRequestMode hrtf_userreq = Hrtf_Default;
1664     enum DevFmtChannels oldChans;
1665     enum DevFmtType oldType;
1666     ALCuint oldFreq;
1667     FPUCtl oldMode;
1668     ALCsizei hrtf_id = -1;
1669     size_t size;
1670
1671     // Check for attributes
1672     if(device->Type == Loopback)
1673     {
1674         enum {
1675             GotFreq  = 1<<0,
1676             GotChans = 1<<1,
1677             GotType  = 1<<2,
1678             GotAll   = GotFreq|GotChans|GotType
1679         };
1680         ALCuint freq, numMono, numStereo, numSends;
1681         enum DevFmtChannels schans;
1682         enum DevFmtType stype;
1683         ALCuint attrIdx = 0;
1684         ALCint gotFmt = 0;
1685
1686         if(!attrList)
1687         {
1688             WARN("Missing attributes for loopback device\n");
1689             return ALC_INVALID_VALUE;
1690         }
1691
1692         numMono = device->NumMonoSources;
1693         numStereo = device->NumStereoSources;
1694         numSends = device->NumAuxSends;
1695         schans = device->FmtChans;
1696         stype = device->FmtType;
1697         freq = device->Frequency;
1698
1699         while(attrList[attrIdx])
1700         {
1701             if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1702             {
1703                 ALCint val = attrList[attrIdx + 1];
1704                 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1705                     return ALC_INVALID_VALUE;
1706                 schans = val;
1707                 gotFmt |= GotChans;
1708             }
1709
1710             if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1711             {
1712                 ALCint val = attrList[attrIdx + 1];
1713                 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1714                     return ALC_INVALID_VALUE;
1715                 stype = val;
1716                 gotFmt |= GotType;
1717             }
1718
1719             if(attrList[attrIdx] == ALC_FREQUENCY)
1720             {
1721                 freq = attrList[attrIdx + 1];
1722                 if(freq < MIN_OUTPUT_RATE)
1723                     return ALC_INVALID_VALUE;
1724                 gotFmt |= GotFreq;
1725             }
1726
1727             if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1728             {
1729                 numStereo = attrList[attrIdx + 1];
1730                 if(numStereo > device->MaxNoOfSources)
1731                     numStereo = device->MaxNoOfSources;
1732
1733                 numMono = device->MaxNoOfSources - numStereo;
1734             }
1735
1736             if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1737                 numSends = attrList[attrIdx + 1];
1738
1739             if(attrList[attrIdx] == ALC_HRTF_SOFT)
1740             {
1741                 if(attrList[attrIdx + 1] == ALC_FALSE)
1742                     hrtf_appreq = Hrtf_Disable;
1743                 else if(attrList[attrIdx + 1] == ALC_TRUE)
1744                     hrtf_appreq = Hrtf_Enable;
1745                 else
1746                     hrtf_appreq = Hrtf_Default;
1747             }
1748
1749             if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1750                 hrtf_id = attrList[attrIdx + 1];
1751
1752             attrIdx += 2;
1753         }
1754
1755         if(gotFmt != GotAll)
1756         {
1757             WARN("Missing format for loopback device\n");
1758             return ALC_INVALID_VALUE;
1759         }
1760
1761         ConfigValueUInt(NULL, NULL, "sends", &numSends);
1762         numSends = minu(MAX_SENDS, numSends);
1763
1764         if((device->Flags&DEVICE_RUNNING))
1765             V0(device->Backend,stop)();
1766         device->Flags &= ~DEVICE_RUNNING;
1767
1768         UpdateClockBase(device);
1769
1770         device->Frequency = freq;
1771         device->FmtChans = schans;
1772         device->FmtType = stype;
1773         device->NumMonoSources = numMono;
1774         device->NumStereoSources = numStereo;
1775         device->NumAuxSends = numSends;
1776     }
1777     else if(attrList && attrList[0])
1778     {
1779         ALCuint freq, numMono, numStereo, numSends;
1780         ALCuint attrIdx = 0;
1781
1782         /* If a context is already running on the device, stop playback so the
1783          * device attributes can be updated. */
1784         if((device->Flags&DEVICE_RUNNING))
1785             V0(device->Backend,stop)();
1786         device->Flags &= ~DEVICE_RUNNING;
1787
1788         freq = device->Frequency;
1789         numMono = device->NumMonoSources;
1790         numStereo = device->NumStereoSources;
1791         numSends = device->NumAuxSends;
1792
1793         while(attrList[attrIdx])
1794         {
1795             if(attrList[attrIdx] == ALC_FREQUENCY)
1796             {
1797                 freq = attrList[attrIdx + 1];
1798                 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1799             }
1800
1801             if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1802             {
1803                 numStereo = attrList[attrIdx + 1];
1804                 if(numStereo > device->MaxNoOfSources)
1805                     numStereo = device->MaxNoOfSources;
1806
1807                 numMono = device->MaxNoOfSources - numStereo;
1808             }
1809
1810             if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1811                 numSends = attrList[attrIdx + 1];
1812
1813             if(attrList[attrIdx] == ALC_HRTF_SOFT)
1814             {
1815                 if(attrList[attrIdx + 1] == ALC_FALSE)
1816                     hrtf_appreq = Hrtf_Disable;
1817                 else if(attrList[attrIdx + 1] == ALC_TRUE)
1818                     hrtf_appreq = Hrtf_Enable;
1819                 else
1820                     hrtf_appreq = Hrtf_Default;
1821             }
1822
1823             if(attrList[attrIdx] == ALC_HRTF_ID_SOFT)
1824                 hrtf_id = attrList[attrIdx + 1];
1825
1826             attrIdx += 2;
1827         }
1828
1829         ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq);
1830         freq = maxu(freq, MIN_OUTPUT_RATE);
1831
1832         ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends);
1833         numSends = minu(MAX_SENDS, numSends);
1834
1835         UpdateClockBase(device);
1836
1837         device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1838                              device->Frequency;
1839         /* SSE and Neon do best with the update size being a multiple of 4 */
1840         if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1841             device->UpdateSize = (device->UpdateSize+3)&~3;
1842
1843         device->Frequency = freq;
1844         device->NumMonoSources = numMono;
1845         device->NumStereoSources = numStereo;
1846         device->NumAuxSends = numSends;
1847     }
1848
1849     if((device->Flags&DEVICE_RUNNING))
1850         return ALC_NO_ERROR;
1851
1852     al_free(device->DryBuffer);
1853     device->DryBuffer = NULL;
1854
1855     UpdateClockBase(device);
1856
1857     device->Hrtf_Status = ALC_HRTF_DISABLED_SOFT;
1858     if(device->Type != Loopback)
1859     {
1860         const char *hrtf;
1861         if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf", &hrtf))
1862         {
1863             if(strcasecmp(hrtf, "true") == 0)
1864                 hrtf_userreq = Hrtf_Enable;
1865             else if(strcasecmp(hrtf, "false") == 0)
1866                 hrtf_userreq = Hrtf_Disable;
1867             else if(strcasecmp(hrtf, "auto") != 0)
1868                 ERR("Unexpected hrtf value: %s\n", hrtf);
1869         }
1870
1871         if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
1872         {
1873             if(VECTOR_SIZE(device->Hrtf_List) == 0)
1874             {
1875                 VECTOR_DEINIT(device->Hrtf_List);
1876                 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1877             }
1878             if(VECTOR_SIZE(device->Hrtf_List) > 0)
1879             {
1880                 device->FmtChans = DevFmtStereo;
1881                 if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
1882                     device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, hrtf_id).hrtf);
1883                 else
1884                     device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
1885                 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
1886             }
1887             else
1888             {
1889                 hrtf_userreq = hrtf_appreq = Hrtf_Default;
1890                 device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1891             }
1892         }
1893     }
1894     else if(hrtf_appreq == Hrtf_Enable)
1895     {
1896         size_t i;
1897         /* Loopback device. We don't need to match to a specific HRTF entry
1898          * here. If the requested ID matches, we'll pick that later, if not,
1899          * we'll try to auto-select one anyway. */
1900         if(device->FmtChans != DevFmtStereo)
1901             i = VECTOR_SIZE(device->Hrtf_List);
1902         else
1903         {
1904             if(VECTOR_SIZE(device->Hrtf_List) == 0)
1905             {
1906                 VECTOR_DEINIT(device->Hrtf_List);
1907                 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
1908             }
1909             for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
1910             {
1911                 const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
1912                 if(GetHrtfSampleRate(hrtf) == device->Frequency)
1913                     break;
1914             }
1915         }
1916         if(i == VECTOR_SIZE(device->Hrtf_List))
1917         {
1918             ERR("Requested format not HRTF compatible: %s, %uhz\n",
1919                 DevFmtChannelsString(device->FmtChans), device->Frequency);
1920             hrtf_appreq = Hrtf_Default;
1921             device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1922         }
1923     }
1924
1925     oldFreq  = device->Frequency;
1926     oldChans = device->FmtChans;
1927     oldType  = device->FmtType;
1928
1929     TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1930         (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
1931         (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
1932         (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
1933         device->UpdateSize, device->NumUpdates
1934     );
1935
1936     if(V0(device->Backend,reset)() == ALC_FALSE)
1937         return ALC_INVALID_DEVICE;
1938
1939     if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1940     {
1941         ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1942             DevFmtChannelsString(device->FmtChans));
1943         device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1944     }
1945     if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1946     {
1947         ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1948             DevFmtTypeString(device->FmtType));
1949         device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1950     }
1951     if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1952     {
1953         ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1954         device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1955     }
1956
1957     TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1958         DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
1959         device->Frequency, device->UpdateSize, device->NumUpdates
1960     );
1961
1962     if((device->UpdateSize&3) != 0)
1963     {
1964         if((CPUCapFlags&CPU_CAP_SSE))
1965             WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1966         if((CPUCapFlags&CPU_CAP_NEON))
1967             WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1968     }
1969
1970     device->Hrtf = NULL;
1971     device->Hrtf_Mode = DisabledHrtf;
1972     al_string_clear(&device->Hrtf_Name);
1973     if(device->FmtChans != DevFmtStereo)
1974     {
1975         if(hrtf_appreq == Hrtf_Enable)
1976             device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
1977
1978         free(device->Bs2b);
1979         device->Bs2b = NULL;
1980     }
1981     else
1982     {
1983         bool headphones = device->IsHeadphones;
1984         enum HrtfMode hrtf_mode = FullHrtf;
1985         ALCenum hrtf_status = device->Hrtf_Status;
1986         const char *mode;
1987         int bs2blevel;
1988         int usehrtf;
1989
1990         if(device->Type != Loopback)
1991         {
1992             if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "stereo-mode", &mode))
1993             {
1994                 if(strcasecmp(mode, "headphones") == 0)
1995                     headphones = true;
1996                 else if(strcasecmp(mode, "speakers") == 0)
1997                     headphones = false;
1998                 else if(strcasecmp(mode, "auto") != 0)
1999                     ERR("Unexpected stereo-mode: %s\n", mode);
2000             }
2001
2002             if(ConfigValueStr(al_string_get_cstr(device->DeviceName), NULL, "hrtf-mode", &mode))
2003             {
2004                 if(strcasecmp(mode, "full") == 0)
2005                     hrtf_mode = FullHrtf;
2006                 else if(strcasecmp(mode, "basic") == 0)
2007                     hrtf_mode = BasicHrtf;
2008                 else
2009                     ERR("Unexpected hrtf-mode: %s\n", mode);
2010             }
2011         }
2012
2013
2014         if(hrtf_userreq == Hrtf_Default)
2015         {
2016             usehrtf = (headphones && hrtf_appreq != Hrtf_Disable) ||
2017                       (hrtf_appreq == Hrtf_Enable);
2018             if(headphones && hrtf_appreq != Hrtf_Disable)
2019                 hrtf_status = ALC_HRTF_HEADPHONES_DETECTED_SOFT;
2020             else if(usehrtf)
2021                 hrtf_status = ALC_HRTF_ENABLED_SOFT;
2022         }
2023         else
2024         {
2025             usehrtf = (hrtf_userreq == Hrtf_Enable);
2026             if(!usehrtf)
2027                 hrtf_status = ALC_HRTF_DENIED_SOFT;
2028             else
2029                 hrtf_status = ALC_HRTF_REQUIRED_SOFT;
2030         }
2031
2032         if(!usehrtf)
2033             device->Hrtf_Status = hrtf_status;
2034         else
2035         {
2036             size_t i;
2037
2038             device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
2039             if(VECTOR_SIZE(device->Hrtf_List) == 0)
2040             {
2041                 VECTOR_DEINIT(device->Hrtf_List);
2042                 device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2043             }
2044
2045             if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf_List))
2046             {
2047                 const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, hrtf_id);
2048                 if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2049                 {
2050                     device->Hrtf = entry->hrtf;
2051                     al_string_copy(&device->Hrtf_Name, entry->name);
2052                 }
2053             }
2054             if(!device->Hrtf)
2055             {
2056                 for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
2057                 {
2058                     const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
2059                     if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
2060                     {
2061                         device->Hrtf = entry->hrtf;
2062                         al_string_copy(&device->Hrtf_Name, entry->name);
2063                         break;
2064                     }
2065                 }
2066             }
2067         }
2068         if(device->Hrtf)
2069         {
2070             device->Hrtf_Mode = hrtf_mode;
2071             device->Hrtf_Status = hrtf_status;
2072             TRACE("HRTF enabled, \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
2073             free(device->Bs2b);
2074             device->Bs2b = NULL;
2075         }
2076         else
2077         {
2078             TRACE("HRTF disabled\n");
2079
2080             bs2blevel = ((headphones && hrtf_appreq != Hrtf_Disable) ||
2081                          (hrtf_appreq == Hrtf_Enable)) ? 5 : 0;
2082             if(device->Type != Loopback)
2083                 ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "cf_level", &bs2blevel);
2084             if(bs2blevel > 0 && bs2blevel <= 6)
2085             {
2086                 if(!device->Bs2b)
2087                 {
2088                     device->Bs2b = calloc(1, sizeof(*device->Bs2b));
2089                     bs2b_clear(device->Bs2b);
2090                 }
2091                 bs2b_set_params(device->Bs2b, bs2blevel, device->Frequency);
2092                 TRACE("BS2B enabled\n");
2093             }
2094             else
2095             {
2096                 free(device->Bs2b);
2097                 device->Bs2b = NULL;
2098                 TRACE("BS2B disabled\n");
2099             }
2100         }
2101     }
2102
2103     aluInitPanning(device);
2104
2105     /* With HRTF, allocate two extra channels for the post-filter output. */
2106     size = sizeof(device->DryBuffer[0]) * (device->NumChannels + (device->Hrtf ? 2 : 0));
2107     device->DryBuffer = al_calloc(16, size);
2108     if(!device->DryBuffer)
2109     {
2110         ERR("Failed to allocate "SZFMT" bytes for mix buffer\n", size);
2111         return ALC_INVALID_DEVICE;
2112     }
2113
2114     SetMixerFPUMode(&oldMode);
2115     V0(device->Backend,lock)();
2116     context = ATOMIC_LOAD(&device->ContextList);
2117     while(context)
2118     {
2119         ALsizei pos;
2120
2121         ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
2122         LockUIntMapRead(&context->EffectSlotMap);
2123         for(pos = 0;pos < context->EffectSlotMap.size;pos++)
2124         {
2125             ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
2126
2127             if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2128             {
2129                 UnlockUIntMapRead(&context->EffectSlotMap);
2130                 V0(device->Backend,unlock)();
2131                 RestoreFPUMode(&oldMode);
2132                 return ALC_INVALID_DEVICE;
2133             }
2134             ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2135             V(slot->EffectState,update)(device, slot);
2136         }
2137         UnlockUIntMapRead(&context->EffectSlotMap);
2138
2139         LockUIntMapRead(&context->SourceMap);
2140         for(pos = 0;pos < context->SourceMap.size;pos++)
2141         {
2142             ALsource *source = context->SourceMap.array[pos].value;
2143             ALuint s = device->NumAuxSends;
2144             while(s < MAX_SENDS)
2145             {
2146                 if(source->Send[s].Slot)
2147                     DecrementRef(&source->Send[s].Slot->ref);
2148                 source->Send[s].Slot = NULL;
2149                 source->Send[s].Gain = 1.0f;
2150                 source->Send[s].GainHF = 1.0f;
2151                 s++;
2152             }
2153             ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
2154         }
2155         UnlockUIntMapRead(&context->SourceMap);
2156
2157         for(pos = 0;pos < context->VoiceCount;pos++)
2158         {
2159             ALvoice *voice = &context->Voices[pos];
2160             ALsource *source = voice->Source;
2161             ALuint s = device->NumAuxSends;
2162
2163             while(s < MAX_SENDS)
2164             {
2165                 voice->Send[s].Moving = AL_FALSE;
2166                 voice->Send[s].Counter = 0;
2167                 s++;
2168             }
2169
2170             if(source)
2171             {
2172                 ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
2173                 voice->Update(voice, source, context);
2174             }
2175         }
2176
2177         context = context->next;
2178     }
2179     if(device->DefaultSlot)
2180     {
2181         ALeffectslot *slot = device->DefaultSlot;
2182
2183         if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
2184         {
2185             V0(device->Backend,unlock)();
2186             RestoreFPUMode(&oldMode);
2187             return ALC_INVALID_DEVICE;
2188         }
2189         ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE);
2190         V(slot->EffectState,update)(device, slot);
2191     }
2192     V0(device->Backend,unlock)();
2193     RestoreFPUMode(&oldMode);
2194
2195     if(!(device->Flags&DEVICE_PAUSED))
2196     {
2197         if(V0(device->Backend,start)() == ALC_FALSE)
2198             return ALC_INVALID_DEVICE;
2199         device->Flags |= DEVICE_RUNNING;
2200     }
2201
2202     return ALC_NO_ERROR;
2203 }
2204
2205 /* FreeDevice
2206  *
2207  * Frees the device structure, and destroys any objects the app failed to
2208  * delete. Called once there's no more references on the device.
2209  */
2210 static ALCvoid FreeDevice(ALCdevice *device)
2211 {
2212     TRACE("%p\n", device);
2213
2214     V0(device->Backend,close)();
2215     DELETE_OBJ(device->Backend);
2216     device->Backend = NULL;
2217
2218     if(device->DefaultSlot)
2219     {
2220         ALeffectState *state = device->DefaultSlot->EffectState;
2221         device->DefaultSlot = NULL;
2222         DELETE_OBJ(state);
2223     }
2224
2225     if(device->BufferMap.size > 0)
2226     {
2227         WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
2228         ReleaseALBuffers(device);
2229     }
2230     ResetUIntMap(&device->BufferMap);
2231
2232     if(device->EffectMap.size > 0)
2233     {
2234         WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2235         ReleaseALEffects(device);
2236     }
2237     ResetUIntMap(&device->EffectMap);
2238
2239     if(device->FilterMap.size > 0)
2240     {
2241         WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2242         ReleaseALFilters(device);
2243     }
2244     ResetUIntMap(&device->FilterMap);
2245
2246     AL_STRING_DEINIT(device->Hrtf_Name);
2247     FreeHrtfList(&device->Hrtf_List);
2248
2249     free(device->Bs2b);
2250     device->Bs2b = NULL;
2251
2252     AL_STRING_DEINIT(device->DeviceName);
2253
2254     al_free(device->DryBuffer);
2255     device->DryBuffer = NULL;
2256
2257     al_free(device);
2258 }
2259
2260
2261 void ALCdevice_IncRef(ALCdevice *device)
2262 {
2263     uint ref;
2264     ref = IncrementRef(&device->ref);
2265     TRACEREF("%p increasing refcount to %u\n", device, ref);
2266 }
2267
2268 void ALCdevice_DecRef(ALCdevice *device)
2269 {
2270     uint ref;
2271     ref = DecrementRef(&device->ref);
2272     TRACEREF("%p decreasing refcount to %u\n", device, ref);
2273     if(ref == 0) FreeDevice(device);
2274 }
2275
2276 /* VerifyDevice
2277  *
2278  * Checks if the device handle is valid, and increments its ref count if so.
2279  */
2280 static ALCboolean VerifyDevice(ALCdevice **device)
2281 {
2282     ALCdevice *tmpDevice;
2283
2284     LockLists();
2285     tmpDevice = ATOMIC_LOAD(&DeviceList);
2286     while(tmpDevice)
2287     {
2288         if(tmpDevice == *device)
2289         {
2290             ALCdevice_IncRef(tmpDevice);
2291             UnlockLists();
2292             return ALC_TRUE;
2293         }
2294         tmpDevice = tmpDevice->next;
2295     }
2296     UnlockLists();
2297
2298     *device = NULL;
2299     return ALC_FALSE;
2300 }
2301
2302
2303 /* InitContext
2304  *
2305  * Initializes context fields
2306  */
2307 static ALvoid InitContext(ALCcontext *Context)
2308 {
2309     ALlistener *listener = Context->Listener;
2310     //Initialise listener
2311     listener->Gain = 1.0f;
2312     listener->MetersPerUnit = 1.0f;
2313     aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
2314     aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2315     listener->Forward[0] = 0.0f;
2316     listener->Forward[1] = 0.0f;
2317     listener->Forward[2] = -1.0f;
2318     listener->Up[0] = 0.0f;
2319     listener->Up[1] = 1.0f;
2320     listener->Up[2] = 0.0f;
2321     aluMatrixdSet(&listener->Params.Matrix,
2322         1.0, 0.0, 0.0, 0.0,
2323         0.0, 1.0, 0.0, 0.0,
2324         0.0, 0.0, 1.0, 0.0,
2325         0.0, 0.0, 0.0, 1.0
2326     );
2327     aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
2328
2329     //Validate Context
2330     ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
2331     ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
2332     InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2333     InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2334
2335     //Set globals
2336     Context->DistanceModel = DefaultDistanceModel;
2337     Context->SourceDistanceModel = AL_FALSE;
2338     Context->DopplerFactor = 1.0f;
2339     Context->DopplerVelocity = 1.0f;
2340     Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2341     Context->DeferUpdates = AL_FALSE;
2342
2343     Context->ExtensionList = alExtList;
2344 }
2345
2346
2347 /* FreeContext
2348  *
2349  * Cleans up the context, and destroys any remaining objects the app failed to
2350  * delete. Called once there's no more references on the context.
2351  */
2352 static void FreeContext(ALCcontext *context)
2353 {
2354     TRACE("%p\n", context);
2355
2356     if(context->SourceMap.size > 0)
2357     {
2358         WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2359         ReleaseALSources(context);
2360     }
2361     ResetUIntMap(&context->SourceMap);
2362
2363     if(context->EffectSlotMap.size > 0)
2364     {
2365         WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2366         ReleaseALAuxiliaryEffectSlots(context);
2367     }
2368     ResetUIntMap(&context->EffectSlotMap);
2369
2370     al_free(context->Voices);
2371     context->Voices = NULL;
2372     context->VoiceCount = 0;
2373     context->MaxVoices = 0;
2374
2375     VECTOR_DEINIT(context->ActiveAuxSlots);
2376
2377     ALCdevice_DecRef(context->Device);
2378     context->Device = NULL;
2379
2380     //Invalidate context
2381     memset(context, 0, sizeof(ALCcontext));
2382     al_free(context);
2383 }
2384
2385 /* ReleaseContext
2386  *
2387  * Removes the context reference from the given device and removes it from
2388  * being current on the running thread or globally.
2389  */
2390 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2391 {
2392     ALCcontext *nextctx;
2393     ALCcontext *origctx;
2394
2395     if(altss_get(LocalContext) == context)
2396     {
2397         WARN("%p released while current on thread\n", context);
2398         altss_set(LocalContext, NULL);
2399         ALCcontext_DecRef(context);
2400     }
2401
2402     origctx = context;
2403     if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL))
2404         ALCcontext_DecRef(context);
2405
2406     ALCdevice_Lock(device);
2407     origctx = context;
2408     nextctx = context->next;
2409     if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, nextctx))
2410     {
2411         ALCcontext *list;
2412         do {
2413             list = origctx;
2414             origctx = context;
2415         } while(!COMPARE_EXCHANGE(&list->next, &origctx, nextctx));
2416     }
2417     ALCdevice_Unlock(device);
2418
2419     ALCcontext_DecRef(context);
2420 }
2421
2422 void ALCcontext_IncRef(ALCcontext *context)
2423 {
2424     uint ref;
2425     ref = IncrementRef(&context->ref);
2426     TRACEREF("%p increasing refcount to %u\n", context, ref);
2427 }
2428
2429 void ALCcontext_DecRef(ALCcontext *context)
2430 {
2431     uint ref;
2432     ref = DecrementRef(&context->ref);
2433     TRACEREF("%p decreasing refcount to %u\n", context, ref);
2434     if(ref == 0) FreeContext(context);
2435 }
2436
2437 static void ReleaseThreadCtx(void *ptr)
2438 {
2439     WARN("%p current for thread being destroyed\n", ptr);
2440     ALCcontext_DecRef(ptr);
2441 }
2442
2443 /* VerifyContext
2444  *
2445  * Checks that the given context is valid, and increments its reference count.
2446  */
2447 static ALCboolean VerifyContext(ALCcontext **context)
2448 {
2449     ALCdevice *dev;
2450
2451     LockLists();
2452     dev = ATOMIC_LOAD(&DeviceList);
2453     while(dev)
2454     {
2455         ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList);
2456         while(ctx)
2457         {
2458             if(ctx == *context)
2459             {
2460                 ALCcontext_IncRef(ctx);
2461                 UnlockLists();
2462                 return ALC_TRUE;
2463             }
2464             ctx = ctx->next;
2465         }
2466         dev = dev->next;
2467     }
2468     UnlockLists();
2469
2470     *context = NULL;
2471     return ALC_FALSE;
2472 }
2473
2474
2475 /* GetContextRef
2476  *
2477  * Returns the currently active context for this thread, and adds a reference
2478  * without locking it.
2479  */
2480 ALCcontext *GetContextRef(void)
2481 {
2482     ALCcontext *context;
2483
2484     context = altss_get(LocalContext);
2485     if(context)
2486         ALCcontext_IncRef(context);
2487     else
2488     {
2489         LockLists();
2490         context = ATOMIC_LOAD(&GlobalContext);
2491         if(context)
2492             ALCcontext_IncRef(context);
2493         UnlockLists();
2494     }
2495
2496     return context;
2497 }
2498
2499
2500 /************************************************
2501  * Standard ALC functions
2502  ************************************************/
2503
2504 /* alcGetError
2505  *
2506  * Return last ALC generated error code for the given device
2507 */
2508 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2509 {
2510     ALCenum errorCode;
2511
2512     if(VerifyDevice(&device))
2513     {
2514         errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR);
2515         ALCdevice_DecRef(device);
2516     }
2517     else
2518         errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR);
2519
2520     return errorCode;
2521 }
2522
2523
2524 /* alcSuspendContext
2525  *
2526  * Suspends updates for the given context
2527  */
2528 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2529 {
2530     if(!SuspendDefers)
2531         return;
2532
2533     if(!VerifyContext(&context))
2534         alcSetError(NULL, ALC_INVALID_CONTEXT);
2535     else
2536     {
2537         ALCcontext_DeferUpdates(context);
2538         ALCcontext_DecRef(context);
2539     }
2540 }
2541
2542 /* alcProcessContext
2543  *
2544  * Resumes processing updates for the given context
2545  */
2546 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
2547 {
2548     if(!SuspendDefers)
2549         return;
2550
2551     if(!VerifyContext(&context))
2552         alcSetError(NULL, ALC_INVALID_CONTEXT);
2553     else
2554     {
2555         ALCcontext_ProcessUpdates(context);
2556         ALCcontext_DecRef(context);
2557     }
2558 }
2559
2560
2561 /* alcGetString
2562  *
2563  * Returns information about the device, and error strings
2564  */
2565 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2566 {
2567     const ALCchar *value = NULL;
2568
2569     switch(param)
2570     {
2571     case ALC_NO_ERROR:
2572         value = alcNoError;
2573         break;
2574
2575     case ALC_INVALID_ENUM:
2576         value = alcErrInvalidEnum;
2577         break;
2578
2579     case ALC_INVALID_VALUE:
2580         value = alcErrInvalidValue;
2581         break;
2582
2583     case ALC_INVALID_DEVICE:
2584         value = alcErrInvalidDevice;
2585         break;
2586
2587     case ALC_INVALID_CONTEXT:
2588         value = alcErrInvalidContext;
2589         break;
2590
2591     case ALC_OUT_OF_MEMORY:
2592         value = alcErrOutOfMemory;
2593         break;
2594
2595     case ALC_DEVICE_SPECIFIER:
2596         value = alcDefaultName;
2597         break;
2598
2599     case ALC_ALL_DEVICES_SPECIFIER:
2600         if(VerifyDevice(&Device))
2601         {
2602             value = al_string_get_cstr(Device->DeviceName);
2603             ALCdevice_DecRef(Device);
2604         }
2605         else
2606         {
2607             ProbeAllDevicesList();
2608             value = al_string_get_cstr(alcAllDevicesList);
2609         }
2610         break;
2611
2612     case ALC_CAPTURE_DEVICE_SPECIFIER:
2613         if(VerifyDevice(&Device))
2614         {
2615             value = al_string_get_cstr(Device->DeviceName);
2616             ALCdevice_DecRef(Device);
2617         }
2618         else
2619         {
2620             ProbeCaptureDeviceList();
2621             value = al_string_get_cstr(alcCaptureDeviceList);
2622         }
2623         break;
2624
2625     /* Default devices are always first in the list */
2626     case ALC_DEFAULT_DEVICE_SPECIFIER:
2627         value = alcDefaultName;
2628         break;
2629
2630     case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2631         if(al_string_empty(alcAllDevicesList))
2632             ProbeAllDevicesList();
2633
2634         VerifyDevice(&Device);
2635
2636         free(alcDefaultAllDevicesSpecifier);
2637         alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2638         if(!alcDefaultAllDevicesSpecifier)
2639             alcSetError(Device, ALC_OUT_OF_MEMORY);
2640
2641         value = alcDefaultAllDevicesSpecifier;
2642         if(Device) ALCdevice_DecRef(Device);
2643         break;
2644
2645     case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2646         if(al_string_empty(alcCaptureDeviceList))
2647             ProbeCaptureDeviceList();
2648
2649         VerifyDevice(&Device);
2650
2651         free(alcCaptureDefaultDeviceSpecifier);
2652         alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcCaptureDeviceList));
2653         if(!alcCaptureDefaultDeviceSpecifier)
2654             alcSetError(Device, ALC_OUT_OF_MEMORY);
2655
2656         value = alcCaptureDefaultDeviceSpecifier;
2657         if(Device) ALCdevice_DecRef(Device);
2658         break;
2659
2660     case ALC_EXTENSIONS:
2661         if(!VerifyDevice(&Device))
2662             value = alcNoDeviceExtList;
2663         else
2664         {
2665             value = alcExtensionList;
2666             ALCdevice_DecRef(Device);
2667         }
2668         break;
2669
2670     case ALC_HRTF_SPECIFIER_SOFT:
2671         if(!VerifyDevice(&Device))
2672             alcSetError(NULL, ALC_INVALID_DEVICE);
2673         else
2674         {
2675             LockLists();
2676             value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
2677             UnlockLists();
2678             ALCdevice_DecRef(Device);
2679         }
2680         break;
2681
2682     default:
2683         VerifyDevice(&Device);
2684         alcSetError(Device, ALC_INVALID_ENUM);
2685         if(Device) ALCdevice_DecRef(Device);
2686         break;
2687     }
2688
2689     return value;
2690 }
2691
2692
2693 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2694 {
2695     ALCsizei i;
2696
2697     if(size <= 0 || values == NULL)
2698     {
2699         alcSetError(device, ALC_INVALID_VALUE);
2700         return 0;
2701     }
2702
2703     if(!device)
2704     {
2705         switch(param)
2706         {
2707             case ALC_MAJOR_VERSION:
2708                 values[0] = alcMajorVersion;
2709                 return 1;
2710             case ALC_MINOR_VERSION:
2711                 values[0] = alcMinorVersion;
2712                 return 1;
2713
2714             case ALC_ATTRIBUTES_SIZE:
2715             case ALC_ALL_ATTRIBUTES:
2716             case ALC_FREQUENCY:
2717             case ALC_REFRESH:
2718             case ALC_SYNC:
2719             case ALC_MONO_SOURCES:
2720             case ALC_STEREO_SOURCES:
2721             case ALC_CAPTURE_SAMPLES:
2722             case ALC_FORMAT_CHANNELS_SOFT:
2723             case ALC_FORMAT_TYPE_SOFT:
2724                 alcSetError(NULL, ALC_INVALID_DEVICE);
2725                 return 0;
2726
2727             default:
2728                 alcSetError(NULL, ALC_INVALID_ENUM);
2729                 return 0;
2730         }
2731         return 0;
2732     }
2733
2734     if(device->Type == Capture)
2735     {
2736         switch(param)
2737         {
2738             case ALC_CAPTURE_SAMPLES:
2739                 V0(device->Backend,lock)();
2740                 values[0] = V0(device->Backend,availableSamples)();
2741                 V0(device->Backend,unlock)();
2742                 return 1;
2743
2744             case ALC_CONNECTED:
2745                 values[0] = device->Connected;
2746                 return 1;
2747
2748             default:
2749                 alcSetError(device, ALC_INVALID_ENUM);
2750                 return 0;
2751         }
2752         return 0;
2753     }
2754
2755     /* render device */
2756     switch(param)
2757     {
2758         case ALC_MAJOR_VERSION:
2759             values[0] = alcMajorVersion;
2760             return 1;
2761
2762         case ALC_MINOR_VERSION:
2763             values[0] = alcMinorVersion;
2764             return 1;
2765
2766         case ALC_EFX_MAJOR_VERSION:
2767             values[0] = alcEFXMajorVersion;
2768             return 1;
2769
2770         case ALC_EFX_MINOR_VERSION:
2771             values[0] = alcEFXMinorVersion;
2772             return 1;
2773
2774         case ALC_ATTRIBUTES_SIZE:
2775             values[0] = 17;
2776             return 1;
2777
2778         case ALC_ALL_ATTRIBUTES:
2779             if(size < 17)
2780             {
2781                 alcSetError(device, ALC_INVALID_VALUE);
2782                 return 0;
2783             }
2784
2785             i = 0;
2786             values[i++] = ALC_FREQUENCY;
2787             values[i++] = device->Frequency;
2788
2789             if(device->Type != Loopback)
2790             {
2791                 values[i++] = ALC_REFRESH;
2792                 values[i++] = device->Frequency / device->UpdateSize;
2793
2794                 values[i++] = ALC_SYNC;
2795                 values[i++] = ALC_FALSE;
2796             }
2797             else
2798             {
2799                 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2800                 values[i++] = device->FmtChans;
2801
2802                 values[i++] = ALC_FORMAT_TYPE_SOFT;
2803                 values[i++] = device->FmtType;
2804             }
2805
2806             values[i++] = ALC_MONO_SOURCES;
2807             values[i++] = device->NumMonoSources;
2808
2809             values[i++] = ALC_STEREO_SOURCES;
2810             values[i++] = device->NumStereoSources;
2811
2812             values[i++] = ALC_MAX_AUXILIARY_SENDS;
2813             values[i++] = device->NumAuxSends;
2814
2815             values[i++] = ALC_HRTF_SOFT;
2816             values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2817
2818             values[i++] = ALC_HRTF_STATUS_SOFT;
2819             values[i++] = device->Hrtf_Status;
2820
2821             values[i++] = 0;
2822             return i;
2823
2824         case ALC_FREQUENCY:
2825             values[0] = device->Frequency;
2826             return 1;
2827
2828         case ALC_REFRESH:
2829             if(device->Type == Loopback)
2830             {
2831                 alcSetError(device, ALC_INVALID_DEVICE);
2832                 return 0;
2833             }
2834             values[0] = device->Frequency / device->UpdateSize;
2835             return 1;
2836
2837         case ALC_SYNC:
2838             if(device->Type == Loopback)
2839             {
2840                 alcSetError(device, ALC_INVALID_DEVICE);
2841                 return 0;
2842             }
2843             values[0] = ALC_FALSE;
2844             return 1;
2845
2846         case ALC_FORMAT_CHANNELS_SOFT:
2847             if(device->Type != Loopback)
2848             {
2849                 alcSetError(device, ALC_INVALID_DEVICE);
2850                 return 0;
2851             }
2852             values[0] = device->FmtChans;
2853             return 1;
2854
2855         case ALC_FORMAT_TYPE_SOFT:
2856             if(device->Type != Loopback)
2857             {
2858                 alcSetError(device, ALC_INVALID_DEVICE);
2859                 return 0;
2860             }
2861             values[0] = device->FmtType;
2862             return 1;
2863
2864         case ALC_MONO_SOURCES:
2865             values[0] = device->NumMonoSources;
2866             return 1;
2867
2868         case ALC_STEREO_SOURCES:
2869             values[0] = device->NumStereoSources;
2870             return 1;
2871
2872         case ALC_MAX_AUXILIARY_SENDS:
2873             values[0] = device->NumAuxSends;
2874             return 1;
2875
2876         case ALC_CONNECTED:
2877             values[0] = device->Connected;
2878             return 1;
2879
2880         case ALC_HRTF_SOFT:
2881             values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2882             return 1;
2883
2884         case ALC_HRTF_STATUS_SOFT:
2885             values[0] = device->Hrtf_Status;
2886             return 1;
2887
2888         case ALC_NUM_HRTF_SPECIFIERS_SOFT:
2889             FreeHrtfList(&device->Hrtf_List);
2890             device->Hrtf_List = EnumerateHrtf(device->DeviceName);
2891             values[0] = (ALCint)VECTOR_SIZE(device->Hrtf_List);
2892             return 1;
2893
2894         default:
2895             alcSetError(device, ALC_INVALID_ENUM);
2896             return 0;
2897     }
2898     return 0;
2899 }
2900
2901 /* alcGetIntegerv
2902  *
2903  * Returns information about the device and the version of OpenAL
2904  */
2905 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2906 {
2907     VerifyDevice(&device);
2908     if(size <= 0 || values == NULL)
2909         alcSetError(device, ALC_INVALID_VALUE);
2910     else
2911         GetIntegerv(device, param, size, values);
2912     if(device) ALCdevice_DecRef(device);
2913 }
2914
2915 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2916 {
2917     ALCint *ivals;
2918     ALsizei i;
2919
2920     VerifyDevice(&device);
2921     if(size <= 0 || values == NULL)
2922         alcSetError(device, ALC_INVALID_VALUE);
2923     else if(!device || device->Type == Capture)
2924     {
2925         ivals = malloc(size * sizeof(ALCint));
2926         size = GetIntegerv(device, pname, size, ivals);
2927         for(i = 0;i < size;i++)
2928             values[i] = ivals[i];
2929         free(ivals);
2930     }
2931     else /* render device */
2932     {
2933         switch(pname)
2934         {
2935             case ALC_ATTRIBUTES_SIZE:
2936                 *values = 19;
2937                 break;
2938
2939             case ALC_ALL_ATTRIBUTES:
2940                 if(size < 19)
2941                     alcSetError(device, ALC_INVALID_VALUE);
2942                 else
2943                 {
2944                     int i = 0;
2945
2946                     V0(device->Backend,lock)();
2947                     values[i++] = ALC_FREQUENCY;
2948                     values[i++] = device->Frequency;
2949
2950                     if(device->Type != Loopback)
2951                     {
2952                         values[i++] = ALC_REFRESH;
2953                         values[i++] = device->Frequency / device->UpdateSize;
2954
2955                         values[i++] = ALC_SYNC;
2956                         values[i++] = ALC_FALSE;
2957                     }
2958                     else
2959                     {
2960                         values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2961                         values[i++] = device->FmtChans;
2962
2963                         values[i++] = ALC_FORMAT_TYPE_SOFT;
2964                         values[i++] = device->FmtType;
2965                     }
2966
2967                     values[i++] = ALC_MONO_SOURCES;
2968                     values[i++] = device->NumMonoSources;
2969
2970                     values[i++] = ALC_STEREO_SOURCES;
2971                     values[i++] = device->NumStereoSources;
2972
2973                     values[i++] = ALC_MAX_AUXILIARY_SENDS;
2974                     values[i++] = device->NumAuxSends;
2975
2976                     values[i++] = ALC_HRTF_SOFT;
2977                     values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2978
2979                     values[i++] = ALC_HRTF_STATUS_SOFT;
2980                     values[i++] = device->Hrtf_Status;
2981
2982                     values[i++] = ALC_DEVICE_CLOCK_SOFT;
2983                     values[i++] = device->ClockBase +
2984                                   (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2985
2986                     values[i++] = 0;
2987                     V0(device->Backend,unlock)();
2988                 }
2989                 break;
2990
2991             case ALC_DEVICE_CLOCK_SOFT:
2992                 V0(device->Backend,lock)();
2993                 *values = device->ClockBase +
2994                           (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2995                 V0(device->Backend,unlock)();
2996                 break;
2997
2998             default:
2999                 ivals = malloc(size * sizeof(ALCint));
3000                 size = GetIntegerv(device, pname, size, ivals);
3001                 for(i = 0;i < size;i++)
3002                     values[i] = ivals[i];
3003                 free(ivals);
3004                 break;
3005         }
3006     }
3007     if(device)
3008         ALCdevice_DecRef(device);
3009 }
3010
3011
3012 /* alcIsExtensionPresent
3013  *
3014  * Determines if there is support for a particular extension
3015  */
3016 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3017 {
3018     ALCboolean bResult = ALC_FALSE;
3019
3020     VerifyDevice(&device);
3021
3022     if(!extName)
3023         alcSetError(device, ALC_INVALID_VALUE);
3024     else
3025     {
3026         size_t len = strlen(extName);
3027         const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
3028         while(ptr && *ptr)
3029         {
3030             if(strncasecmp(ptr, extName, len) == 0 &&
3031                (ptr[len] == '\0' || isspace(ptr[len])))
3032             {
3033                 bResult = ALC_TRUE;
3034                 break;
3035             }
3036             if((ptr=strchr(ptr, ' ')) != NULL)
3037             {
3038                 do {
3039                     ++ptr;
3040                 } while(isspace(*ptr));
3041             }
3042         }
3043     }
3044     if(device)
3045         ALCdevice_DecRef(device);
3046     return bResult;
3047 }
3048
3049
3050 /* alcGetProcAddress
3051  *
3052  * Retrieves the function address for a particular extension function
3053  */
3054 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3055 {
3056     ALCvoid *ptr = NULL;
3057
3058     if(!funcName)
3059     {
3060         VerifyDevice(&device);
3061         alcSetError(device, ALC_INVALID_VALUE);
3062         if(device) ALCdevice_DecRef(device);
3063     }
3064     else
3065     {
3066         ALsizei i = 0;
3067         while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
3068             i++;
3069         ptr = alcFunctions[i].address;
3070     }
3071
3072     return ptr;
3073 }
3074
3075
3076 /* alcGetEnumValue
3077  *
3078  * Get the value for a particular ALC enumeration name
3079  */
3080 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3081 {
3082     ALCenum val = 0;
3083
3084     if(!enumName)
3085     {
3086         VerifyDevice(&device);
3087         alcSetError(device, ALC_INVALID_VALUE);
3088         if(device) ALCdevice_DecRef(device);
3089     }
3090     else
3091     {
3092         ALsizei i = 0;
3093         while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
3094             i++;
3095         val = enumeration[i].value;
3096     }
3097
3098     return val;
3099 }
3100
3101
3102 /* alcCreateContext
3103  *
3104  * Create and attach a context to the given device.
3105  */
3106 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3107 {
3108     ALCcontext *ALContext;
3109     ALCenum err;
3110
3111     LockLists();
3112     if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3113     {
3114         UnlockLists();
3115         alcSetError(device, ALC_INVALID_DEVICE);
3116         if(device) ALCdevice_DecRef(device);
3117         return NULL;
3118     }
3119
3120     ATOMIC_STORE(&device->LastError, ALC_NO_ERROR);
3121
3122     if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
3123     {
3124         UnlockLists();
3125         alcSetError(device, err);
3126         if(err == ALC_INVALID_DEVICE)
3127         {
3128             V0(device->Backend,lock)();
3129             aluHandleDisconnect(device);
3130             V0(device->Backend,unlock)();
3131         }
3132         ALCdevice_DecRef(device);
3133         return NULL;
3134     }
3135
3136     ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener));
3137     if(ALContext)
3138     {
3139         InitRef(&ALContext->ref, 1);
3140         ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
3141
3142         VECTOR_INIT(ALContext->ActiveAuxSlots);
3143
3144         ALContext->VoiceCount = 0;
3145         ALContext->MaxVoices = 256;
3146         ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0]));
3147     }
3148     if(!ALContext || !ALContext->Voices)
3149     {
3150         if(!ATOMIC_LOAD(&device->ContextList))
3151         {
3152             V0(device->Backend,stop)();
3153             device->Flags &= ~DEVICE_RUNNING;
3154         }
3155         UnlockLists();
3156
3157         if(ALContext)
3158         {
3159             al_free(ALContext->Voices);
3160             ALContext->Voices = NULL;
3161
3162             VECTOR_DEINIT(ALContext->ActiveAuxSlots);
3163
3164             al_free(ALContext);
3165             ALContext = NULL;
3166         }
3167
3168         alcSetError(device, ALC_OUT_OF_MEMORY);
3169         ALCdevice_DecRef(device);
3170         return NULL;
3171     }
3172
3173     ALContext->Device = device;
3174     ALCdevice_IncRef(device);
3175     InitContext(ALContext);
3176
3177     {
3178         ALCcontext *head = ATOMIC_LOAD(&device->ContextList);
3179         do {
3180             ALContext->next = head;
3181         } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext));
3182     }
3183     UnlockLists();
3184
3185     ALCdevice_DecRef(device);
3186
3187     TRACE("Created context %p\n", ALContext);
3188     return ALContext;
3189 }
3190
3191 /* alcDestroyContext
3192  *
3193  * Remove a context from its device
3194  */
3195 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3196 {
3197     ALCdevice *Device;
3198
3199     LockLists();
3200     /* alcGetContextsDevice sets an error for invalid contexts */
3201     Device = alcGetContextsDevice(context);
3202     if(Device)
3203     {
3204         ReleaseContext(context, Device);
3205         if(!ATOMIC_LOAD(&Device->ContextList))
3206         {
3207             V0(Device->Backend,stop)();
3208             Device->Flags &= ~DEVICE_RUNNING;
3209         }
3210     }
3211     UnlockLists();
3212 }
3213
3214
3215 /* alcGetCurrentContext
3216  *
3217  * Returns the currently active context on the calling thread
3218  */
3219 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3220 {
3221     ALCcontext *Context = altss_get(LocalContext);
3222     if(!Context) Context = ATOMIC_LOAD(&GlobalContext);
3223     return Context;
3224 }
3225
3226 /* alcGetThreadContext
3227  *
3228  * Returns the currently active thread-local context
3229  */
3230 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3231 {
3232     return altss_get(LocalContext);
3233 }
3234
3235
3236 /* alcMakeContextCurrent
3237  *
3238  * Makes the given context the active process-wide context, and removes the
3239  * thread-local context for the calling thread.
3240  */
3241 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3242 {
3243     /* context must be valid or NULL */
3244     if(context && !VerifyContext(&context))
3245     {
3246         alcSetError(NULL, ALC_INVALID_CONTEXT);
3247         return ALC_FALSE;
3248     }
3249     /* context's reference count is already incremented */
3250     context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context);
3251     if(context) ALCcontext_DecRef(context);
3252
3253     if((context=altss_get(LocalContext)) != NULL)
3254     {
3255         altss_set(LocalContext, NULL);
3256         ALCcontext_DecRef(context);
3257     }
3258
3259     return ALC_TRUE;
3260 }
3261
3262 /* alcSetThreadContext
3263  *
3264  * Makes the given context the active context for the current thread
3265  */
3266 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3267 {
3268     ALCcontext *old;
3269
3270     /* context must be valid or NULL */
3271     if(context && !VerifyContext(&context))
3272     {
3273         alcSetError(NULL, ALC_INVALID_CONTEXT);
3274         return ALC_FALSE;
3275     }
3276     /* context's reference count is already incremented */
3277     old = altss_get(LocalContext);
3278     altss_set(LocalContext, context);
3279     if(old) ALCcontext_DecRef(old);
3280
3281     return ALC_TRUE;
3282 }
3283
3284
3285 /* alcGetContextsDevice
3286  *
3287  * Returns the device that a particular context is attached to
3288  */
3289 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3290 {
3291     ALCdevice *Device;
3292
3293     if(!VerifyContext(&Context))
3294     {
3295         alcSetError(NULL, ALC_INVALID_CONTEXT);
3296         return NULL;
3297     }
3298     Device = Context->Device;
3299     ALCcontext_DecRef(Context);
3300
3301     return Device;
3302 }
3303
3304
3305 /* alcOpenDevice
3306  *
3307  * Opens the named device.
3308  */
3309 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3310 {
3311     const ALCchar *fmt;
3312     ALCdevice *device;
3313     ALCenum err;
3314
3315     DO_INITCONFIG();
3316
3317     if(!PlaybackBackend.name)
3318     {
3319         alcSetError(NULL, ALC_INVALID_VALUE);
3320         return NULL;
3321     }
3322
3323     if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0
3324 #ifdef _WIN32
3325         /* Some old Windows apps hardcode these expecting OpenAL to use a
3326          * specific audio API, even when they're not enumerated. Creative's
3327          * router effectively ignores them too.
3328          */
3329         || strcasecmp(deviceName, "DirectSound3D") == 0 || strcasecmp(deviceName, "DirectSound") == 0
3330         || strcasecmp(deviceName, "MMSYSTEM") == 0
3331 #endif
3332     ))
3333         deviceName = NULL;
3334
3335     device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3336     if(!device)
3337     {
3338         alcSetError(NULL, ALC_OUT_OF_MEMORY);
3339         return NULL;
3340     }
3341
3342     //Validate device
3343     InitRef(&device->ref, 1);
3344     device->Connected = ALC_TRUE;
3345     device->Type = Playback;
3346     ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3347
3348     device->Flags = 0;
3349     device->Bs2b = NULL;
3350     VECTOR_INIT(device->Hrtf_List);
3351     AL_STRING_INIT(device->Hrtf_Name);
3352     device->Hrtf_Mode = DisabledHrtf;
3353     AL_STRING_INIT(device->DeviceName);
3354     device->DryBuffer = NULL;
3355
3356     ATOMIC_INIT(&device->ContextList, NULL);
3357
3358     device->ClockBase = 0;
3359     device->SamplesDone = 0;
3360
3361     device->MaxNoOfSources = 256;
3362     device->AuxiliaryEffectSlotMax = 4;
3363     device->NumAuxSends = MAX_SENDS;
3364
3365     InitUIntMap(&device->BufferMap, ~0);
3366     InitUIntMap(&device->EffectMap, ~0);
3367     InitUIntMap(&device->FilterMap, ~0);
3368
3369     //Set output format
3370     device->FmtChans = DevFmtChannelsDefault;
3371     device->FmtType = DevFmtTypeDefault;
3372     device->Frequency = DEFAULT_OUTPUT_RATE;
3373     device->IsHeadphones = AL_FALSE;
3374     device->NumUpdates = 4;
3375     device->UpdateSize = 1024;
3376
3377     if(!PlaybackBackend.getFactory)
3378         device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3379                                                  ALCbackend_Playback);
3380     else
3381     {
3382         ALCbackendFactory *factory = PlaybackBackend.getFactory();
3383         device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3384     }
3385     if(!device->Backend)
3386     {
3387         al_free(device);
3388         alcSetError(NULL, ALC_OUT_OF_MEMORY);
3389         return NULL;
3390     }
3391
3392
3393     if(ConfigValueStr(deviceName, NULL, "channels", &fmt))
3394     {
3395         static const struct {
3396             const char name[16];
3397             enum DevFmtChannels chans;
3398         } chanlist[] = {
3399             { "mono",       DevFmtMono   },
3400             { "stereo",     DevFmtStereo },
3401             { "quad",       DevFmtQuad   },
3402             { "surround51", DevFmtX51    },
3403             { "surround61", DevFmtX61    },
3404             { "surround71", DevFmtX71    },
3405             { "surround51rear", DevFmtX51Rear },
3406         };
3407         size_t i;
3408
3409         for(i = 0;i < COUNTOF(chanlist);i++)
3410         {
3411             if(strcasecmp(chanlist[i].name, fmt) == 0)
3412             {
3413                 device->FmtChans = chanlist[i].chans;
3414                 device->Flags |= DEVICE_CHANNELS_REQUEST;
3415                 break;
3416             }
3417         }
3418         if(i == COUNTOF(chanlist))
3419             ERR("Unsupported channels: %s\n", fmt);
3420     }
3421     if(ConfigValueStr(deviceName, NULL, "sample-type", &fmt))
3422     {
3423         static const struct {
3424             const char name[16];
3425             enum DevFmtType type;
3426         } typelist[] = {
3427             { "int8",    DevFmtByte   },
3428             { "uint8",   DevFmtUByte  },
3429             { "int16",   DevFmtShort  },
3430             { "uint16",  DevFmtUShort },
3431             { "int32",   DevFmtInt    },
3432             { "uint32",  DevFmtUInt   },
3433             { "float32", DevFmtFloat  },
3434         };
3435         size_t i;
3436
3437         for(i = 0;i < COUNTOF(typelist);i++)
3438         {
3439             if(strcasecmp(typelist[i].name, fmt) == 0)
3440             {
3441                 device->FmtType = typelist[i].type;
3442                 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3443                 break;
3444             }
3445         }
3446         if(i == COUNTOF(typelist))
3447             ERR("Unsupported sample-type: %s\n", fmt);
3448     }
3449
3450     if(ConfigValueUInt(deviceName, NULL, "frequency", &device->Frequency))
3451     {
3452         device->Flags |= DEVICE_FREQUENCY_REQUEST;
3453         if(device->Frequency < MIN_OUTPUT_RATE)
3454             ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3455         device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3456     }
3457
3458     ConfigValueUInt(deviceName, NULL, "periods", &device->NumUpdates);
3459     device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3460
3461     ConfigValueUInt(deviceName, NULL, "period_size", &device->UpdateSize);
3462     device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3463     if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
3464         device->UpdateSize = (device->UpdateSize+3)&~3;
3465
3466     ConfigValueUInt(deviceName, NULL, "sources", &device->MaxNoOfSources);
3467     if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3468
3469     ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3470     if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3471
3472     ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends);
3473     if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3474
3475     device->NumStereoSources = 1;
3476     device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3477
3478     // Find a playback device to open
3479     if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3480     {
3481         DELETE_OBJ(device->Backend);
3482         al_free(device);
3483         alcSetError(NULL, err);
3484         return NULL;
3485     }
3486
3487     if(DefaultEffect.type != AL_EFFECT_NULL)
3488     {
3489         device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3490         if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3491         {
3492             device->DefaultSlot = NULL;
3493             ERR("Failed to initialize the default effect slot\n");
3494         }
3495         else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3496         {
3497             ALeffectState *state = device->DefaultSlot->EffectState;
3498             device->DefaultSlot = NULL;
3499             DELETE_OBJ(state);
3500             ERR("Failed to initialize the default effect\n");
3501         }
3502     }
3503
3504     {
3505         ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3506         do {
3507             device->next = head;
3508         } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3509     }
3510
3511     TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3512     return device;
3513 }
3514
3515 /* alcCloseDevice
3516  *
3517  * Closes the given device.
3518  */
3519 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3520 {
3521     ALCdevice *list, *origdev, *nextdev;
3522     ALCcontext *ctx;
3523
3524     LockLists();
3525     list = ATOMIC_LOAD(&DeviceList);
3526     do {
3527         if(list == device)
3528             break;
3529     } while((list=list->next) != NULL);
3530     if(!list || list->Type == Capture)
3531     {
3532         alcSetError(list, ALC_INVALID_DEVICE);
3533         UnlockLists();
3534         return ALC_FALSE;
3535     }
3536
3537     origdev = device;
3538     nextdev = device->next;
3539     if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, nextdev))
3540     {
3541         do {
3542             list = origdev;
3543             origdev = device;
3544         } while(!COMPARE_EXCHANGE(&list->next, &origdev, nextdev));
3545     }
3546     UnlockLists();
3547
3548     ctx = ATOMIC_LOAD(&device->ContextList);
3549     while(ctx != NULL)
3550     {
3551         ALCcontext *next = ctx->next;
3552         WARN("Releasing context %p\n", ctx);
3553         ReleaseContext(ctx, device);
3554         ctx = next;
3555     }
3556     if((device->Flags&DEVICE_RUNNING))
3557         V0(device->Backend,stop)();
3558     device->Flags &= ~DEVICE_RUNNING;
3559
3560     ALCdevice_DecRef(device);
3561
3562     return ALC_TRUE;
3563 }
3564
3565
3566 /************************************************
3567  * ALC capture functions
3568  ************************************************/
3569 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3570 {
3571     ALCdevice *device = NULL;
3572     ALCenum err;
3573
3574     DO_INITCONFIG();
3575
3576     if(!CaptureBackend.name)
3577     {
3578         alcSetError(NULL, ALC_INVALID_VALUE);
3579         return NULL;
3580     }
3581
3582     if(samples <= 0)
3583     {
3584         alcSetError(NULL, ALC_INVALID_VALUE);
3585         return NULL;
3586     }
3587
3588     if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3589         deviceName = NULL;
3590
3591     device = al_calloc(16, sizeof(ALCdevice));
3592     if(!device)
3593     {
3594         alcSetError(NULL, ALC_OUT_OF_MEMORY);
3595         return NULL;
3596     }
3597
3598     //Validate device
3599     InitRef(&device->ref, 1);
3600     device->Connected = ALC_TRUE;
3601     device->Type = Capture;
3602
3603     VECTOR_INIT(device->Hrtf_List);
3604     AL_STRING_INIT(device->Hrtf_Name);
3605
3606     AL_STRING_INIT(device->DeviceName);
3607     device->DryBuffer = NULL;
3608
3609     InitUIntMap(&device->BufferMap, ~0);
3610     InitUIntMap(&device->EffectMap, ~0);
3611     InitUIntMap(&device->FilterMap, ~0);
3612
3613     if(!CaptureBackend.getFactory)
3614         device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3615                                                  ALCbackend_Capture);
3616     else
3617     {
3618         ALCbackendFactory *factory = CaptureBackend.getFactory();
3619         device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3620     }
3621     if(!device->Backend)
3622     {
3623         al_free(device);
3624         alcSetError(NULL, ALC_OUT_OF_MEMORY);
3625         return NULL;
3626     }
3627
3628     device->Flags |= DEVICE_FREQUENCY_REQUEST;
3629     device->Frequency = frequency;
3630
3631     device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3632     if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3633     {
3634         al_free(device);
3635         alcSetError(NULL, ALC_INVALID_ENUM);
3636         return NULL;
3637     }
3638     device->IsHeadphones = AL_FALSE;
3639
3640     device->UpdateSize = samples;
3641     device->NumUpdates = 1;
3642
3643     if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3644     {
3645         al_free(device);
3646         alcSetError(NULL, err);
3647         return NULL;
3648     }
3649
3650     {
3651         ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3652         do {
3653             device->next = head;
3654         } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3655     }
3656
3657     TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3658     return device;
3659 }
3660
3661 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3662 {
3663     ALCdevice *list, *next, *nextdev;
3664
3665     LockLists();
3666     list = ATOMIC_LOAD(&DeviceList);
3667     do {
3668         if(list == device)
3669             break;
3670     } while((list=list->next) != NULL);
3671     if(!list || list->Type != Capture)
3672     {
3673         alcSetError(list, ALC_INVALID_DEVICE);
3674         UnlockLists();
3675         return ALC_FALSE;
3676     }
3677
3678     next = device;
3679     nextdev = device->next;
3680     if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &next, nextdev))
3681     {
3682         do {
3683             list = next;
3684             next = device;
3685         } while(!COMPARE_EXCHANGE(&list->next, &next, nextdev));
3686     }
3687     UnlockLists();
3688
3689     ALCdevice_DecRef(device);
3690
3691     return ALC_TRUE;
3692 }
3693
3694 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3695 {
3696     if(!VerifyDevice(&device) || device->Type != Capture)
3697         alcSetError(device, ALC_INVALID_DEVICE);
3698     else
3699     {
3700         V0(device->Backend,lock)();
3701         if(!device->Connected)
3702             alcSetError(device, ALC_INVALID_DEVICE);
3703         else if(!(device->Flags&DEVICE_RUNNING))
3704         {
3705             if(V0(device->Backend,start)())
3706                 device->Flags |= DEVICE_RUNNING;
3707             else
3708             {
3709                 aluHandleDisconnect(device);
3710                 alcSetError(device, ALC_INVALID_DEVICE);
3711             }
3712         }
3713         V0(device->Backend,unlock)();
3714     }
3715
3716     if(device) ALCdevice_DecRef(device);
3717 }
3718
3719 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3720 {
3721     if(!VerifyDevice(&device) || device->Type != Capture)
3722         alcSetError(device, ALC_INVALID_DEVICE);
3723     else
3724     {
3725         V0(device->Backend,lock)();
3726         if((device->Flags&DEVICE_RUNNING))
3727             V0(device->Backend,stop)();
3728         device->Flags &= ~DEVICE_RUNNING;
3729         V0(device->Backend,unlock)();
3730     }
3731
3732     if(device) ALCdevice_DecRef(device);
3733 }
3734
3735 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3736 {
3737     if(!VerifyDevice(&device) || device->Type != Capture)
3738         alcSetError(device, ALC_INVALID_DEVICE);
3739     else
3740     {
3741         ALCenum err = ALC_INVALID_VALUE;
3742
3743         V0(device->Backend,lock)();
3744         if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3745             err = V(device->Backend,captureSamples)(buffer, samples);
3746         V0(device->Backend,unlock)();
3747
3748         if(err != ALC_NO_ERROR)
3749             alcSetError(device, err);
3750     }
3751     if(device) ALCdevice_DecRef(device);
3752 }
3753
3754
3755 /************************************************
3756  * ALC loopback functions
3757  ************************************************/
3758
3759 /* alcLoopbackOpenDeviceSOFT
3760  *
3761  * Open a loopback device, for manual rendering.
3762  */
3763 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3764 {
3765     ALCbackendFactory *factory;
3766     ALCdevice *device;
3767
3768     DO_INITCONFIG();
3769
3770     /* Make sure the device name, if specified, is us. */
3771     if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3772     {
3773         alcSetError(NULL, ALC_INVALID_VALUE);
3774         return NULL;
3775     }
3776
3777     device = al_calloc(16, sizeof(ALCdevice));
3778     if(!device)
3779     {
3780         alcSetError(NULL, ALC_OUT_OF_MEMORY);
3781         return NULL;
3782     }
3783
3784     //Validate device
3785     InitRef(&device->ref, 1);
3786     device->Connected = ALC_TRUE;
3787     device->Type = Loopback;
3788     ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
3789
3790     device->Flags = 0;
3791     VECTOR_INIT(device->Hrtf_List);
3792     AL_STRING_INIT(device->Hrtf_Name);
3793     device->Bs2b = NULL;
3794     device->Hrtf_Mode = DisabledHrtf;
3795     AL_STRING_INIT(device->DeviceName);
3796     device->DryBuffer = NULL;
3797
3798     ATOMIC_INIT(&device->ContextList, NULL);
3799
3800     device->ClockBase = 0;
3801     device->SamplesDone = 0;
3802
3803     device->MaxNoOfSources = 256;
3804     device->AuxiliaryEffectSlotMax = 4;
3805     device->NumAuxSends = MAX_SENDS;
3806
3807     InitUIntMap(&device->BufferMap, ~0);
3808     InitUIntMap(&device->EffectMap, ~0);
3809     InitUIntMap(&device->FilterMap, ~0);
3810
3811     factory = ALCloopbackFactory_getFactory();
3812     device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3813     if(!device->Backend)
3814     {
3815         al_free(device);
3816         alcSetError(NULL, ALC_OUT_OF_MEMORY);
3817         return NULL;
3818     }
3819
3820     //Set output format
3821     device->NumUpdates = 0;
3822     device->UpdateSize = 0;
3823
3824     device->Frequency = DEFAULT_OUTPUT_RATE;
3825     device->FmtChans = DevFmtChannelsDefault;
3826     device->FmtType = DevFmtTypeDefault;
3827     device->IsHeadphones = AL_FALSE;
3828
3829     ConfigValueUInt(NULL, NULL, "sources", &device->MaxNoOfSources);
3830     if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3831
3832     ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax);
3833     if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3834
3835     ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends);
3836     if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3837
3838     device->NumStereoSources = 1;
3839     device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3840
3841     // Open the "backend"
3842     V(device->Backend,open)("Loopback");
3843
3844     {
3845         ALCdevice *head = ATOMIC_LOAD(&DeviceList);
3846         do {
3847             device->next = head;
3848         } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device));
3849     }
3850
3851     TRACE("Created device %p\n", device);
3852     return device;
3853 }
3854
3855 /* alcIsRenderFormatSupportedSOFT
3856  *
3857  * Determines if the loopback device supports the given format for rendering.
3858  */
3859 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3860 {
3861     ALCboolean ret = ALC_FALSE;
3862
3863     if(!VerifyDevice(&device) || device->Type != Loopback)
3864         alcSetError(device, ALC_INVALID_DEVICE);
3865     else if(freq <= 0)
3866         alcSetError(device, ALC_INVALID_VALUE);
3867     else
3868     {
3869         if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3870            IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3871            freq >= MIN_OUTPUT_RATE)
3872             ret = ALC_TRUE;
3873     }
3874     if(device) ALCdevice_DecRef(device);
3875
3876     return ret;
3877 }
3878
3879 /* alcRenderSamplesSOFT
3880  *
3881  * Renders some samples into a buffer, using the format last set by the
3882  * attributes given to alcCreateContext.
3883  */
3884 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3885 {
3886     if(!VerifyDevice(&device) || device->Type != Loopback)
3887         alcSetError(device, ALC_INVALID_DEVICE);
3888     else if(samples < 0 || (samples > 0 && buffer == NULL))
3889         alcSetError(device, ALC_INVALID_VALUE);
3890     else
3891         aluMixData(device, buffer, samples);
3892     if(device) ALCdevice_DecRef(device);
3893 }
3894
3895
3896 /************************************************
3897  * ALC DSP pause/resume functions
3898  ************************************************/
3899
3900 /* alcDevicePauseSOFT
3901  *
3902  * Pause the DSP to stop audio processing.
3903  */
3904 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3905 {
3906     if(!VerifyDevice(&device) || device->Type != Playback)
3907         alcSetError(device, ALC_INVALID_DEVICE);
3908     else
3909     {
3910         LockLists();
3911         if((device->Flags&DEVICE_RUNNING))
3912             V0(device->Backend,stop)();
3913         device->Flags &= ~DEVICE_RUNNING;
3914         device->Flags |= DEVICE_PAUSED;
3915         UnlockLists();
3916     }
3917     if(device) ALCdevice_DecRef(device);
3918 }
3919
3920 /* alcDeviceResumeSOFT
3921  *
3922  * Resume the DSP to restart audio processing.
3923  */
3924 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3925 {
3926     if(!VerifyDevice(&device) || device->Type != Playback)
3927         alcSetError(device, ALC_INVALID_DEVICE);
3928     else
3929     {
3930         LockLists();
3931         if((device->Flags&DEVICE_PAUSED))
3932         {
3933             device->Flags &= ~DEVICE_PAUSED;
3934             if(ATOMIC_LOAD(&device->ContextList) != NULL)
3935             {
3936                 if(V0(device->Backend,start)() != ALC_FALSE)
3937                     device->Flags |= DEVICE_RUNNING;
3938                 else
3939                 {
3940                     alcSetError(device, ALC_INVALID_DEVICE);
3941                     V0(device->Backend,lock)();
3942                     aluHandleDisconnect(device);
3943                     V0(device->Backend,unlock)();
3944                 }
3945             }
3946         }
3947         UnlockLists();
3948     }
3949     if(device) ALCdevice_DecRef(device);
3950 }
3951
3952
3953 /************************************************
3954  * ALC HRTF functions
3955  ************************************************/
3956
3957 /* alcGetStringiSOFT
3958  *
3959  * Gets a string parameter at the given index.
3960  */
3961 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3962 {
3963     const ALCchar *str = NULL;
3964
3965     if(!VerifyDevice(&device) || device->Type == Capture)
3966         alcSetError(device, ALC_INVALID_DEVICE);
3967     else switch(paramName)
3968     {
3969         case ALC_HRTF_SPECIFIER_SOFT:
3970             if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
3971                 str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
3972             else
3973                 alcSetError(device, ALC_INVALID_VALUE);
3974             break;
3975
3976         default:
3977             alcSetError(device, ALC_INVALID_ENUM);
3978             break;
3979     }
3980     if(device) ALCdevice_DecRef(device);
3981
3982     return str;
3983 }
3984
3985 /* alcResetDeviceSOFT
3986  *
3987  * Resets the given device output, using the specified attribute list.
3988  */
3989 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
3990 {
3991     ALCenum err;
3992
3993     LockLists();
3994     if(!VerifyDevice(&device) || device->Type == Capture || !device->Connected)
3995     {
3996         UnlockLists();
3997         alcSetError(device, ALC_INVALID_DEVICE);
3998         if(device) ALCdevice_DecRef(device);
3999         return ALC_FALSE;
4000     }
4001
4002     if((err=UpdateDeviceParams(device, attribs)) != ALC_NO_ERROR)
4003     {
4004         UnlockLists();
4005         alcSetError(device, err);
4006         if(err == ALC_INVALID_DEVICE)
4007         {
4008             V0(device->Backend,lock)();
4009             aluHandleDisconnect(device);
4010             V0(device->Backend,unlock)();
4011         }
4012         ALCdevice_DecRef(device);
4013         return ALC_FALSE;
4014     }
4015     UnlockLists();
4016     ALCdevice_DecRef(device);
4017
4018     return ALC_TRUE;
4019 }