]> git.tdb.fi Git - ext/openal.git/blob - alc/alc.cpp
Tweak some types to work around an MSVC compile error
[ext/openal.git] / alc / alc.cpp
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 "version.h"
24
25 #ifdef _WIN32
26 #define WIN32_LEAN_AND_MEAN
27 #include <windows.h>
28 #endif
29
30 #include <algorithm>
31 #include <array>
32 #include <atomic>
33 #include <bitset>
34 #include <cassert>
35 #include <cctype>
36 #include <chrono>
37 #include <cinttypes>
38 #include <climits>
39 #include <cmath>
40 #include <csignal>
41 #include <cstdint>
42 #include <cstdio>
43 #include <cstdlib>
44 #include <cstring>
45 #include <functional>
46 #include <iterator>
47 #include <limits>
48 #include <memory>
49 #include <mutex>
50 #include <new>
51 #include <stddef.h>
52 #include <stdexcept>
53 #include <string>
54 #include <type_traits>
55 #include <utility>
56
57 #include "AL/al.h"
58 #include "AL/alc.h"
59 #include "AL/alext.h"
60 #include "AL/efx.h"
61
62 #include "al/auxeffectslot.h"
63 #include "al/buffer.h"
64 #include "al/effect.h"
65 #include "al/filter.h"
66 #include "al/listener.h"
67 #include "al/source.h"
68 #include "albit.h"
69 #include "albyte.h"
70 #include "alconfig.h"
71 #include "almalloc.h"
72 #include "alnumeric.h"
73 #include "aloptional.h"
74 #include "alspan.h"
75 #include "alstring.h"
76 #include "alu.h"
77 #include "atomic.h"
78 #include "context.h"
79 #include "core/ambidefs.h"
80 #include "core/bformatdec.h"
81 #include "core/bs2b.h"
82 #include "core/context.h"
83 #include "core/cpu_caps.h"
84 #include "core/devformat.h"
85 #include "core/device.h"
86 #include "core/effectslot.h"
87 #include "core/except.h"
88 #include "core/helpers.h"
89 #include "core/mastering.h"
90 #include "core/mixer/hrtfdefs.h"
91 #include "core/fpu_ctrl.h"
92 #include "core/front_stablizer.h"
93 #include "core/logging.h"
94 #include "core/uhjfilter.h"
95 #include "core/voice.h"
96 #include "core/voice_change.h"
97 #include "device.h"
98 #include "effects/base.h"
99 #include "inprogext.h"
100 #include "intrusive_ptr.h"
101 #include "opthelpers.h"
102 #include "strutils.h"
103 #include "threads.h"
104 #include "vector.h"
105
106 #include "backends/base.h"
107 #include "backends/null.h"
108 #include "backends/loopback.h"
109 #ifdef HAVE_PIPEWIRE
110 #include "backends/pipewire.h"
111 #endif
112 #ifdef HAVE_JACK
113 #include "backends/jack.h"
114 #endif
115 #ifdef HAVE_PULSEAUDIO
116 #include "backends/pulseaudio.h"
117 #endif
118 #ifdef HAVE_ALSA
119 #include "backends/alsa.h"
120 #endif
121 #ifdef HAVE_WASAPI
122 #include "backends/wasapi.h"
123 #endif
124 #ifdef HAVE_COREAUDIO
125 #include "backends/coreaudio.h"
126 #endif
127 #ifdef HAVE_OPENSL
128 #include "backends/opensl.h"
129 #endif
130 #ifdef HAVE_OBOE
131 #include "backends/oboe.h"
132 #endif
133 #ifdef HAVE_SOLARIS
134 #include "backends/solaris.h"
135 #endif
136 #ifdef HAVE_SNDIO
137 #include "backends/sndio.h"
138 #endif
139 #ifdef HAVE_OSS
140 #include "backends/oss.h"
141 #endif
142 #ifdef HAVE_DSOUND
143 #include "backends/dsound.h"
144 #endif
145 #ifdef HAVE_WINMM
146 #include "backends/winmm.h"
147 #endif
148 #ifdef HAVE_PORTAUDIO
149 #include "backends/portaudio.h"
150 #endif
151 #ifdef HAVE_SDL2
152 #include "backends/sdl2.h"
153 #endif
154 #ifdef HAVE_WAVE
155 #include "backends/wave.h"
156 #endif
157
158 #ifdef ALSOFT_EAX
159 #include "al/eax/globals.h"
160 #include "al/eax/x_ram.h"
161 #endif // ALSOFT_EAX
162
163
164 FILE *gLogFile{stderr};
165 #ifdef _DEBUG
166 LogLevel gLogLevel{LogLevel::Warning};
167 #else
168 LogLevel gLogLevel{LogLevel::Error};
169 #endif
170
171 /************************************************
172  * Library initialization
173  ************************************************/
174 #if defined(_WIN32) && !defined(AL_LIBTYPE_STATIC)
175 BOOL APIENTRY DllMain(HINSTANCE module, DWORD reason, LPVOID /*reserved*/)
176 {
177     switch(reason)
178     {
179     case DLL_PROCESS_ATTACH:
180         /* Pin the DLL so we won't get unloaded until the process terminates */
181         GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
182             reinterpret_cast<WCHAR*>(module), &module);
183         break;
184     }
185     return TRUE;
186 }
187 #endif
188
189 namespace {
190
191 using namespace std::placeholders;
192 using std::chrono::seconds;
193 using std::chrono::nanoseconds;
194
195 using voidp = void*;
196 using float2 = std::array<float,2>;
197
198
199 /************************************************
200  * Backends
201  ************************************************/
202 struct BackendInfo {
203     const char *name;
204     BackendFactory& (*getFactory)(void);
205 };
206
207 BackendInfo BackendList[] = {
208 #ifdef HAVE_PIPEWIRE
209     { "pipewire", PipeWireBackendFactory::getFactory },
210 #endif
211 #ifdef HAVE_PULSEAUDIO
212     { "pulse", PulseBackendFactory::getFactory },
213 #endif
214 #ifdef HAVE_WASAPI
215     { "wasapi", WasapiBackendFactory::getFactory },
216 #endif
217 #ifdef HAVE_COREAUDIO
218     { "core", CoreAudioBackendFactory::getFactory },
219 #endif
220 #ifdef HAVE_OBOE
221     { "oboe", OboeBackendFactory::getFactory },
222 #endif
223 #ifdef HAVE_OPENSL
224     { "opensl", OSLBackendFactory::getFactory },
225 #endif
226 #ifdef HAVE_ALSA
227     { "alsa", AlsaBackendFactory::getFactory },
228 #endif
229 #ifdef HAVE_SOLARIS
230     { "solaris", SolarisBackendFactory::getFactory },
231 #endif
232 #ifdef HAVE_SNDIO
233     { "sndio", SndIOBackendFactory::getFactory },
234 #endif
235 #ifdef HAVE_OSS
236     { "oss", OSSBackendFactory::getFactory },
237 #endif
238 #ifdef HAVE_JACK
239     { "jack", JackBackendFactory::getFactory },
240 #endif
241 #ifdef HAVE_DSOUND
242     { "dsound", DSoundBackendFactory::getFactory },
243 #endif
244 #ifdef HAVE_WINMM
245     { "winmm", WinMMBackendFactory::getFactory },
246 #endif
247 #ifdef HAVE_PORTAUDIO
248     { "port", PortBackendFactory::getFactory },
249 #endif
250 #ifdef HAVE_SDL2
251     { "sdl2", SDL2BackendFactory::getFactory },
252 #endif
253
254     { "null", NullBackendFactory::getFactory },
255 #ifdef HAVE_WAVE
256     { "wave", WaveBackendFactory::getFactory },
257 #endif
258 };
259
260 BackendFactory *PlaybackFactory{};
261 BackendFactory *CaptureFactory{};
262
263
264 /************************************************
265  * Functions, enums, and errors
266  ************************************************/
267 #define DECL(x) { #x, reinterpret_cast<void*>(x) }
268 const struct {
269     const char *funcName;
270     void *address;
271 } alcFunctions[] = {
272     DECL(alcCreateContext),
273     DECL(alcMakeContextCurrent),
274     DECL(alcProcessContext),
275     DECL(alcSuspendContext),
276     DECL(alcDestroyContext),
277     DECL(alcGetCurrentContext),
278     DECL(alcGetContextsDevice),
279     DECL(alcOpenDevice),
280     DECL(alcCloseDevice),
281     DECL(alcGetError),
282     DECL(alcIsExtensionPresent),
283     DECL(alcGetProcAddress),
284     DECL(alcGetEnumValue),
285     DECL(alcGetString),
286     DECL(alcGetIntegerv),
287     DECL(alcCaptureOpenDevice),
288     DECL(alcCaptureCloseDevice),
289     DECL(alcCaptureStart),
290     DECL(alcCaptureStop),
291     DECL(alcCaptureSamples),
292
293     DECL(alcSetThreadContext),
294     DECL(alcGetThreadContext),
295
296     DECL(alcLoopbackOpenDeviceSOFT),
297     DECL(alcIsRenderFormatSupportedSOFT),
298     DECL(alcRenderSamplesSOFT),
299
300     DECL(alcDevicePauseSOFT),
301     DECL(alcDeviceResumeSOFT),
302
303     DECL(alcGetStringiSOFT),
304     DECL(alcResetDeviceSOFT),
305
306     DECL(alcGetInteger64vSOFT),
307
308     DECL(alcReopenDeviceSOFT),
309
310     DECL(alEnable),
311     DECL(alDisable),
312     DECL(alIsEnabled),
313     DECL(alGetString),
314     DECL(alGetBooleanv),
315     DECL(alGetIntegerv),
316     DECL(alGetFloatv),
317     DECL(alGetDoublev),
318     DECL(alGetBoolean),
319     DECL(alGetInteger),
320     DECL(alGetFloat),
321     DECL(alGetDouble),
322     DECL(alGetError),
323     DECL(alIsExtensionPresent),
324     DECL(alGetProcAddress),
325     DECL(alGetEnumValue),
326     DECL(alListenerf),
327     DECL(alListener3f),
328     DECL(alListenerfv),
329     DECL(alListeneri),
330     DECL(alListener3i),
331     DECL(alListeneriv),
332     DECL(alGetListenerf),
333     DECL(alGetListener3f),
334     DECL(alGetListenerfv),
335     DECL(alGetListeneri),
336     DECL(alGetListener3i),
337     DECL(alGetListeneriv),
338     DECL(alGenSources),
339     DECL(alDeleteSources),
340     DECL(alIsSource),
341     DECL(alSourcef),
342     DECL(alSource3f),
343     DECL(alSourcefv),
344     DECL(alSourcei),
345     DECL(alSource3i),
346     DECL(alSourceiv),
347     DECL(alGetSourcef),
348     DECL(alGetSource3f),
349     DECL(alGetSourcefv),
350     DECL(alGetSourcei),
351     DECL(alGetSource3i),
352     DECL(alGetSourceiv),
353     DECL(alSourcePlayv),
354     DECL(alSourceStopv),
355     DECL(alSourceRewindv),
356     DECL(alSourcePausev),
357     DECL(alSourcePlay),
358     DECL(alSourceStop),
359     DECL(alSourceRewind),
360     DECL(alSourcePause),
361     DECL(alSourceQueueBuffers),
362     DECL(alSourceUnqueueBuffers),
363     DECL(alGenBuffers),
364     DECL(alDeleteBuffers),
365     DECL(alIsBuffer),
366     DECL(alBufferData),
367     DECL(alBufferf),
368     DECL(alBuffer3f),
369     DECL(alBufferfv),
370     DECL(alBufferi),
371     DECL(alBuffer3i),
372     DECL(alBufferiv),
373     DECL(alGetBufferf),
374     DECL(alGetBuffer3f),
375     DECL(alGetBufferfv),
376     DECL(alGetBufferi),
377     DECL(alGetBuffer3i),
378     DECL(alGetBufferiv),
379     DECL(alDopplerFactor),
380     DECL(alDopplerVelocity),
381     DECL(alSpeedOfSound),
382     DECL(alDistanceModel),
383
384     DECL(alGenFilters),
385     DECL(alDeleteFilters),
386     DECL(alIsFilter),
387     DECL(alFilteri),
388     DECL(alFilteriv),
389     DECL(alFilterf),
390     DECL(alFilterfv),
391     DECL(alGetFilteri),
392     DECL(alGetFilteriv),
393     DECL(alGetFilterf),
394     DECL(alGetFilterfv),
395     DECL(alGenEffects),
396     DECL(alDeleteEffects),
397     DECL(alIsEffect),
398     DECL(alEffecti),
399     DECL(alEffectiv),
400     DECL(alEffectf),
401     DECL(alEffectfv),
402     DECL(alGetEffecti),
403     DECL(alGetEffectiv),
404     DECL(alGetEffectf),
405     DECL(alGetEffectfv),
406     DECL(alGenAuxiliaryEffectSlots),
407     DECL(alDeleteAuxiliaryEffectSlots),
408     DECL(alIsAuxiliaryEffectSlot),
409     DECL(alAuxiliaryEffectSloti),
410     DECL(alAuxiliaryEffectSlotiv),
411     DECL(alAuxiliaryEffectSlotf),
412     DECL(alAuxiliaryEffectSlotfv),
413     DECL(alGetAuxiliaryEffectSloti),
414     DECL(alGetAuxiliaryEffectSlotiv),
415     DECL(alGetAuxiliaryEffectSlotf),
416     DECL(alGetAuxiliaryEffectSlotfv),
417
418     DECL(alDeferUpdatesSOFT),
419     DECL(alProcessUpdatesSOFT),
420
421     DECL(alSourcedSOFT),
422     DECL(alSource3dSOFT),
423     DECL(alSourcedvSOFT),
424     DECL(alGetSourcedSOFT),
425     DECL(alGetSource3dSOFT),
426     DECL(alGetSourcedvSOFT),
427     DECL(alSourcei64SOFT),
428     DECL(alSource3i64SOFT),
429     DECL(alSourcei64vSOFT),
430     DECL(alGetSourcei64SOFT),
431     DECL(alGetSource3i64SOFT),
432     DECL(alGetSourcei64vSOFT),
433
434     DECL(alGetStringiSOFT),
435
436     DECL(alBufferStorageSOFT),
437     DECL(alMapBufferSOFT),
438     DECL(alUnmapBufferSOFT),
439     DECL(alFlushMappedBufferSOFT),
440
441     DECL(alEventControlSOFT),
442     DECL(alEventCallbackSOFT),
443     DECL(alGetPointerSOFT),
444     DECL(alGetPointervSOFT),
445
446     DECL(alBufferCallbackSOFT),
447     DECL(alGetBufferPtrSOFT),
448     DECL(alGetBuffer3PtrSOFT),
449     DECL(alGetBufferPtrvSOFT),
450
451     DECL(alAuxiliaryEffectSlotPlaySOFT),
452     DECL(alAuxiliaryEffectSlotPlayvSOFT),
453     DECL(alAuxiliaryEffectSlotStopSOFT),
454     DECL(alAuxiliaryEffectSlotStopvSOFT),
455
456     DECL(alSourcePlayAtTimeSOFT),
457     DECL(alSourcePlayAtTimevSOFT),
458
459     DECL(alBufferSubDataSOFT),
460
461     DECL(alBufferDataStatic),
462 #ifdef ALSOFT_EAX
463 }, eaxFunctions[] = {
464     DECL(EAXGet),
465     DECL(EAXSet),
466     DECL(EAXGetBufferMode),
467     DECL(EAXSetBufferMode),
468 #endif
469 };
470 #undef DECL
471
472 #define DECL(x) { #x, (x) }
473 constexpr struct {
474     const ALCchar *enumName;
475     ALCenum value;
476 } alcEnumerations[] = {
477     DECL(ALC_INVALID),
478     DECL(ALC_FALSE),
479     DECL(ALC_TRUE),
480
481     DECL(ALC_MAJOR_VERSION),
482     DECL(ALC_MINOR_VERSION),
483     DECL(ALC_ATTRIBUTES_SIZE),
484     DECL(ALC_ALL_ATTRIBUTES),
485     DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
486     DECL(ALC_DEVICE_SPECIFIER),
487     DECL(ALC_ALL_DEVICES_SPECIFIER),
488     DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
489     DECL(ALC_EXTENSIONS),
490     DECL(ALC_FREQUENCY),
491     DECL(ALC_REFRESH),
492     DECL(ALC_SYNC),
493     DECL(ALC_MONO_SOURCES),
494     DECL(ALC_STEREO_SOURCES),
495     DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
496     DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
497     DECL(ALC_CAPTURE_SAMPLES),
498     DECL(ALC_CONNECTED),
499
500     DECL(ALC_EFX_MAJOR_VERSION),
501     DECL(ALC_EFX_MINOR_VERSION),
502     DECL(ALC_MAX_AUXILIARY_SENDS),
503
504     DECL(ALC_FORMAT_CHANNELS_SOFT),
505     DECL(ALC_FORMAT_TYPE_SOFT),
506
507     DECL(ALC_MONO_SOFT),
508     DECL(ALC_STEREO_SOFT),
509     DECL(ALC_QUAD_SOFT),
510     DECL(ALC_5POINT1_SOFT),
511     DECL(ALC_6POINT1_SOFT),
512     DECL(ALC_7POINT1_SOFT),
513     DECL(ALC_BFORMAT3D_SOFT),
514
515     DECL(ALC_BYTE_SOFT),
516     DECL(ALC_UNSIGNED_BYTE_SOFT),
517     DECL(ALC_SHORT_SOFT),
518     DECL(ALC_UNSIGNED_SHORT_SOFT),
519     DECL(ALC_INT_SOFT),
520     DECL(ALC_UNSIGNED_INT_SOFT),
521     DECL(ALC_FLOAT_SOFT),
522
523     DECL(ALC_HRTF_SOFT),
524     DECL(ALC_DONT_CARE_SOFT),
525     DECL(ALC_HRTF_STATUS_SOFT),
526     DECL(ALC_HRTF_DISABLED_SOFT),
527     DECL(ALC_HRTF_ENABLED_SOFT),
528     DECL(ALC_HRTF_DENIED_SOFT),
529     DECL(ALC_HRTF_REQUIRED_SOFT),
530     DECL(ALC_HRTF_HEADPHONES_DETECTED_SOFT),
531     DECL(ALC_HRTF_UNSUPPORTED_FORMAT_SOFT),
532     DECL(ALC_NUM_HRTF_SPECIFIERS_SOFT),
533     DECL(ALC_HRTF_SPECIFIER_SOFT),
534     DECL(ALC_HRTF_ID_SOFT),
535
536     DECL(ALC_AMBISONIC_LAYOUT_SOFT),
537     DECL(ALC_AMBISONIC_SCALING_SOFT),
538     DECL(ALC_AMBISONIC_ORDER_SOFT),
539     DECL(ALC_ACN_SOFT),
540     DECL(ALC_FUMA_SOFT),
541     DECL(ALC_N3D_SOFT),
542     DECL(ALC_SN3D_SOFT),
543
544     DECL(ALC_OUTPUT_LIMITER_SOFT),
545
546     DECL(ALC_DEVICE_CLOCK_SOFT),
547     DECL(ALC_DEVICE_LATENCY_SOFT),
548     DECL(ALC_DEVICE_CLOCK_LATENCY_SOFT),
549     DECL(AL_SAMPLE_OFFSET_CLOCK_SOFT),
550     DECL(AL_SEC_OFFSET_CLOCK_SOFT),
551
552     DECL(ALC_OUTPUT_MODE_SOFT),
553     DECL(ALC_ANY_SOFT),
554     DECL(ALC_STEREO_BASIC_SOFT),
555     DECL(ALC_STEREO_UHJ_SOFT),
556     DECL(ALC_STEREO_HRTF_SOFT),
557     DECL(ALC_SURROUND_5_1_SOFT),
558     DECL(ALC_SURROUND_6_1_SOFT),
559     DECL(ALC_SURROUND_7_1_SOFT),
560
561     DECL(ALC_NO_ERROR),
562     DECL(ALC_INVALID_DEVICE),
563     DECL(ALC_INVALID_CONTEXT),
564     DECL(ALC_INVALID_ENUM),
565     DECL(ALC_INVALID_VALUE),
566     DECL(ALC_OUT_OF_MEMORY),
567
568
569     DECL(AL_INVALID),
570     DECL(AL_NONE),
571     DECL(AL_FALSE),
572     DECL(AL_TRUE),
573
574     DECL(AL_SOURCE_RELATIVE),
575     DECL(AL_CONE_INNER_ANGLE),
576     DECL(AL_CONE_OUTER_ANGLE),
577     DECL(AL_PITCH),
578     DECL(AL_POSITION),
579     DECL(AL_DIRECTION),
580     DECL(AL_VELOCITY),
581     DECL(AL_LOOPING),
582     DECL(AL_BUFFER),
583     DECL(AL_GAIN),
584     DECL(AL_MIN_GAIN),
585     DECL(AL_MAX_GAIN),
586     DECL(AL_ORIENTATION),
587     DECL(AL_REFERENCE_DISTANCE),
588     DECL(AL_ROLLOFF_FACTOR),
589     DECL(AL_CONE_OUTER_GAIN),
590     DECL(AL_MAX_DISTANCE),
591     DECL(AL_SEC_OFFSET),
592     DECL(AL_SAMPLE_OFFSET),
593     DECL(AL_BYTE_OFFSET),
594     DECL(AL_SOURCE_TYPE),
595     DECL(AL_STATIC),
596     DECL(AL_STREAMING),
597     DECL(AL_UNDETERMINED),
598     DECL(AL_METERS_PER_UNIT),
599     DECL(AL_LOOP_POINTS_SOFT),
600     DECL(AL_DIRECT_CHANNELS_SOFT),
601
602     DECL(AL_DIRECT_FILTER),
603     DECL(AL_AUXILIARY_SEND_FILTER),
604     DECL(AL_AIR_ABSORPTION_FACTOR),
605     DECL(AL_ROOM_ROLLOFF_FACTOR),
606     DECL(AL_CONE_OUTER_GAINHF),
607     DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
608     DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
609     DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
610
611     DECL(AL_SOURCE_STATE),
612     DECL(AL_INITIAL),
613     DECL(AL_PLAYING),
614     DECL(AL_PAUSED),
615     DECL(AL_STOPPED),
616
617     DECL(AL_BUFFERS_QUEUED),
618     DECL(AL_BUFFERS_PROCESSED),
619
620     DECL(AL_FORMAT_MONO8),
621     DECL(AL_FORMAT_MONO16),
622     DECL(AL_FORMAT_MONO_FLOAT32),
623     DECL(AL_FORMAT_MONO_DOUBLE_EXT),
624     DECL(AL_FORMAT_STEREO8),
625     DECL(AL_FORMAT_STEREO16),
626     DECL(AL_FORMAT_STEREO_FLOAT32),
627     DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
628     DECL(AL_FORMAT_MONO_IMA4),
629     DECL(AL_FORMAT_STEREO_IMA4),
630     DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
631     DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
632     DECL(AL_FORMAT_QUAD8_LOKI),
633     DECL(AL_FORMAT_QUAD16_LOKI),
634     DECL(AL_FORMAT_QUAD8),
635     DECL(AL_FORMAT_QUAD16),
636     DECL(AL_FORMAT_QUAD32),
637     DECL(AL_FORMAT_51CHN8),
638     DECL(AL_FORMAT_51CHN16),
639     DECL(AL_FORMAT_51CHN32),
640     DECL(AL_FORMAT_61CHN8),
641     DECL(AL_FORMAT_61CHN16),
642     DECL(AL_FORMAT_61CHN32),
643     DECL(AL_FORMAT_71CHN8),
644     DECL(AL_FORMAT_71CHN16),
645     DECL(AL_FORMAT_71CHN32),
646     DECL(AL_FORMAT_REAR8),
647     DECL(AL_FORMAT_REAR16),
648     DECL(AL_FORMAT_REAR32),
649     DECL(AL_FORMAT_MONO_MULAW),
650     DECL(AL_FORMAT_MONO_MULAW_EXT),
651     DECL(AL_FORMAT_STEREO_MULAW),
652     DECL(AL_FORMAT_STEREO_MULAW_EXT),
653     DECL(AL_FORMAT_QUAD_MULAW),
654     DECL(AL_FORMAT_51CHN_MULAW),
655     DECL(AL_FORMAT_61CHN_MULAW),
656     DECL(AL_FORMAT_71CHN_MULAW),
657     DECL(AL_FORMAT_REAR_MULAW),
658     DECL(AL_FORMAT_MONO_ALAW_EXT),
659     DECL(AL_FORMAT_STEREO_ALAW_EXT),
660
661     DECL(AL_FORMAT_BFORMAT2D_8),
662     DECL(AL_FORMAT_BFORMAT2D_16),
663     DECL(AL_FORMAT_BFORMAT2D_FLOAT32),
664     DECL(AL_FORMAT_BFORMAT2D_MULAW),
665     DECL(AL_FORMAT_BFORMAT3D_8),
666     DECL(AL_FORMAT_BFORMAT3D_16),
667     DECL(AL_FORMAT_BFORMAT3D_FLOAT32),
668     DECL(AL_FORMAT_BFORMAT3D_MULAW),
669
670     DECL(AL_FREQUENCY),
671     DECL(AL_BITS),
672     DECL(AL_CHANNELS),
673     DECL(AL_SIZE),
674     DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
675     DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
676
677     DECL(AL_SOURCE_RADIUS),
678
679     DECL(AL_SAMPLE_OFFSET_LATENCY_SOFT),
680     DECL(AL_SEC_OFFSET_LATENCY_SOFT),
681
682     DECL(AL_STEREO_ANGLES),
683
684     DECL(AL_UNUSED),
685     DECL(AL_PENDING),
686     DECL(AL_PROCESSED),
687
688     DECL(AL_NO_ERROR),
689     DECL(AL_INVALID_NAME),
690     DECL(AL_INVALID_ENUM),
691     DECL(AL_INVALID_VALUE),
692     DECL(AL_INVALID_OPERATION),
693     DECL(AL_OUT_OF_MEMORY),
694
695     DECL(AL_VENDOR),
696     DECL(AL_VERSION),
697     DECL(AL_RENDERER),
698     DECL(AL_EXTENSIONS),
699
700     DECL(AL_DOPPLER_FACTOR),
701     DECL(AL_DOPPLER_VELOCITY),
702     DECL(AL_DISTANCE_MODEL),
703     DECL(AL_SPEED_OF_SOUND),
704     DECL(AL_SOURCE_DISTANCE_MODEL),
705     DECL(AL_DEFERRED_UPDATES_SOFT),
706     DECL(AL_GAIN_LIMIT_SOFT),
707
708     DECL(AL_INVERSE_DISTANCE),
709     DECL(AL_INVERSE_DISTANCE_CLAMPED),
710     DECL(AL_LINEAR_DISTANCE),
711     DECL(AL_LINEAR_DISTANCE_CLAMPED),
712     DECL(AL_EXPONENT_DISTANCE),
713     DECL(AL_EXPONENT_DISTANCE_CLAMPED),
714
715     DECL(AL_FILTER_TYPE),
716     DECL(AL_FILTER_NULL),
717     DECL(AL_FILTER_LOWPASS),
718     DECL(AL_FILTER_HIGHPASS),
719     DECL(AL_FILTER_BANDPASS),
720
721     DECL(AL_LOWPASS_GAIN),
722     DECL(AL_LOWPASS_GAINHF),
723
724     DECL(AL_HIGHPASS_GAIN),
725     DECL(AL_HIGHPASS_GAINLF),
726
727     DECL(AL_BANDPASS_GAIN),
728     DECL(AL_BANDPASS_GAINHF),
729     DECL(AL_BANDPASS_GAINLF),
730
731     DECL(AL_EFFECT_TYPE),
732     DECL(AL_EFFECT_NULL),
733     DECL(AL_EFFECT_REVERB),
734     DECL(AL_EFFECT_EAXREVERB),
735     DECL(AL_EFFECT_CHORUS),
736     DECL(AL_EFFECT_DISTORTION),
737     DECL(AL_EFFECT_ECHO),
738     DECL(AL_EFFECT_FLANGER),
739     DECL(AL_EFFECT_PITCH_SHIFTER),
740     DECL(AL_EFFECT_FREQUENCY_SHIFTER),
741     DECL(AL_EFFECT_VOCAL_MORPHER),
742     DECL(AL_EFFECT_RING_MODULATOR),
743     DECL(AL_EFFECT_AUTOWAH),
744     DECL(AL_EFFECT_COMPRESSOR),
745     DECL(AL_EFFECT_EQUALIZER),
746     DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
747     DECL(AL_EFFECT_DEDICATED_DIALOGUE),
748
749     DECL(AL_EFFECTSLOT_EFFECT),
750     DECL(AL_EFFECTSLOT_GAIN),
751     DECL(AL_EFFECTSLOT_AUXILIARY_SEND_AUTO),
752     DECL(AL_EFFECTSLOT_NULL),
753
754     DECL(AL_EAXREVERB_DENSITY),
755     DECL(AL_EAXREVERB_DIFFUSION),
756     DECL(AL_EAXREVERB_GAIN),
757     DECL(AL_EAXREVERB_GAINHF),
758     DECL(AL_EAXREVERB_GAINLF),
759     DECL(AL_EAXREVERB_DECAY_TIME),
760     DECL(AL_EAXREVERB_DECAY_HFRATIO),
761     DECL(AL_EAXREVERB_DECAY_LFRATIO),
762     DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
763     DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
764     DECL(AL_EAXREVERB_REFLECTIONS_PAN),
765     DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
766     DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
767     DECL(AL_EAXREVERB_LATE_REVERB_PAN),
768     DECL(AL_EAXREVERB_ECHO_TIME),
769     DECL(AL_EAXREVERB_ECHO_DEPTH),
770     DECL(AL_EAXREVERB_MODULATION_TIME),
771     DECL(AL_EAXREVERB_MODULATION_DEPTH),
772     DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
773     DECL(AL_EAXREVERB_HFREFERENCE),
774     DECL(AL_EAXREVERB_LFREFERENCE),
775     DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
776     DECL(AL_EAXREVERB_DECAY_HFLIMIT),
777
778     DECL(AL_REVERB_DENSITY),
779     DECL(AL_REVERB_DIFFUSION),
780     DECL(AL_REVERB_GAIN),
781     DECL(AL_REVERB_GAINHF),
782     DECL(AL_REVERB_DECAY_TIME),
783     DECL(AL_REVERB_DECAY_HFRATIO),
784     DECL(AL_REVERB_REFLECTIONS_GAIN),
785     DECL(AL_REVERB_REFLECTIONS_DELAY),
786     DECL(AL_REVERB_LATE_REVERB_GAIN),
787     DECL(AL_REVERB_LATE_REVERB_DELAY),
788     DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
789     DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
790     DECL(AL_REVERB_DECAY_HFLIMIT),
791
792     DECL(AL_CHORUS_WAVEFORM),
793     DECL(AL_CHORUS_PHASE),
794     DECL(AL_CHORUS_RATE),
795     DECL(AL_CHORUS_DEPTH),
796     DECL(AL_CHORUS_FEEDBACK),
797     DECL(AL_CHORUS_DELAY),
798
799     DECL(AL_DISTORTION_EDGE),
800     DECL(AL_DISTORTION_GAIN),
801     DECL(AL_DISTORTION_LOWPASS_CUTOFF),
802     DECL(AL_DISTORTION_EQCENTER),
803     DECL(AL_DISTORTION_EQBANDWIDTH),
804
805     DECL(AL_ECHO_DELAY),
806     DECL(AL_ECHO_LRDELAY),
807     DECL(AL_ECHO_DAMPING),
808     DECL(AL_ECHO_FEEDBACK),
809     DECL(AL_ECHO_SPREAD),
810
811     DECL(AL_FLANGER_WAVEFORM),
812     DECL(AL_FLANGER_PHASE),
813     DECL(AL_FLANGER_RATE),
814     DECL(AL_FLANGER_DEPTH),
815     DECL(AL_FLANGER_FEEDBACK),
816     DECL(AL_FLANGER_DELAY),
817
818     DECL(AL_FREQUENCY_SHIFTER_FREQUENCY),
819     DECL(AL_FREQUENCY_SHIFTER_LEFT_DIRECTION),
820     DECL(AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION),
821
822     DECL(AL_RING_MODULATOR_FREQUENCY),
823     DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
824     DECL(AL_RING_MODULATOR_WAVEFORM),
825
826     DECL(AL_PITCH_SHIFTER_COARSE_TUNE),
827     DECL(AL_PITCH_SHIFTER_FINE_TUNE),
828
829     DECL(AL_COMPRESSOR_ONOFF),
830
831     DECL(AL_EQUALIZER_LOW_GAIN),
832     DECL(AL_EQUALIZER_LOW_CUTOFF),
833     DECL(AL_EQUALIZER_MID1_GAIN),
834     DECL(AL_EQUALIZER_MID1_CENTER),
835     DECL(AL_EQUALIZER_MID1_WIDTH),
836     DECL(AL_EQUALIZER_MID2_GAIN),
837     DECL(AL_EQUALIZER_MID2_CENTER),
838     DECL(AL_EQUALIZER_MID2_WIDTH),
839     DECL(AL_EQUALIZER_HIGH_GAIN),
840     DECL(AL_EQUALIZER_HIGH_CUTOFF),
841
842     DECL(AL_DEDICATED_GAIN),
843
844     DECL(AL_AUTOWAH_ATTACK_TIME),
845     DECL(AL_AUTOWAH_RELEASE_TIME),
846     DECL(AL_AUTOWAH_RESONANCE),
847     DECL(AL_AUTOWAH_PEAK_GAIN),
848
849     DECL(AL_VOCAL_MORPHER_PHONEMEA),
850     DECL(AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING),
851     DECL(AL_VOCAL_MORPHER_PHONEMEB),
852     DECL(AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING),
853     DECL(AL_VOCAL_MORPHER_WAVEFORM),
854     DECL(AL_VOCAL_MORPHER_RATE),
855
856     DECL(AL_EFFECTSLOT_TARGET_SOFT),
857
858     DECL(AL_NUM_RESAMPLERS_SOFT),
859     DECL(AL_DEFAULT_RESAMPLER_SOFT),
860     DECL(AL_SOURCE_RESAMPLER_SOFT),
861     DECL(AL_RESAMPLER_NAME_SOFT),
862
863     DECL(AL_SOURCE_SPATIALIZE_SOFT),
864     DECL(AL_AUTO_SOFT),
865
866     DECL(AL_MAP_READ_BIT_SOFT),
867     DECL(AL_MAP_WRITE_BIT_SOFT),
868     DECL(AL_MAP_PERSISTENT_BIT_SOFT),
869     DECL(AL_PRESERVE_DATA_BIT_SOFT),
870
871     DECL(AL_EVENT_CALLBACK_FUNCTION_SOFT),
872     DECL(AL_EVENT_CALLBACK_USER_PARAM_SOFT),
873     DECL(AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT),
874     DECL(AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT),
875     DECL(AL_EVENT_TYPE_DISCONNECTED_SOFT),
876
877     DECL(AL_DROP_UNMATCHED_SOFT),
878     DECL(AL_REMIX_UNMATCHED_SOFT),
879
880     DECL(AL_AMBISONIC_LAYOUT_SOFT),
881     DECL(AL_AMBISONIC_SCALING_SOFT),
882     DECL(AL_FUMA_SOFT),
883     DECL(AL_ACN_SOFT),
884     DECL(AL_SN3D_SOFT),
885     DECL(AL_N3D_SOFT),
886
887     DECL(AL_BUFFER_CALLBACK_FUNCTION_SOFT),
888     DECL(AL_BUFFER_CALLBACK_USER_PARAM_SOFT),
889
890     DECL(AL_UNPACK_AMBISONIC_ORDER_SOFT),
891
892     DECL(AL_EFFECT_CONVOLUTION_REVERB_SOFT),
893     DECL(AL_EFFECTSLOT_STATE_SOFT),
894
895     DECL(AL_FORMAT_UHJ2CHN8_SOFT),
896     DECL(AL_FORMAT_UHJ2CHN16_SOFT),
897     DECL(AL_FORMAT_UHJ2CHN_FLOAT32_SOFT),
898     DECL(AL_FORMAT_UHJ3CHN8_SOFT),
899     DECL(AL_FORMAT_UHJ3CHN16_SOFT),
900     DECL(AL_FORMAT_UHJ3CHN_FLOAT32_SOFT),
901     DECL(AL_FORMAT_UHJ4CHN8_SOFT),
902     DECL(AL_FORMAT_UHJ4CHN16_SOFT),
903     DECL(AL_FORMAT_UHJ4CHN_FLOAT32_SOFT),
904     DECL(AL_STEREO_MODE_SOFT),
905     DECL(AL_NORMAL_SOFT),
906     DECL(AL_SUPER_STEREO_SOFT),
907     DECL(AL_SUPER_STEREO_WIDTH_SOFT),
908
909     DECL(AL_FORMAT_UHJ2CHN_MULAW_SOFT),
910     DECL(AL_FORMAT_UHJ2CHN_ALAW_SOFT),
911     DECL(AL_FORMAT_UHJ2CHN_IMA4_SOFT),
912     DECL(AL_FORMAT_UHJ2CHN_MSADPCM_SOFT),
913     DECL(AL_FORMAT_UHJ3CHN_MULAW_SOFT),
914     DECL(AL_FORMAT_UHJ3CHN_ALAW_SOFT),
915     DECL(AL_FORMAT_UHJ4CHN_MULAW_SOFT),
916     DECL(AL_FORMAT_UHJ4CHN_ALAW_SOFT),
917
918     DECL(AL_STOP_SOURCES_ON_DISCONNECT_SOFT),
919
920 #ifdef ALSOFT_EAX
921 }, eaxEnumerations[] = {
922     DECL(AL_EAX_RAM_SIZE),
923     DECL(AL_EAX_RAM_FREE),
924     DECL(AL_STORAGE_AUTOMATIC),
925     DECL(AL_STORAGE_HARDWARE),
926     DECL(AL_STORAGE_ACCESSIBLE),
927 #endif // ALSOFT_EAX
928 };
929 #undef DECL
930
931 constexpr ALCchar alcNoError[] = "No Error";
932 constexpr ALCchar alcErrInvalidDevice[] = "Invalid Device";
933 constexpr ALCchar alcErrInvalidContext[] = "Invalid Context";
934 constexpr ALCchar alcErrInvalidEnum[] = "Invalid Enum";
935 constexpr ALCchar alcErrInvalidValue[] = "Invalid Value";
936 constexpr ALCchar alcErrOutOfMemory[] = "Out of Memory";
937
938
939 /************************************************
940  * Global variables
941  ************************************************/
942
943 /* Enumerated device names */
944 constexpr ALCchar alcDefaultName[] = "OpenAL Soft\0";
945
946 std::string alcAllDevicesList;
947 std::string alcCaptureDeviceList;
948
949 /* Default is always the first in the list */
950 std::string alcDefaultAllDevicesSpecifier;
951 std::string alcCaptureDefaultDeviceSpecifier;
952
953 std::atomic<ALCenum> LastNullDeviceError{ALC_NO_ERROR};
954
955 /* Flag to trap ALC device errors */
956 bool TrapALCError{false};
957
958 /* One-time configuration init control */
959 std::once_flag alc_config_once{};
960
961 /* Flag to specify if alcSuspendContext/alcProcessContext should defer/process
962  * updates.
963  */
964 bool SuspendDefers{true};
965
966 /* Initial seed for dithering. */
967 constexpr uint DitherRNGSeed{22222u};
968
969
970 /************************************************
971  * ALC information
972  ************************************************/
973 constexpr ALCchar alcNoDeviceExtList[] =
974     "ALC_ENUMERATE_ALL_EXT "
975     "ALC_ENUMERATION_EXT "
976     "ALC_EXT_CAPTURE "
977     "ALC_EXT_EFX "
978     "ALC_EXT_thread_local_context "
979     "ALC_SOFT_loopback "
980     "ALC_SOFT_loopback_bformat "
981     "ALC_SOFT_reopen_device";
982 constexpr ALCchar alcExtensionList[] =
983     "ALC_ENUMERATE_ALL_EXT "
984     "ALC_ENUMERATION_EXT "
985     "ALC_EXT_CAPTURE "
986     "ALC_EXT_DEDICATED "
987     "ALC_EXT_disconnect "
988     "ALC_EXT_EFX "
989     "ALC_EXT_thread_local_context "
990     "ALC_SOFT_device_clock "
991     "ALC_SOFT_HRTF "
992     "ALC_SOFT_loopback "
993     "ALC_SOFT_loopback_bformat "
994     "ALC_SOFT_output_limiter "
995     "ALC_SOFT_output_mode "
996     "ALC_SOFT_pause_device "
997     "ALC_SOFT_reopen_device";
998 constexpr int alcMajorVersion{1};
999 constexpr int alcMinorVersion{1};
1000
1001 constexpr int alcEFXMajorVersion{1};
1002 constexpr int alcEFXMinorVersion{0};
1003
1004
1005 using DeviceRef = al::intrusive_ptr<ALCdevice>;
1006
1007
1008 /************************************************
1009  * Device lists
1010  ************************************************/
1011 al::vector<ALCdevice*> DeviceList;
1012 al::vector<ALCcontext*> ContextList;
1013
1014 std::recursive_mutex ListLock;
1015
1016
1017 void alc_initconfig(void)
1018 {
1019     if(auto loglevel = al::getenv("ALSOFT_LOGLEVEL"))
1020     {
1021         long lvl = strtol(loglevel->c_str(), nullptr, 0);
1022         if(lvl >= static_cast<long>(LogLevel::Trace))
1023             gLogLevel = LogLevel::Trace;
1024         else if(lvl <= static_cast<long>(LogLevel::Disable))
1025             gLogLevel = LogLevel::Disable;
1026         else
1027             gLogLevel = static_cast<LogLevel>(lvl);
1028     }
1029
1030 #ifdef _WIN32
1031     if(const auto logfile = al::getenv(L"ALSOFT_LOGFILE"))
1032     {
1033         FILE *logf{_wfopen(logfile->c_str(), L"wt")};
1034         if(logf) gLogFile = logf;
1035         else
1036         {
1037             auto u8name = wstr_to_utf8(logfile->c_str());
1038             ERR("Failed to open log file '%s'\n", u8name.c_str());
1039         }
1040     }
1041 #else
1042     if(const auto logfile = al::getenv("ALSOFT_LOGFILE"))
1043     {
1044         FILE *logf{fopen(logfile->c_str(), "wt")};
1045         if(logf) gLogFile = logf;
1046         else ERR("Failed to open log file '%s'\n", logfile->c_str());
1047     }
1048 #endif
1049
1050     TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION, ALSOFT_GIT_COMMIT_HASH,
1051         ALSOFT_GIT_BRANCH);
1052     {
1053         std::string names;
1054         if(al::size(BackendList) < 1)
1055             names = "(none)";
1056         else
1057         {
1058             const al::span<const BackendInfo> infos{BackendList};
1059             names = infos[0].name;
1060             for(const auto &backend : infos.subspan<1>())
1061             {
1062                 names += ", ";
1063                 names += backend.name;
1064             }
1065         }
1066         TRACE("Supported backends: %s\n", names.c_str());
1067     }
1068     ReadALConfig();
1069
1070     if(auto suspendmode = al::getenv("__ALSOFT_SUSPEND_CONTEXT"))
1071     {
1072         if(al::strcasecmp(suspendmode->c_str(), "ignore") == 0)
1073         {
1074             SuspendDefers = false;
1075             TRACE("Selected context suspend behavior, \"ignore\"\n");
1076         }
1077         else
1078             ERR("Unhandled context suspend behavior setting: \"%s\"\n", suspendmode->c_str());
1079     }
1080
1081     int capfilter{0};
1082 #if defined(HAVE_SSE4_1)
1083     capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3 | CPU_CAP_SSE4_1;
1084 #elif defined(HAVE_SSE3)
1085     capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE3;
1086 #elif defined(HAVE_SSE2)
1087     capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
1088 #elif defined(HAVE_SSE)
1089     capfilter |= CPU_CAP_SSE;
1090 #endif
1091 #ifdef HAVE_NEON
1092     capfilter |= CPU_CAP_NEON;
1093 #endif
1094     if(auto cpuopt = ConfigValueStr(nullptr, nullptr, "disable-cpu-exts"))
1095     {
1096         const char *str{cpuopt->c_str()};
1097         if(al::strcasecmp(str, "all") == 0)
1098             capfilter = 0;
1099         else
1100         {
1101             const char *next = str;
1102             do {
1103                 str = next;
1104                 while(isspace(str[0]))
1105                     str++;
1106                 next = strchr(str, ',');
1107
1108                 if(!str[0] || str[0] == ',')
1109                     continue;
1110
1111                 size_t len{next ? static_cast<size_t>(next-str) : strlen(str)};
1112                 while(len > 0 && isspace(str[len-1]))
1113                     len--;
1114                 if(len == 3 && al::strncasecmp(str, "sse", len) == 0)
1115                     capfilter &= ~CPU_CAP_SSE;
1116                 else if(len == 4 && al::strncasecmp(str, "sse2", len) == 0)
1117                     capfilter &= ~CPU_CAP_SSE2;
1118                 else if(len == 4 && al::strncasecmp(str, "sse3", len) == 0)
1119                     capfilter &= ~CPU_CAP_SSE3;
1120                 else if(len == 6 && al::strncasecmp(str, "sse4.1", len) == 0)
1121                     capfilter &= ~CPU_CAP_SSE4_1;
1122                 else if(len == 4 && al::strncasecmp(str, "neon", len) == 0)
1123                     capfilter &= ~CPU_CAP_NEON;
1124                 else
1125                     WARN("Invalid CPU extension \"%s\"\n", str);
1126             } while(next++);
1127         }
1128     }
1129     if(auto cpuopt = GetCPUInfo())
1130     {
1131         if(!cpuopt->mVendor.empty() || !cpuopt->mName.empty())
1132         {
1133             TRACE("Vendor ID: \"%s\"\n", cpuopt->mVendor.c_str());
1134             TRACE("Name: \"%s\"\n", cpuopt->mName.c_str());
1135         }
1136         const int caps{cpuopt->mCaps};
1137         TRACE("Extensions:%s%s%s%s%s%s\n",
1138             ((capfilter&CPU_CAP_SSE)    ? ((caps&CPU_CAP_SSE)    ? " +SSE"    : " -SSE")    : ""),
1139             ((capfilter&CPU_CAP_SSE2)   ? ((caps&CPU_CAP_SSE2)   ? " +SSE2"   : " -SSE2")   : ""),
1140             ((capfilter&CPU_CAP_SSE3)   ? ((caps&CPU_CAP_SSE3)   ? " +SSE3"   : " -SSE3")   : ""),
1141             ((capfilter&CPU_CAP_SSE4_1) ? ((caps&CPU_CAP_SSE4_1) ? " +SSE4.1" : " -SSE4.1") : ""),
1142             ((capfilter&CPU_CAP_NEON)   ? ((caps&CPU_CAP_NEON)   ? " +NEON"   : " -NEON")   : ""),
1143             ((!capfilter) ? " -none-" : ""));
1144         CPUCapFlags = caps & capfilter;
1145     }
1146
1147     if(auto priopt = ConfigValueInt(nullptr, nullptr, "rt-prio"))
1148         RTPrioLevel = *priopt;
1149     if(auto limopt = ConfigValueBool(nullptr, nullptr, "rt-time-limit"))
1150         AllowRTTimeLimit = *limopt;
1151
1152     {
1153         CompatFlagBitset compatflags{};
1154         auto checkflag = [](const char *envname, const char *optname) -> bool
1155         {
1156             if(auto optval = al::getenv(envname))
1157             {
1158                 if(al::strcasecmp(optval->c_str(), "true") == 0
1159                     || strtol(optval->c_str(), nullptr, 0) == 1)
1160                     return true;
1161                 return false;
1162             }
1163             return GetConfigValueBool(nullptr, "game_compat", optname, false);
1164         };
1165         sBufferSubDataCompat = checkflag("__ALSOFT_ENABLE_SUB_DATA_EXT", "enable-sub-data-ext");
1166         compatflags.set(CompatFlags::ReverseX, checkflag("__ALSOFT_REVERSE_X", "reverse-x"));
1167         compatflags.set(CompatFlags::ReverseY, checkflag("__ALSOFT_REVERSE_Y", "reverse-y"));
1168         compatflags.set(CompatFlags::ReverseZ, checkflag("__ALSOFT_REVERSE_Z", "reverse-z"));
1169
1170         aluInit(compatflags, ConfigValueFloat(nullptr, "game_compat", "nfc-scale").value_or(1.0f));
1171     }
1172     Voice::InitMixer(ConfigValueStr(nullptr, nullptr, "resampler"));
1173
1174     auto uhjfiltopt = ConfigValueStr(nullptr, "uhj", "decode-filter");
1175     if(!uhjfiltopt)
1176     {
1177         if((uhjfiltopt = ConfigValueStr(nullptr, "uhj", "filter")))
1178             WARN("uhj/filter is deprecated, please use uhj/decode-filter\n");
1179     }
1180     if(uhjfiltopt)
1181     {
1182         if(al::strcasecmp(uhjfiltopt->c_str(), "fir256") == 0)
1183             UhjDecodeQuality = UhjQualityType::FIR256;
1184         else if(al::strcasecmp(uhjfiltopt->c_str(), "fir512") == 0)
1185             UhjDecodeQuality = UhjQualityType::FIR512;
1186         else if(al::strcasecmp(uhjfiltopt->c_str(), "iir") == 0)
1187             UhjDecodeQuality = UhjQualityType::IIR;
1188         else
1189             WARN("Unsupported uhj/decode-filter: %s\n", uhjfiltopt->c_str());
1190     }
1191     if((uhjfiltopt = ConfigValueStr(nullptr, "uhj", "encode-filter")))
1192     {
1193         if(al::strcasecmp(uhjfiltopt->c_str(), "fir256") == 0)
1194             UhjEncodeQuality = UhjQualityType::FIR256;
1195         else if(al::strcasecmp(uhjfiltopt->c_str(), "fir512") == 0)
1196             UhjEncodeQuality = UhjQualityType::FIR512;
1197         else if(al::strcasecmp(uhjfiltopt->c_str(), "iir") == 0)
1198             UhjEncodeQuality = UhjQualityType::IIR;
1199         else
1200             WARN("Unsupported uhj/encode-filter: %s\n", uhjfiltopt->c_str());
1201     }
1202
1203     auto traperr = al::getenv("ALSOFT_TRAP_ERROR");
1204     if(traperr && (al::strcasecmp(traperr->c_str(), "true") == 0
1205             || std::strtol(traperr->c_str(), nullptr, 0) == 1))
1206     {
1207         TrapALError  = true;
1208         TrapALCError = true;
1209     }
1210     else
1211     {
1212         traperr = al::getenv("ALSOFT_TRAP_AL_ERROR");
1213         if(traperr)
1214             TrapALError = al::strcasecmp(traperr->c_str(), "true") == 0
1215                 || strtol(traperr->c_str(), nullptr, 0) == 1;
1216         else
1217             TrapALError = !!GetConfigValueBool(nullptr, nullptr, "trap-al-error", false);
1218
1219         traperr = al::getenv("ALSOFT_TRAP_ALC_ERROR");
1220         if(traperr)
1221             TrapALCError = al::strcasecmp(traperr->c_str(), "true") == 0
1222                 || strtol(traperr->c_str(), nullptr, 0) == 1;
1223         else
1224             TrapALCError = !!GetConfigValueBool(nullptr, nullptr, "trap-alc-error", false);
1225     }
1226
1227     if(auto boostopt = ConfigValueFloat(nullptr, "reverb", "boost"))
1228     {
1229         const float valf{std::isfinite(*boostopt) ? clampf(*boostopt, -24.0f, 24.0f) : 0.0f};
1230         ReverbBoost *= std::pow(10.0f, valf / 20.0f);
1231     }
1232
1233     auto BackendListEnd = std::end(BackendList);
1234     auto devopt = al::getenv("ALSOFT_DRIVERS");
1235     if(devopt || (devopt=ConfigValueStr(nullptr, nullptr, "drivers")))
1236     {
1237         auto backendlist_cur = std::begin(BackendList);
1238
1239         bool endlist{true};
1240         const char *next{devopt->c_str()};
1241         do {
1242             const char *devs{next};
1243             while(isspace(devs[0]))
1244                 devs++;
1245             next = strchr(devs, ',');
1246
1247             const bool delitem{devs[0] == '-'};
1248             if(devs[0] == '-') devs++;
1249
1250             if(!devs[0] || devs[0] == ',')
1251             {
1252                 endlist = false;
1253                 continue;
1254             }
1255             endlist = true;
1256
1257             size_t len{next ? (static_cast<size_t>(next-devs)) : strlen(devs)};
1258             while(len > 0 && isspace(devs[len-1])) --len;
1259 #ifdef HAVE_WASAPI
1260             /* HACK: For backwards compatibility, convert backend references of
1261              * mmdevapi to wasapi. This should eventually be removed.
1262              */
1263             if(len == 8 && strncmp(devs, "mmdevapi", len) == 0)
1264             {
1265                 devs = "wasapi";
1266                 len = 6;
1267             }
1268 #endif
1269
1270             auto find_backend = [devs,len](const BackendInfo &backend) -> bool
1271             { return len == strlen(backend.name) && strncmp(backend.name, devs, len) == 0; };
1272             auto this_backend = std::find_if(std::begin(BackendList), BackendListEnd,
1273                 find_backend);
1274
1275             if(this_backend == BackendListEnd)
1276                 continue;
1277
1278             if(delitem)
1279                 BackendListEnd = std::move(this_backend+1, BackendListEnd, this_backend);
1280             else
1281                 backendlist_cur = std::rotate(backendlist_cur, this_backend, this_backend+1);
1282         } while(next++);
1283
1284         if(endlist)
1285             BackendListEnd = backendlist_cur;
1286     }
1287
1288     auto init_backend = [](BackendInfo &backend) -> void
1289     {
1290         if(PlaybackFactory && CaptureFactory)
1291             return;
1292
1293         BackendFactory &factory = backend.getFactory();
1294         if(!factory.init())
1295         {
1296             WARN("Failed to initialize backend \"%s\"\n", backend.name);
1297             return;
1298         }
1299
1300         TRACE("Initialized backend \"%s\"\n", backend.name);
1301         if(!PlaybackFactory && factory.querySupport(BackendType::Playback))
1302         {
1303             PlaybackFactory = &factory;
1304             TRACE("Added \"%s\" for playback\n", backend.name);
1305         }
1306         if(!CaptureFactory && factory.querySupport(BackendType::Capture))
1307         {
1308             CaptureFactory = &factory;
1309             TRACE("Added \"%s\" for capture\n", backend.name);
1310         }
1311     };
1312     std::for_each(std::begin(BackendList), BackendListEnd, init_backend);
1313
1314     LoopbackBackendFactory::getFactory().init();
1315
1316     if(!PlaybackFactory)
1317         WARN("No playback backend available!\n");
1318     if(!CaptureFactory)
1319         WARN("No capture backend available!\n");
1320
1321     if(auto exclopt = ConfigValueStr(nullptr, nullptr, "excludefx"))
1322     {
1323         const char *next{exclopt->c_str()};
1324         do {
1325             const char *str{next};
1326             next = strchr(str, ',');
1327
1328             if(!str[0] || next == str)
1329                 continue;
1330
1331             size_t len{next ? static_cast<size_t>(next-str) : strlen(str)};
1332             for(const EffectList &effectitem : gEffectList)
1333             {
1334                 if(len == strlen(effectitem.name) &&
1335                    strncmp(effectitem.name, str, len) == 0)
1336                     DisabledEffects[effectitem.type] = true;
1337             }
1338         } while(next++);
1339     }
1340
1341     InitEffect(&ALCcontext::sDefaultEffect);
1342     auto defrevopt = al::getenv("ALSOFT_DEFAULT_REVERB");
1343     if(defrevopt || (defrevopt=ConfigValueStr(nullptr, nullptr, "default-reverb")))
1344         LoadReverbPreset(defrevopt->c_str(), &ALCcontext::sDefaultEffect);
1345
1346 #ifdef ALSOFT_EAX
1347     {
1348         static constexpr char eax_block_name[] = "eax";
1349
1350         if(const auto eax_enable_opt = ConfigValueBool(nullptr, eax_block_name, "enable"))
1351         {
1352             eax_g_is_enabled = *eax_enable_opt;
1353             if(!eax_g_is_enabled)
1354                 TRACE("%s\n", "EAX disabled by a configuration.");
1355         }
1356         else
1357             eax_g_is_enabled = true;
1358
1359         if((DisabledEffects[EAXREVERB_EFFECT] || DisabledEffects[CHORUS_EFFECT])
1360             && eax_g_is_enabled)
1361         {
1362             eax_g_is_enabled = false;
1363             TRACE("EAX disabled because %s disabled.\n",
1364                 (DisabledEffects[EAXREVERB_EFFECT] && DisabledEffects[CHORUS_EFFECT])
1365                     ? "EAXReverb and Chorus are" :
1366                 DisabledEffects[EAXREVERB_EFFECT] ? "EAXReverb is" :
1367                 DisabledEffects[CHORUS_EFFECT] ? "Chorus is" : "");
1368         }
1369     }
1370 #endif // ALSOFT_EAX
1371 }
1372 inline void InitConfig()
1373 { std::call_once(alc_config_once, [](){alc_initconfig();}); }
1374
1375
1376 /************************************************
1377  * Device enumeration
1378  ************************************************/
1379 void ProbeAllDevicesList()
1380 {
1381     InitConfig();
1382
1383     std::lock_guard<std::recursive_mutex> _{ListLock};
1384     if(!PlaybackFactory)
1385         decltype(alcAllDevicesList){}.swap(alcAllDevicesList);
1386     else
1387     {
1388         std::string names{PlaybackFactory->probe(BackendType::Playback)};
1389         if(names.empty()) names += '\0';
1390         names.swap(alcAllDevicesList);
1391     }
1392 }
1393 void ProbeCaptureDeviceList()
1394 {
1395     InitConfig();
1396
1397     std::lock_guard<std::recursive_mutex> _{ListLock};
1398     if(!CaptureFactory)
1399         decltype(alcCaptureDeviceList){}.swap(alcCaptureDeviceList);
1400     else
1401     {
1402         std::string names{CaptureFactory->probe(BackendType::Capture)};
1403         if(names.empty()) names += '\0';
1404         names.swap(alcCaptureDeviceList);
1405     }
1406 }
1407
1408
1409 struct DevFmtPair { DevFmtChannels chans; DevFmtType type; };
1410 al::optional<DevFmtPair> DecomposeDevFormat(ALenum format)
1411 {
1412     static const struct {
1413         ALenum format;
1414         DevFmtChannels channels;
1415         DevFmtType type;
1416     } list[] = {
1417         { AL_FORMAT_MONO8,        DevFmtMono, DevFmtUByte },
1418         { AL_FORMAT_MONO16,       DevFmtMono, DevFmtShort },
1419         { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1420
1421         { AL_FORMAT_STEREO8,        DevFmtStereo, DevFmtUByte },
1422         { AL_FORMAT_STEREO16,       DevFmtStereo, DevFmtShort },
1423         { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1424
1425         { AL_FORMAT_QUAD8,  DevFmtQuad, DevFmtUByte },
1426         { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1427         { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1428
1429         { AL_FORMAT_51CHN8,  DevFmtX51, DevFmtUByte },
1430         { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1431         { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1432
1433         { AL_FORMAT_61CHN8,  DevFmtX61, DevFmtUByte },
1434         { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1435         { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1436
1437         { AL_FORMAT_71CHN8,  DevFmtX71, DevFmtUByte },
1438         { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1439         { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1440     };
1441
1442     for(const auto &item : list)
1443     {
1444         if(item.format == format)
1445             return al::make_optional<DevFmtPair>({item.channels, item.type});
1446     }
1447
1448     return al::nullopt;
1449 }
1450
1451 al::optional<DevFmtType> DevFmtTypeFromEnum(ALCenum type)
1452 {
1453     switch(type)
1454     {
1455     case ALC_BYTE_SOFT: return DevFmtByte;
1456     case ALC_UNSIGNED_BYTE_SOFT: return DevFmtUByte;
1457     case ALC_SHORT_SOFT: return DevFmtShort;
1458     case ALC_UNSIGNED_SHORT_SOFT: return DevFmtUShort;
1459     case ALC_INT_SOFT: return DevFmtInt;
1460     case ALC_UNSIGNED_INT_SOFT: return DevFmtUInt;
1461     case ALC_FLOAT_SOFT: return DevFmtFloat;
1462     }
1463     WARN("Unsupported format type: 0x%04x\n", type);
1464     return al::nullopt;
1465 }
1466 ALCenum EnumFromDevFmt(DevFmtType type)
1467 {
1468     switch(type)
1469     {
1470     case DevFmtByte: return ALC_BYTE_SOFT;
1471     case DevFmtUByte: return ALC_UNSIGNED_BYTE_SOFT;
1472     case DevFmtShort: return ALC_SHORT_SOFT;
1473     case DevFmtUShort: return ALC_UNSIGNED_SHORT_SOFT;
1474     case DevFmtInt: return ALC_INT_SOFT;
1475     case DevFmtUInt: return ALC_UNSIGNED_INT_SOFT;
1476     case DevFmtFloat: return ALC_FLOAT_SOFT;
1477     }
1478     throw std::runtime_error{"Invalid DevFmtType: "+std::to_string(int(type))};
1479 }
1480
1481 al::optional<DevFmtChannels> DevFmtChannelsFromEnum(ALCenum channels)
1482 {
1483     switch(channels)
1484     {
1485     case ALC_MONO_SOFT: return DevFmtMono;
1486     case ALC_STEREO_SOFT: return DevFmtStereo;
1487     case ALC_QUAD_SOFT: return DevFmtQuad;
1488     case ALC_5POINT1_SOFT: return DevFmtX51;
1489     case ALC_6POINT1_SOFT: return DevFmtX61;
1490     case ALC_7POINT1_SOFT: return DevFmtX71;
1491     case ALC_BFORMAT3D_SOFT: return DevFmtAmbi3D;
1492     }
1493     WARN("Unsupported format channels: 0x%04x\n", channels);
1494     return al::nullopt;
1495 }
1496 ALCenum EnumFromDevFmt(DevFmtChannels channels)
1497 {
1498     switch(channels)
1499     {
1500     case DevFmtMono: return ALC_MONO_SOFT;
1501     case DevFmtStereo: return ALC_STEREO_SOFT;
1502     case DevFmtQuad: return ALC_QUAD_SOFT;
1503     case DevFmtX51: return ALC_5POINT1_SOFT;
1504     case DevFmtX61: return ALC_6POINT1_SOFT;
1505     case DevFmtX71: return ALC_7POINT1_SOFT;
1506     case DevFmtAmbi3D: return ALC_BFORMAT3D_SOFT;
1507     /* FIXME: Shouldn't happen. */
1508     case DevFmtX714:
1509     case DevFmtX3D71: break;
1510     }
1511     throw std::runtime_error{"Invalid DevFmtChannels: "+std::to_string(int(channels))};
1512 }
1513
1514 al::optional<DevAmbiLayout> DevAmbiLayoutFromEnum(ALCenum layout)
1515 {
1516     switch(layout)
1517     {
1518     case ALC_FUMA_SOFT: return DevAmbiLayout::FuMa;
1519     case ALC_ACN_SOFT: return DevAmbiLayout::ACN;
1520     }
1521     WARN("Unsupported ambisonic layout: 0x%04x\n", layout);
1522     return al::nullopt;
1523 }
1524 ALCenum EnumFromDevAmbi(DevAmbiLayout layout)
1525 {
1526     switch(layout)
1527     {
1528     case DevAmbiLayout::FuMa: return ALC_FUMA_SOFT;
1529     case DevAmbiLayout::ACN: return ALC_ACN_SOFT;
1530     }
1531     throw std::runtime_error{"Invalid DevAmbiLayout: "+std::to_string(int(layout))};
1532 }
1533
1534 al::optional<DevAmbiScaling> DevAmbiScalingFromEnum(ALCenum scaling)
1535 {
1536     switch(scaling)
1537     {
1538     case ALC_FUMA_SOFT: return DevAmbiScaling::FuMa;
1539     case ALC_SN3D_SOFT: return DevAmbiScaling::SN3D;
1540     case ALC_N3D_SOFT: return DevAmbiScaling::N3D;
1541     }
1542     WARN("Unsupported ambisonic scaling: 0x%04x\n", scaling);
1543     return al::nullopt;
1544 }
1545 ALCenum EnumFromDevAmbi(DevAmbiScaling scaling)
1546 {
1547     switch(scaling)
1548     {
1549     case DevAmbiScaling::FuMa: return ALC_FUMA_SOFT;
1550     case DevAmbiScaling::SN3D: return ALC_SN3D_SOFT;
1551     case DevAmbiScaling::N3D: return ALC_N3D_SOFT;
1552     }
1553     throw std::runtime_error{"Invalid DevAmbiScaling: "+std::to_string(int(scaling))};
1554 }
1555
1556
1557 /* Downmixing channel arrays, to map the given format's missing channels to
1558  * existing ones. Based on Wine's DSound downmix values, which are based on
1559  * PulseAudio's.
1560  */
1561 constexpr std::array<InputRemixMap::TargetMix,2> FrontStereoSplit{{
1562     {FrontLeft, 0.5f}, {FrontRight, 0.5f}
1563 }};
1564 constexpr std::array<InputRemixMap::TargetMix,1> FrontLeft9{{
1565     {FrontLeft, 1.0f/9.0f}
1566 }};
1567 constexpr std::array<InputRemixMap::TargetMix,1> FrontRight9{{
1568     {FrontRight, 1.0f/9.0f}
1569 }};
1570 constexpr std::array<InputRemixMap::TargetMix,2> BackMonoToFrontSplit{{
1571     {FrontLeft, 0.5f/9.0f}, {FrontRight, 0.5f/9.0f}
1572 }};
1573 constexpr std::array<InputRemixMap::TargetMix,2> LeftStereoSplit{{
1574     {FrontLeft, 0.5f}, {BackLeft, 0.5f}
1575 }};
1576 constexpr std::array<InputRemixMap::TargetMix,2> RightStereoSplit{{
1577     {FrontRight, 0.5f}, {BackRight, 0.5f}
1578 }};
1579 constexpr std::array<InputRemixMap::TargetMix,2> BackStereoSplit{{
1580     {BackLeft, 0.5f}, {BackRight, 0.5f}
1581 }};
1582 constexpr std::array<InputRemixMap::TargetMix,2> SideStereoSplit{{
1583     {SideLeft, 0.5f}, {SideRight, 0.5f}
1584 }};
1585 constexpr std::array<InputRemixMap::TargetMix,1> ToSideLeft{{
1586     {SideLeft, 1.0f}
1587 }};
1588 constexpr std::array<InputRemixMap::TargetMix,1> ToSideRight{{
1589     {SideRight, 1.0f}
1590 }};
1591 constexpr std::array<InputRemixMap::TargetMix,2> BackLeftSplit{{
1592     {SideLeft, 0.5f}, {BackCenter, 0.5f}
1593 }};
1594 constexpr std::array<InputRemixMap::TargetMix,2> BackRightSplit{{
1595     {SideRight, 0.5f}, {BackCenter, 0.5f}
1596 }};
1597
1598 const std::array<InputRemixMap,6> StereoDownmix{{
1599     { FrontCenter, FrontStereoSplit },
1600     { SideLeft,    FrontLeft9 },
1601     { SideRight,   FrontRight9 },
1602     { BackLeft,    FrontLeft9 },
1603     { BackRight,   FrontRight9 },
1604     { BackCenter,  BackMonoToFrontSplit },
1605 }};
1606 const std::array<InputRemixMap,4> QuadDownmix{{
1607     { FrontCenter, FrontStereoSplit },
1608     { SideLeft,    LeftStereoSplit },
1609     { SideRight,   RightStereoSplit },
1610     { BackCenter,  BackStereoSplit },
1611 }};
1612 const std::array<InputRemixMap,3> X51Downmix{{
1613     { BackLeft,   ToSideLeft },
1614     { BackRight,  ToSideRight },
1615     { BackCenter, SideStereoSplit },
1616 }};
1617 const std::array<InputRemixMap,2> X61Downmix{{
1618     { BackLeft,  BackLeftSplit },
1619     { BackRight, BackRightSplit },
1620 }};
1621 const std::array<InputRemixMap,1> X71Downmix{{
1622     { BackCenter, BackStereoSplit },
1623 }};
1624
1625
1626 /** Stores the latest ALC device error. */
1627 void alcSetError(ALCdevice *device, ALCenum errorCode)
1628 {
1629     WARN("Error generated on device %p, code 0x%04x\n", voidp{device}, errorCode);
1630     if(TrapALCError)
1631     {
1632 #ifdef _WIN32
1633         /* DebugBreak() will cause an exception if there is no debugger */
1634         if(IsDebuggerPresent())
1635             DebugBreak();
1636 #elif defined(SIGTRAP)
1637         raise(SIGTRAP);
1638 #endif
1639     }
1640
1641     if(device)
1642         device->LastError.store(errorCode);
1643     else
1644         LastNullDeviceError.store(errorCode);
1645 }
1646
1647
1648 std::unique_ptr<Compressor> CreateDeviceLimiter(const ALCdevice *device, const float threshold)
1649 {
1650     static constexpr bool AutoKnee{true};
1651     static constexpr bool AutoAttack{true};
1652     static constexpr bool AutoRelease{true};
1653     static constexpr bool AutoPostGain{true};
1654     static constexpr bool AutoDeclip{true};
1655     static constexpr float LookAheadTime{0.001f};
1656     static constexpr float HoldTime{0.002f};
1657     static constexpr float PreGainDb{0.0f};
1658     static constexpr float PostGainDb{0.0f};
1659     static constexpr float Ratio{std::numeric_limits<float>::infinity()};
1660     static constexpr float KneeDb{0.0f};
1661     static constexpr float AttackTime{0.02f};
1662     static constexpr float ReleaseTime{0.2f};
1663
1664     return Compressor::Create(device->RealOut.Buffer.size(), static_cast<float>(device->Frequency),
1665         AutoKnee, AutoAttack, AutoRelease, AutoPostGain, AutoDeclip, LookAheadTime, HoldTime,
1666         PreGainDb, PostGainDb, threshold, Ratio, KneeDb, AttackTime, ReleaseTime);
1667 }
1668
1669 /**
1670  * Updates the device's base clock time with however many samples have been
1671  * done. This is used so frequency changes on the device don't cause the time
1672  * to jump forward or back. Must not be called while the device is running/
1673  * mixing.
1674  */
1675 inline void UpdateClockBase(ALCdevice *device)
1676 {
1677     IncrementRef(device->MixCount);
1678     device->ClockBase += nanoseconds{seconds{device->SamplesDone}} / device->Frequency;
1679     device->SamplesDone = 0;
1680     IncrementRef(device->MixCount);
1681 }
1682
1683 /**
1684  * Updates device parameters according to the attribute list (caller is
1685  * responsible for holding the list lock).
1686  */
1687 ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
1688 {
1689     if((!attrList || !attrList[0]) && device->Type == DeviceType::Loopback)
1690     {
1691         WARN("Missing attributes for loopback device\n");
1692         return ALC_INVALID_VALUE;
1693     }
1694
1695     uint numMono{device->NumMonoSources};
1696     uint numStereo{device->NumStereoSources};
1697     uint numSends{device->NumAuxSends};
1698     al::optional<StereoEncoding> stereomode;
1699     al::optional<bool> optlimit;
1700     al::optional<uint> optsrate;
1701     al::optional<DevFmtChannels> optchans;
1702     al::optional<DevFmtType> opttype;
1703     al::optional<DevAmbiLayout> optlayout;
1704     al::optional<DevAmbiScaling> optscale;
1705     uint period_size{DEFAULT_UPDATE_SIZE};
1706     uint buffer_size{DEFAULT_UPDATE_SIZE * DEFAULT_NUM_UPDATES};
1707     int hrtf_id{-1};
1708     uint aorder{0u};
1709
1710     if(device->Type != DeviceType::Loopback)
1711     {
1712         /* Get default settings from the user configuration */
1713
1714         if(auto freqopt = device->configValue<uint>(nullptr, "frequency"))
1715         {
1716             optsrate = clampu(*freqopt, MIN_OUTPUT_RATE, MAX_OUTPUT_RATE);
1717
1718             const double scale{static_cast<double>(*optsrate) / DEFAULT_OUTPUT_RATE};
1719             period_size = static_cast<uint>(period_size*scale + 0.5);
1720         }
1721
1722         if(auto persizeopt = device->configValue<uint>(nullptr, "period_size"))
1723             period_size = clampu(*persizeopt, 64, 8192);
1724         if(auto numperopt = device->configValue<uint>(nullptr, "periods"))
1725             buffer_size = clampu(*numperopt, 2, 16) * period_size;
1726         else
1727             buffer_size = period_size * DEFAULT_NUM_UPDATES;
1728
1729         if(auto typeopt = device->configValue<std::string>(nullptr, "sample-type"))
1730         {
1731             static constexpr struct TypeMap {
1732                 const char name[8];
1733                 DevFmtType type;
1734             } typelist[] = {
1735                 { "int8",    DevFmtByte   },
1736                 { "uint8",   DevFmtUByte  },
1737                 { "int16",   DevFmtShort  },
1738                 { "uint16",  DevFmtUShort },
1739                 { "int32",   DevFmtInt    },
1740                 { "uint32",  DevFmtUInt   },
1741                 { "float32", DevFmtFloat  },
1742             };
1743
1744             const ALCchar *fmt{typeopt->c_str()};
1745             auto iter = std::find_if(std::begin(typelist), std::end(typelist),
1746                 [fmt](const TypeMap &entry) -> bool
1747                 { return al::strcasecmp(entry.name, fmt) == 0; });
1748             if(iter == std::end(typelist))
1749                 ERR("Unsupported sample-type: %s\n", fmt);
1750             else
1751                 opttype = iter->type;
1752         }
1753         if(auto chanopt = device->configValue<std::string>(nullptr, "channels"))
1754         {
1755             static constexpr struct ChannelMap {
1756                 const char name[16];
1757                 DevFmtChannels chans;
1758                 uint8_t order;
1759             } chanlist[] = {
1760                 { "mono",       DevFmtMono,   0 },
1761                 { "stereo",     DevFmtStereo, 0 },
1762                 { "quad",       DevFmtQuad,   0 },
1763                 { "surround51", DevFmtX51,    0 },
1764                 { "surround61", DevFmtX61,    0 },
1765                 { "surround71", DevFmtX71,    0 },
1766                 { "surround714", DevFmtX714,  0 },
1767                 { "surround3d71", DevFmtX3D71, 0 },
1768                 { "surround51rear", DevFmtX51, 0 },
1769                 { "ambi1", DevFmtAmbi3D, 1 },
1770                 { "ambi2", DevFmtAmbi3D, 2 },
1771                 { "ambi3", DevFmtAmbi3D, 3 },
1772             };
1773
1774             const ALCchar *fmt{chanopt->c_str()};
1775             auto iter = std::find_if(std::begin(chanlist), std::end(chanlist),
1776                 [fmt](const ChannelMap &entry) -> bool
1777                 { return al::strcasecmp(entry.name, fmt) == 0; });
1778             if(iter == std::end(chanlist))
1779                 ERR("Unsupported channels: %s\n", fmt);
1780             else
1781             {
1782                 optchans = iter->chans;
1783                 aorder = iter->order;
1784             }
1785         }
1786         if(auto ambiopt = device->configValue<std::string>(nullptr, "ambi-format"))
1787         {
1788             const ALCchar *fmt{ambiopt->c_str()};
1789             if(al::strcasecmp(fmt, "fuma") == 0)
1790             {
1791                 optlayout = DevAmbiLayout::FuMa;
1792                 optscale = DevAmbiScaling::FuMa;
1793             }
1794             else if(al::strcasecmp(fmt, "acn+fuma") == 0)
1795             {
1796                 optlayout = DevAmbiLayout::ACN;
1797                 optscale = DevAmbiScaling::FuMa;
1798             }
1799             else if(al::strcasecmp(fmt, "ambix") == 0 || al::strcasecmp(fmt, "acn+sn3d") == 0)
1800             {
1801                 optlayout = DevAmbiLayout::ACN;
1802                 optscale = DevAmbiScaling::SN3D;
1803             }
1804             else if(al::strcasecmp(fmt, "acn+n3d") == 0)
1805             {
1806                 optlayout = DevAmbiLayout::ACN;
1807                 optscale = DevAmbiScaling::N3D;
1808             }
1809             else
1810                 ERR("Unsupported ambi-format: %s\n", fmt);
1811         }
1812
1813         if(auto hrtfopt = device->configValue<std::string>(nullptr, "hrtf"))
1814         {
1815             WARN("general/hrtf is deprecated, please use stereo-encoding instead\n");
1816
1817             const char *hrtf{hrtfopt->c_str()};
1818             if(al::strcasecmp(hrtf, "true") == 0)
1819                 stereomode = StereoEncoding::Hrtf;
1820             else if(al::strcasecmp(hrtf, "false") == 0)
1821             {
1822                 if(!stereomode || *stereomode == StereoEncoding::Hrtf)
1823                     stereomode = StereoEncoding::Default;
1824             }
1825             else if(al::strcasecmp(hrtf, "auto") != 0)
1826                 ERR("Unexpected hrtf value: %s\n", hrtf);
1827         }
1828     }
1829
1830     if(auto encopt = device->configValue<std::string>(nullptr, "stereo-encoding"))
1831     {
1832         const char *mode{encopt->c_str()};
1833         if(al::strcasecmp(mode, "basic") == 0 || al::strcasecmp(mode, "panpot") == 0)
1834             stereomode = StereoEncoding::Basic;
1835         else if(al::strcasecmp(mode, "uhj") == 0)
1836             stereomode = StereoEncoding::Uhj;
1837         else if(al::strcasecmp(mode, "hrtf") == 0)
1838             stereomode = StereoEncoding::Hrtf;
1839         else
1840             ERR("Unexpected stereo-encoding: %s\n", mode);
1841     }
1842
1843     // Check for app-specified attributes
1844     if(attrList && attrList[0])
1845     {
1846         ALenum outmode{ALC_ANY_SOFT};
1847         al::optional<bool> opthrtf;
1848         int freqAttr{};
1849
1850 #define ATTRIBUTE(a) a: TRACE("%s = %d\n", #a, attrList[attrIdx + 1]);
1851         size_t attrIdx{0};
1852         while(attrList[attrIdx])
1853         {
1854             switch(attrList[attrIdx])
1855             {
1856             case ATTRIBUTE(ALC_FORMAT_CHANNELS_SOFT)
1857                 if(device->Type == DeviceType::Loopback)
1858                     optchans = DevFmtChannelsFromEnum(attrList[attrIdx + 1]);
1859                 break;
1860
1861             case ATTRIBUTE(ALC_FORMAT_TYPE_SOFT)
1862                 if(device->Type == DeviceType::Loopback)
1863                     opttype = DevFmtTypeFromEnum(attrList[attrIdx + 1]);
1864                 break;
1865
1866             case ATTRIBUTE(ALC_FREQUENCY)
1867                 freqAttr = attrList[attrIdx + 1];
1868                 break;
1869
1870             case ATTRIBUTE(ALC_AMBISONIC_LAYOUT_SOFT)
1871                 if(device->Type == DeviceType::Loopback)
1872                     optlayout = DevAmbiLayoutFromEnum(attrList[attrIdx + 1]);
1873                 break;
1874
1875             case ATTRIBUTE(ALC_AMBISONIC_SCALING_SOFT)
1876                 if(device->Type == DeviceType::Loopback)
1877                     optscale = DevAmbiScalingFromEnum(attrList[attrIdx + 1]);
1878                 break;
1879
1880             case ATTRIBUTE(ALC_AMBISONIC_ORDER_SOFT)
1881                 if(device->Type == DeviceType::Loopback)
1882                     aorder = static_cast<uint>(attrList[attrIdx + 1]);
1883                 break;
1884
1885             case ATTRIBUTE(ALC_MONO_SOURCES)
1886                 numMono = static_cast<uint>(attrList[attrIdx + 1]);
1887                 if(numMono > INT_MAX) numMono = 0;
1888                 break;
1889
1890             case ATTRIBUTE(ALC_STEREO_SOURCES)
1891                 numStereo = static_cast<uint>(attrList[attrIdx + 1]);
1892                 if(numStereo > INT_MAX) numStereo = 0;
1893                 break;
1894
1895             case ATTRIBUTE(ALC_MAX_AUXILIARY_SENDS)
1896                 numSends = static_cast<uint>(attrList[attrIdx + 1]);
1897                 if(numSends > INT_MAX) numSends = 0;
1898                 else numSends = minu(numSends, MAX_SENDS);
1899                 break;
1900
1901             case ATTRIBUTE(ALC_HRTF_SOFT)
1902                 if(attrList[attrIdx + 1] == ALC_FALSE)
1903                     opthrtf = false;
1904                 else if(attrList[attrIdx + 1] == ALC_TRUE)
1905                     opthrtf = true;
1906                 else if(attrList[attrIdx + 1] == ALC_DONT_CARE_SOFT)
1907                     opthrtf = al::nullopt;
1908                 break;
1909
1910             case ATTRIBUTE(ALC_HRTF_ID_SOFT)
1911                 hrtf_id = attrList[attrIdx + 1];
1912                 break;
1913
1914             case ATTRIBUTE(ALC_OUTPUT_LIMITER_SOFT)
1915                 if(attrList[attrIdx + 1] == ALC_FALSE)
1916                     optlimit = false;
1917                 else if(attrList[attrIdx + 1] == ALC_TRUE)
1918                     optlimit = true;
1919                 else if(attrList[attrIdx + 1] == ALC_DONT_CARE_SOFT)
1920                     optlimit = al::nullopt;
1921                 break;
1922
1923             case ATTRIBUTE(ALC_OUTPUT_MODE_SOFT)
1924                 outmode = attrList[attrIdx + 1];
1925                 break;
1926
1927             default:
1928                 TRACE("0x%04X = %d (0x%x)\n", attrList[attrIdx],
1929                     attrList[attrIdx + 1], attrList[attrIdx + 1]);
1930                 break;
1931             }
1932
1933             attrIdx += 2;
1934         }
1935 #undef ATTRIBUTE
1936
1937         if(device->Type == DeviceType::Loopback)
1938         {
1939             if(!optchans || !opttype)
1940                 return ALC_INVALID_VALUE;
1941             if(freqAttr < MIN_OUTPUT_RATE || freqAttr > MAX_OUTPUT_RATE)
1942                 return ALC_INVALID_VALUE;
1943             if(*optchans == DevFmtAmbi3D)
1944             {
1945                 if(!optlayout || !optscale)
1946                     return ALC_INVALID_VALUE;
1947                 if(aorder < 1 || aorder > MaxAmbiOrder)
1948                     return ALC_INVALID_VALUE;
1949                 if((*optlayout == DevAmbiLayout::FuMa || *optscale == DevAmbiScaling::FuMa)
1950                     && aorder > 3)
1951                     return ALC_INVALID_VALUE;
1952             }
1953             else if(*optchans == DevFmtStereo)
1954             {
1955                 if(opthrtf)
1956                 {
1957                     if(*opthrtf)
1958                         stereomode = StereoEncoding::Hrtf;
1959                     else
1960                     {
1961                         if(stereomode.value_or(StereoEncoding::Hrtf) == StereoEncoding::Hrtf)
1962                             stereomode = StereoEncoding::Default;
1963                     }
1964                 }
1965
1966                 if(outmode == ALC_STEREO_BASIC_SOFT)
1967                     stereomode = StereoEncoding::Basic;
1968                 else if(outmode == ALC_STEREO_UHJ_SOFT)
1969                     stereomode = StereoEncoding::Uhj;
1970                 else if(outmode == ALC_STEREO_HRTF_SOFT)
1971                     stereomode = StereoEncoding::Hrtf;
1972             }
1973
1974             optsrate = static_cast<uint>(freqAttr);
1975         }
1976         else
1977         {
1978             if(opthrtf)
1979             {
1980                 if(*opthrtf)
1981                     stereomode = StereoEncoding::Hrtf;
1982                 else
1983                 {
1984                     if(stereomode.value_or(StereoEncoding::Hrtf) == StereoEncoding::Hrtf)
1985                         stereomode = StereoEncoding::Default;
1986                 }
1987             }
1988
1989             if(outmode != ALC_ANY_SOFT)
1990             {
1991                 using OutputMode = ALCdevice::OutputMode;
1992                 switch(OutputMode(outmode))
1993                 {
1994                 case OutputMode::Any: break;
1995                 case OutputMode::Mono: optchans = DevFmtMono; break;
1996                 case OutputMode::Stereo: optchans = DevFmtStereo; break;
1997                 case OutputMode::StereoBasic:
1998                     optchans = DevFmtStereo;
1999                     stereomode = StereoEncoding::Basic;
2000                     break;
2001                 case OutputMode::Uhj2:
2002                     optchans = DevFmtStereo;
2003                     stereomode = StereoEncoding::Uhj;
2004                     break;
2005                 case OutputMode::Hrtf:
2006                     optchans = DevFmtStereo;
2007                     stereomode = StereoEncoding::Hrtf;
2008                     break;
2009                 case OutputMode::Quad: optchans = DevFmtQuad; break;
2010                 case OutputMode::X51: optchans = DevFmtX51; break;
2011                 case OutputMode::X61: optchans = DevFmtX61; break;
2012                 case OutputMode::X71: optchans = DevFmtX71; break;
2013                 }
2014             }
2015
2016             if(freqAttr)
2017             {
2018                 uint oldrate = optsrate.value_or(DEFAULT_OUTPUT_RATE);
2019                 freqAttr = clampi(freqAttr, MIN_OUTPUT_RATE, MAX_OUTPUT_RATE);
2020
2021                 const double scale{static_cast<double>(freqAttr) / oldrate};
2022                 period_size = static_cast<uint>(period_size*scale + 0.5);
2023                 buffer_size = static_cast<uint>(buffer_size*scale + 0.5);
2024                 optsrate = static_cast<uint>(freqAttr);
2025             }
2026         }
2027
2028         /* If a context is already running on the device, stop playback so the
2029          * device attributes can be updated.
2030          */
2031         if(device->Flags.test(DeviceRunning))
2032             device->Backend->stop();
2033         device->Flags.reset(DeviceRunning);
2034
2035         UpdateClockBase(device);
2036     }
2037
2038     if(device->Flags.test(DeviceRunning))
2039         return ALC_NO_ERROR;
2040
2041     device->AvgSpeakerDist = 0.0f;
2042     device->mNFCtrlFilter = NfcFilter{};
2043     device->mUhjEncoder = nullptr;
2044     device->AmbiDecoder = nullptr;
2045     device->Bs2b = nullptr;
2046     device->PostProcess = nullptr;
2047
2048     device->Limiter = nullptr;
2049     device->ChannelDelays = nullptr;
2050
2051     std::fill(std::begin(device->HrtfAccumData), std::end(device->HrtfAccumData), float2{});
2052
2053     device->Dry.AmbiMap.fill(BFChannelConfig{});
2054     device->Dry.Buffer = {};
2055     std::fill(std::begin(device->NumChannelsPerOrder), std::end(device->NumChannelsPerOrder), 0u);
2056     device->RealOut.RemixMap = {};
2057     device->RealOut.ChannelIndex.fill(InvalidChannelIndex);
2058     device->RealOut.Buffer = {};
2059     device->MixBuffer.clear();
2060     device->MixBuffer.shrink_to_fit();
2061
2062     UpdateClockBase(device);
2063     device->FixedLatency = nanoseconds::zero();
2064
2065     device->DitherDepth = 0.0f;
2066     device->DitherSeed = DitherRNGSeed;
2067
2068     device->mHrtfStatus = ALC_HRTF_DISABLED_SOFT;
2069
2070     /*************************************************************************
2071      * Update device format request
2072      */
2073
2074     if(device->Type == DeviceType::Loopback)
2075     {
2076         device->Frequency = *optsrate;
2077         device->FmtChans = *optchans;
2078         device->FmtType = *opttype;
2079         if(device->FmtChans == DevFmtAmbi3D)
2080         {
2081             device->mAmbiOrder = aorder;
2082             device->mAmbiLayout = *optlayout;
2083             device->mAmbiScale = *optscale;
2084         }
2085         device->Flags.set(FrequencyRequest).set(ChannelsRequest).set(SampleTypeRequest);
2086     }
2087     else
2088     {
2089         device->FmtType = opttype.value_or(DevFmtTypeDefault);
2090         device->FmtChans = optchans.value_or(DevFmtChannelsDefault);
2091         device->mAmbiOrder = 0;
2092         device->BufferSize = buffer_size;
2093         device->UpdateSize = period_size;
2094         device->Frequency = optsrate.value_or(DEFAULT_OUTPUT_RATE);
2095         device->Flags.set(FrequencyRequest, optsrate.has_value())
2096             .set(ChannelsRequest, optchans.has_value())
2097             .set(SampleTypeRequest, opttype.has_value());
2098
2099         if(device->FmtChans == DevFmtAmbi3D)
2100         {
2101             device->mAmbiOrder = clampu(aorder, 1, MaxAmbiOrder);
2102             device->mAmbiLayout = optlayout.value_or(DevAmbiLayout::Default);
2103             device->mAmbiScale = optscale.value_or(DevAmbiScaling::Default);
2104             if(device->mAmbiOrder > 3
2105                 && (device->mAmbiLayout == DevAmbiLayout::FuMa
2106                     || device->mAmbiScale == DevAmbiScaling::FuMa))
2107             {
2108                 ERR("FuMa is incompatible with %d%s order ambisonics (up to 3rd order only)\n",
2109                     device->mAmbiOrder,
2110                     (((device->mAmbiOrder%100)/10) == 1) ? "th" :
2111                     ((device->mAmbiOrder%10) == 1) ? "st" :
2112                     ((device->mAmbiOrder%10) == 2) ? "nd" :
2113                     ((device->mAmbiOrder%10) == 3) ? "rd" : "th");
2114                 device->mAmbiOrder = 3;
2115             }
2116         }
2117     }
2118
2119     TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u / %u buffer\n",
2120         device->Flags.test(ChannelsRequest)?"*":"", DevFmtChannelsString(device->FmtChans),
2121         device->Flags.test(SampleTypeRequest)?"*":"", DevFmtTypeString(device->FmtType),
2122         device->Flags.test(FrequencyRequest)?"*":"", device->Frequency,
2123         device->UpdateSize, device->BufferSize);
2124
2125     const uint oldFreq{device->Frequency};
2126     const DevFmtChannels oldChans{device->FmtChans};
2127     const DevFmtType oldType{device->FmtType};
2128     try {
2129         auto backend = device->Backend.get();
2130         if(!backend->reset())
2131             throw al::backend_exception{al::backend_error::DeviceError, "Device reset failure"};
2132     }
2133     catch(std::exception &e) {
2134         ERR("Device error: %s\n", e.what());
2135         device->handleDisconnect("%s", e.what());
2136         return ALC_INVALID_DEVICE;
2137     }
2138
2139     if(device->FmtChans != oldChans && device->Flags.test(ChannelsRequest))
2140     {
2141         ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
2142             DevFmtChannelsString(device->FmtChans));
2143         device->Flags.reset(ChannelsRequest);
2144     }
2145     if(device->FmtType != oldType && device->Flags.test(SampleTypeRequest))
2146     {
2147         ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
2148             DevFmtTypeString(device->FmtType));
2149         device->Flags.reset(SampleTypeRequest);
2150     }
2151     if(device->Frequency != oldFreq && device->Flags.test(FrequencyRequest))
2152     {
2153         WARN("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
2154         device->Flags.reset(FrequencyRequest);
2155     }
2156
2157     TRACE("Post-reset: %s, %s, %uhz, %u / %u buffer\n",
2158         DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2159         device->Frequency, device->UpdateSize, device->BufferSize);
2160
2161     if(device->Type != DeviceType::Loopback)
2162     {
2163         if(auto modeopt = device->configValue<std::string>(nullptr, "stereo-mode"))
2164         {
2165             const char *mode{modeopt->c_str()};
2166             if(al::strcasecmp(mode, "headphones") == 0)
2167                 device->Flags.set(DirectEar);
2168             else if(al::strcasecmp(mode, "speakers") == 0)
2169                 device->Flags.reset(DirectEar);
2170             else if(al::strcasecmp(mode, "auto") != 0)
2171                 ERR("Unexpected stereo-mode: %s\n", mode);
2172         }
2173     }
2174
2175     aluInitRenderer(device, hrtf_id, stereomode);
2176
2177     /* Calculate the max number of sources, and split them between the mono and
2178      * stereo count given the requested number of stereo sources.
2179      */
2180     if(auto srcsopt = device->configValue<uint>(nullptr, "sources"))
2181     {
2182         if(*srcsopt <= 0) numMono = 256;
2183         else numMono = maxu(*srcsopt, 16);
2184     }
2185     else
2186     {
2187         numMono = minu(numMono, INT_MAX-numStereo);
2188         numMono = maxu(numMono+numStereo, 256);
2189     }
2190     numStereo = minu(numStereo, numMono);
2191     numMono -= numStereo;
2192     device->SourcesMax = numMono + numStereo;
2193     device->NumMonoSources = numMono;
2194     device->NumStereoSources = numStereo;
2195
2196     if(auto sendsopt = device->configValue<int>(nullptr, "sends"))
2197         numSends = minu(numSends, static_cast<uint>(clampi(*sendsopt, 0, MAX_SENDS)));
2198     device->NumAuxSends = numSends;
2199
2200     TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
2201         device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
2202         device->AuxiliaryEffectSlotMax, device->NumAuxSends);
2203
2204     switch(device->FmtChans)
2205     {
2206     case DevFmtMono: break;
2207     case DevFmtStereo:
2208         if(!device->mUhjEncoder)
2209             device->RealOut.RemixMap = StereoDownmix;
2210         break;
2211     case DevFmtQuad: device->RealOut.RemixMap = QuadDownmix; break;
2212     case DevFmtX51: device->RealOut.RemixMap = X51Downmix; break;
2213     case DevFmtX61: device->RealOut.RemixMap = X61Downmix; break;
2214     case DevFmtX71: device->RealOut.RemixMap = X71Downmix; break;
2215     case DevFmtX714: device->RealOut.RemixMap = X71Downmix; break;
2216     case DevFmtX3D71: device->RealOut.RemixMap = X51Downmix; break;
2217     case DevFmtAmbi3D: break;
2218     }
2219
2220     nanoseconds::rep sample_delay{0};
2221     if(auto *encoder{device->mUhjEncoder.get()})
2222         sample_delay += encoder->getDelay();
2223
2224     if(device->getConfigValueBool(nullptr, "dither", true))
2225     {
2226         int depth{device->configValue<int>(nullptr, "dither-depth").value_or(0)};
2227         if(depth <= 0)
2228         {
2229             switch(device->FmtType)
2230             {
2231             case DevFmtByte:
2232             case DevFmtUByte:
2233                 depth = 8;
2234                 break;
2235             case DevFmtShort:
2236             case DevFmtUShort:
2237                 depth = 16;
2238                 break;
2239             case DevFmtInt:
2240             case DevFmtUInt:
2241             case DevFmtFloat:
2242                 break;
2243             }
2244         }
2245
2246         if(depth > 0)
2247         {
2248             depth = clampi(depth, 2, 24);
2249             device->DitherDepth = std::pow(2.0f, static_cast<float>(depth-1));
2250         }
2251     }
2252     if(!(device->DitherDepth > 0.0f))
2253         TRACE("Dithering disabled\n");
2254     else
2255         TRACE("Dithering enabled (%d-bit, %g)\n", float2int(std::log2(device->DitherDepth)+0.5f)+1,
2256               device->DitherDepth);
2257
2258     if(!optlimit)
2259         optlimit = device->configValue<bool>(nullptr, "output-limiter");
2260
2261     /* If the gain limiter is unset, use the limiter for integer-based output
2262      * (where samples must be clamped), and don't for floating-point (which can
2263      * take unclamped samples).
2264      */
2265     if(!optlimit)
2266     {
2267         switch(device->FmtType)
2268         {
2269         case DevFmtByte:
2270         case DevFmtUByte:
2271         case DevFmtShort:
2272         case DevFmtUShort:
2273         case DevFmtInt:
2274         case DevFmtUInt:
2275             optlimit = true;
2276             break;
2277         case DevFmtFloat:
2278             break;
2279         }
2280     }
2281     if(optlimit.value_or(false) == false)
2282         TRACE("Output limiter disabled\n");
2283     else
2284     {
2285         float thrshld{1.0f};
2286         switch(device->FmtType)
2287         {
2288         case DevFmtByte:
2289         case DevFmtUByte:
2290             thrshld = 127.0f / 128.0f;
2291             break;
2292         case DevFmtShort:
2293         case DevFmtUShort:
2294             thrshld = 32767.0f / 32768.0f;
2295             break;
2296         case DevFmtInt:
2297         case DevFmtUInt:
2298         case DevFmtFloat:
2299             break;
2300         }
2301         if(device->DitherDepth > 0.0f)
2302             thrshld -= 1.0f / device->DitherDepth;
2303
2304         const float thrshld_dB{std::log10(thrshld) * 20.0f};
2305         auto limiter = CreateDeviceLimiter(device, thrshld_dB);
2306
2307         sample_delay += limiter->getLookAhead();
2308         device->Limiter = std::move(limiter);
2309         TRACE("Output limiter enabled, %.4fdB limit\n", thrshld_dB);
2310     }
2311
2312     /* Convert the sample delay from samples to nanosamples to nanoseconds. */
2313     device->FixedLatency += nanoseconds{seconds{sample_delay}} / device->Frequency;
2314     TRACE("Fixed device latency: %" PRId64 "ns\n", int64_t{device->FixedLatency.count()});
2315
2316     FPUCtl mixer_mode{};
2317     for(ContextBase *ctxbase : *device->mContexts.load())
2318     {
2319         auto *context = static_cast<ALCcontext*>(ctxbase);
2320
2321         std::unique_lock<std::mutex> proplock{context->mPropLock};
2322         std::unique_lock<std::mutex> slotlock{context->mEffectSlotLock};
2323
2324         /* Clear out unused effect slot clusters. */
2325         auto slot_cluster_not_in_use = [](ContextBase::EffectSlotCluster &cluster)
2326         {
2327             for(size_t i{0};i < ContextBase::EffectSlotClusterSize;++i)
2328             {
2329                 if(cluster[i].InUse)
2330                     return false;
2331             }
2332             return true;
2333         };
2334         auto slotcluster_iter = std::remove_if(context->mEffectSlotClusters.begin(),
2335             context->mEffectSlotClusters.end(), slot_cluster_not_in_use);
2336         context->mEffectSlotClusters.erase(slotcluster_iter, context->mEffectSlotClusters.end());
2337
2338         /* Free all wet buffers. Any in use will be reallocated with an updated
2339          * configuration in aluInitEffectPanning.
2340          */
2341         for(auto&& slots : context->mEffectSlotClusters)
2342         {
2343             for(size_t i{0};i < ContextBase::EffectSlotClusterSize;++i)
2344             {
2345                 slots[i].mWetBuffer.clear();
2346                 slots[i].mWetBuffer.shrink_to_fit();
2347                 slots[i].Wet.Buffer = {};
2348             }
2349         }
2350
2351         if(ALeffectslot *slot{context->mDefaultSlot.get()})
2352         {
2353             aluInitEffectPanning(slot->mSlot, context);
2354
2355             EffectState *state{slot->Effect.State.get()};
2356             state->mOutTarget = device->Dry.Buffer;
2357             state->deviceUpdate(device, slot->Buffer);
2358             slot->updateProps(context);
2359         }
2360
2361         if(EffectSlotArray *curarray{context->mActiveAuxSlots.load(std::memory_order_relaxed)})
2362             std::fill_n(curarray->end(), curarray->size(), nullptr);
2363         for(auto &sublist : context->mEffectSlotList)
2364         {
2365             uint64_t usemask{~sublist.FreeMask};
2366             while(usemask)
2367             {
2368                 const int idx{al::countr_zero(usemask)};
2369                 ALeffectslot *slot{sublist.EffectSlots + idx};
2370                 usemask &= ~(1_u64 << idx);
2371
2372                 aluInitEffectPanning(slot->mSlot, context);
2373
2374                 EffectState *state{slot->Effect.State.get()};
2375                 state->mOutTarget = device->Dry.Buffer;
2376                 state->deviceUpdate(device, slot->Buffer);
2377                 slot->updateProps(context);
2378             }
2379         }
2380         slotlock.unlock();
2381
2382         const uint num_sends{device->NumAuxSends};
2383         std::unique_lock<std::mutex> srclock{context->mSourceLock};
2384         for(auto &sublist : context->mSourceList)
2385         {
2386             uint64_t usemask{~sublist.FreeMask};
2387             while(usemask)
2388             {
2389                 const int idx{al::countr_zero(usemask)};
2390                 ALsource *source{sublist.Sources + idx};
2391                 usemask &= ~(1_u64 << idx);
2392
2393                 auto clear_send = [](ALsource::SendData &send) -> void
2394                 {
2395                     if(send.Slot)
2396                         DecrementRef(send.Slot->ref);
2397                     send.Slot = nullptr;
2398                     send.Gain = 1.0f;
2399                     send.GainHF = 1.0f;
2400                     send.HFReference = LOWPASSFREQREF;
2401                     send.GainLF = 1.0f;
2402                     send.LFReference = HIGHPASSFREQREF;
2403                 };
2404                 auto send_begin = source->Send.begin() + static_cast<ptrdiff_t>(num_sends);
2405                 std::for_each(send_begin, source->Send.end(), clear_send);
2406
2407                 source->mPropsDirty = true;
2408             }
2409         }
2410
2411         auto voicelist = context->getVoicesSpan();
2412         for(Voice *voice : voicelist)
2413         {
2414             /* Clear extraneous property set sends. */
2415             std::fill(std::begin(voice->mProps.Send)+num_sends, std::end(voice->mProps.Send),
2416                 VoiceProps::SendData{});
2417
2418             std::fill(voice->mSend.begin()+num_sends, voice->mSend.end(), Voice::TargetData{});
2419             for(auto &chandata : voice->mChans)
2420             {
2421                 std::fill(chandata.mWetParams.begin()+num_sends, chandata.mWetParams.end(),
2422                     SendParams{});
2423             }
2424
2425             if(VoicePropsItem *props{voice->mUpdate.exchange(nullptr, std::memory_order_relaxed)})
2426                 AtomicReplaceHead(context->mFreeVoiceProps, props);
2427
2428             /* Force the voice to stopped if it was stopping. */
2429             Voice::State vstate{Voice::Stopping};
2430             voice->mPlayState.compare_exchange_strong(vstate, Voice::Stopped,
2431                 std::memory_order_acquire, std::memory_order_acquire);
2432             if(voice->mSourceID.load(std::memory_order_relaxed) == 0u)
2433                 continue;
2434
2435             voice->prepare(device);
2436         }
2437         /* Clear all voice props to let them get allocated again. */
2438         context->mVoicePropClusters.clear();
2439         context->mFreeVoiceProps.store(nullptr, std::memory_order_relaxed);
2440         srclock.unlock();
2441
2442         context->mPropsDirty = false;
2443         UpdateContextProps(context);
2444         UpdateAllSourceProps(context);
2445     }
2446     mixer_mode.leave();
2447
2448     if(!device->Flags.test(DevicePaused))
2449     {
2450         try {
2451             auto backend = device->Backend.get();
2452             backend->start();
2453             device->Flags.set(DeviceRunning);
2454         }
2455         catch(al::backend_exception& e) {
2456             ERR("%s\n", e.what());
2457             device->handleDisconnect("%s", e.what());
2458             return ALC_INVALID_DEVICE;
2459         }
2460         TRACE("Post-start: %s, %s, %uhz, %u / %u buffer\n",
2461             DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
2462             device->Frequency, device->UpdateSize, device->BufferSize);
2463     }
2464
2465     return ALC_NO_ERROR;
2466 }
2467
2468 /**
2469  * Updates device parameters as above, and also first clears the disconnected
2470  * status, if set.
2471  */
2472 bool ResetDeviceParams(ALCdevice *device, const int *attrList)
2473 {
2474     /* If the device was disconnected, reset it since we're opened anew. */
2475     if(!device->Connected.load(std::memory_order_relaxed)) UNLIKELY
2476     {
2477         /* Make sure disconnection is finished before continuing on. */
2478         device->waitForMix();
2479
2480         for(ContextBase *ctxbase : *device->mContexts.load(std::memory_order_acquire))
2481         {
2482             auto *ctx = static_cast<ALCcontext*>(ctxbase);
2483             if(!ctx->mStopVoicesOnDisconnect.load(std::memory_order_acquire))
2484                 continue;
2485
2486             /* Clear any pending voice changes and reallocate voices to get a
2487              * clean restart.
2488              */
2489             std::lock_guard<std::mutex> __{ctx->mSourceLock};
2490             auto *vchg = ctx->mCurrentVoiceChange.load(std::memory_order_acquire);
2491             while(auto *next = vchg->mNext.load(std::memory_order_acquire))
2492                 vchg = next;
2493             ctx->mCurrentVoiceChange.store(vchg, std::memory_order_release);
2494
2495             ctx->mVoicePropClusters.clear();
2496             ctx->mFreeVoiceProps.store(nullptr, std::memory_order_relaxed);
2497
2498             ctx->mVoiceClusters.clear();
2499             ctx->allocVoices(std::max<size_t>(256,
2500                 ctx->mActiveVoiceCount.load(std::memory_order_relaxed)));
2501         }
2502
2503         device->Connected.store(true);
2504     }
2505
2506     ALCenum err{UpdateDeviceParams(device, attrList)};
2507     if(err == ALC_NO_ERROR) LIKELY return ALC_TRUE;
2508
2509     alcSetError(device, err);
2510     return ALC_FALSE;
2511 }
2512
2513
2514 /** Checks if the device handle is valid, and returns a new reference if so. */
2515 DeviceRef VerifyDevice(ALCdevice *device)
2516 {
2517     std::lock_guard<std::recursive_mutex> _{ListLock};
2518     auto iter = std::lower_bound(DeviceList.begin(), DeviceList.end(), device);
2519     if(iter != DeviceList.end() && *iter == device)
2520     {
2521         (*iter)->add_ref();
2522         return DeviceRef{*iter};
2523     }
2524     return nullptr;
2525 }
2526
2527
2528 /**
2529  * Checks if the given context is valid, returning a new reference to it if so.
2530  */
2531 ContextRef VerifyContext(ALCcontext *context)
2532 {
2533     std::lock_guard<std::recursive_mutex> _{ListLock};
2534     auto iter = std::lower_bound(ContextList.begin(), ContextList.end(), context);
2535     if(iter != ContextList.end() && *iter == context)
2536     {
2537         (*iter)->add_ref();
2538         return ContextRef{*iter};
2539     }
2540     return nullptr;
2541 }
2542
2543 } // namespace
2544
2545 /** Returns a new reference to the currently active context for this thread. */
2546 ContextRef GetContextRef(void)
2547 {
2548     ALCcontext *context{ALCcontext::getThreadContext()};
2549     if(context)
2550         context->add_ref();
2551     else
2552     {
2553         while(ALCcontext::sGlobalContextLock.exchange(true, std::memory_order_acquire)) {
2554             /* Wait to make sure another thread isn't trying to change the
2555              * current context and bring its refcount to 0.
2556              */
2557         }
2558         context = ALCcontext::sGlobalContext.load(std::memory_order_acquire);
2559         if(context) LIKELY context->add_ref();
2560         ALCcontext::sGlobalContextLock.store(false, std::memory_order_release);
2561     }
2562     return ContextRef{context};
2563 }
2564
2565
2566 /************************************************
2567  * Standard ALC functions
2568  ************************************************/
2569
2570 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2571 START_API_FUNC
2572 {
2573     DeviceRef dev{VerifyDevice(device)};
2574     if(dev) return dev->LastError.exchange(ALC_NO_ERROR);
2575     return LastNullDeviceError.exchange(ALC_NO_ERROR);
2576 }
2577 END_API_FUNC
2578
2579
2580 ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context)
2581 START_API_FUNC
2582 {
2583     if(!SuspendDefers)
2584         return;
2585
2586     ContextRef ctx{VerifyContext(context)};
2587     if(!ctx)
2588         alcSetError(nullptr, ALC_INVALID_CONTEXT);
2589     else
2590     {
2591         std::lock_guard<std::mutex> _{ctx->mPropLock};
2592         ctx->deferUpdates();
2593     }
2594 }
2595 END_API_FUNC
2596
2597 ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context)
2598 START_API_FUNC
2599 {
2600     if(!SuspendDefers)
2601         return;
2602
2603     ContextRef ctx{VerifyContext(context)};
2604     if(!ctx)
2605         alcSetError(nullptr, ALC_INVALID_CONTEXT);
2606     else
2607     {
2608         std::lock_guard<std::mutex> _{ctx->mPropLock};
2609         ctx->processUpdates();
2610     }
2611 }
2612 END_API_FUNC
2613
2614
2615 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2616 START_API_FUNC
2617 {
2618     const ALCchar *value{nullptr};
2619
2620     switch(param)
2621     {
2622     case ALC_NO_ERROR:
2623         value = alcNoError;
2624         break;
2625
2626     case ALC_INVALID_ENUM:
2627         value = alcErrInvalidEnum;
2628         break;
2629
2630     case ALC_INVALID_VALUE:
2631         value = alcErrInvalidValue;
2632         break;
2633
2634     case ALC_INVALID_DEVICE:
2635         value = alcErrInvalidDevice;
2636         break;
2637
2638     case ALC_INVALID_CONTEXT:
2639         value = alcErrInvalidContext;
2640         break;
2641
2642     case ALC_OUT_OF_MEMORY:
2643         value = alcErrOutOfMemory;
2644         break;
2645
2646     case ALC_DEVICE_SPECIFIER:
2647         value = alcDefaultName;
2648         break;
2649
2650     case ALC_ALL_DEVICES_SPECIFIER:
2651         if(DeviceRef dev{VerifyDevice(Device)})
2652         {
2653             if(dev->Type == DeviceType::Capture)
2654                 alcSetError(dev.get(), ALC_INVALID_ENUM);
2655             else if(dev->Type == DeviceType::Loopback)
2656                 value = alcDefaultName;
2657             else
2658             {
2659                 std::lock_guard<std::mutex> _{dev->StateLock};
2660                 value = dev->DeviceName.c_str();
2661             }
2662         }
2663         else
2664         {
2665             ProbeAllDevicesList();
2666             value = alcAllDevicesList.c_str();
2667         }
2668         break;
2669
2670     case ALC_CAPTURE_DEVICE_SPECIFIER:
2671         if(DeviceRef dev{VerifyDevice(Device)})
2672         {
2673             if(dev->Type != DeviceType::Capture)
2674                 alcSetError(dev.get(), ALC_INVALID_ENUM);
2675             else
2676             {
2677                 std::lock_guard<std::mutex> _{dev->StateLock};
2678                 value = dev->DeviceName.c_str();
2679             }
2680         }
2681         else
2682         {
2683             ProbeCaptureDeviceList();
2684             value = alcCaptureDeviceList.c_str();
2685         }
2686         break;
2687
2688     /* Default devices are always first in the list */
2689     case ALC_DEFAULT_DEVICE_SPECIFIER:
2690         value = alcDefaultName;
2691         break;
2692
2693     case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2694         if(alcAllDevicesList.empty())
2695             ProbeAllDevicesList();
2696
2697         /* Copy first entry as default. */
2698         alcDefaultAllDevicesSpecifier = alcAllDevicesList.c_str();
2699         value = alcDefaultAllDevicesSpecifier.c_str();
2700         break;
2701
2702     case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2703         if(alcCaptureDeviceList.empty())
2704             ProbeCaptureDeviceList();
2705
2706         /* Copy first entry as default. */
2707         alcCaptureDefaultDeviceSpecifier = alcCaptureDeviceList.c_str();
2708         value = alcCaptureDefaultDeviceSpecifier.c_str();
2709         break;
2710
2711     case ALC_EXTENSIONS:
2712         if(VerifyDevice(Device))
2713             value = alcExtensionList;
2714         else
2715             value = alcNoDeviceExtList;
2716         break;
2717
2718     case ALC_HRTF_SPECIFIER_SOFT:
2719         if(DeviceRef dev{VerifyDevice(Device)})
2720         {
2721             std::lock_guard<std::mutex> _{dev->StateLock};
2722             value = (dev->mHrtf ? dev->mHrtfName.c_str() : "");
2723         }
2724         else
2725             alcSetError(nullptr, ALC_INVALID_DEVICE);
2726         break;
2727
2728     default:
2729         alcSetError(VerifyDevice(Device).get(), ALC_INVALID_ENUM);
2730         break;
2731     }
2732
2733     return value;
2734 }
2735 END_API_FUNC
2736
2737
2738 static size_t GetIntegerv(ALCdevice *device, ALCenum param, const al::span<int> values)
2739 {
2740     size_t i;
2741
2742     if(values.empty())
2743     {
2744         alcSetError(device, ALC_INVALID_VALUE);
2745         return 0;
2746     }
2747
2748     if(!device)
2749     {
2750         switch(param)
2751         {
2752         case ALC_MAJOR_VERSION:
2753             values[0] = alcMajorVersion;
2754             return 1;
2755         case ALC_MINOR_VERSION:
2756             values[0] = alcMinorVersion;
2757             return 1;
2758
2759         case ALC_EFX_MAJOR_VERSION:
2760             values[0] = alcEFXMajorVersion;
2761             return 1;
2762         case ALC_EFX_MINOR_VERSION:
2763             values[0] = alcEFXMinorVersion;
2764             return 1;
2765         case ALC_MAX_AUXILIARY_SENDS:
2766             values[0] = MAX_SENDS;
2767             return 1;
2768
2769         case ALC_ATTRIBUTES_SIZE:
2770         case ALC_ALL_ATTRIBUTES:
2771         case ALC_FREQUENCY:
2772         case ALC_REFRESH:
2773         case ALC_SYNC:
2774         case ALC_MONO_SOURCES:
2775         case ALC_STEREO_SOURCES:
2776         case ALC_CAPTURE_SAMPLES:
2777         case ALC_FORMAT_CHANNELS_SOFT:
2778         case ALC_FORMAT_TYPE_SOFT:
2779         case ALC_AMBISONIC_LAYOUT_SOFT:
2780         case ALC_AMBISONIC_SCALING_SOFT:
2781         case ALC_AMBISONIC_ORDER_SOFT:
2782         case ALC_MAX_AMBISONIC_ORDER_SOFT:
2783             alcSetError(nullptr, ALC_INVALID_DEVICE);
2784             return 0;
2785
2786         default:
2787             alcSetError(nullptr, ALC_INVALID_ENUM);
2788         }
2789         return 0;
2790     }
2791
2792     std::lock_guard<std::mutex> _{device->StateLock};
2793     if(device->Type == DeviceType::Capture)
2794     {
2795         static constexpr int MaxCaptureAttributes{9};
2796         switch(param)
2797         {
2798         case ALC_ATTRIBUTES_SIZE:
2799             values[0] = MaxCaptureAttributes;
2800             return 1;
2801         case ALC_ALL_ATTRIBUTES:
2802             i = 0;
2803             if(values.size() < MaxCaptureAttributes)
2804                 alcSetError(device, ALC_INVALID_VALUE);
2805             else
2806             {
2807                 values[i++] = ALC_MAJOR_VERSION;
2808                 values[i++] = alcMajorVersion;
2809                 values[i++] = ALC_MINOR_VERSION;
2810                 values[i++] = alcMinorVersion;
2811                 values[i++] = ALC_CAPTURE_SAMPLES;
2812                 values[i++] = static_cast<int>(device->Backend->availableSamples());
2813                 values[i++] = ALC_CONNECTED;
2814                 values[i++] = device->Connected.load(std::memory_order_relaxed);
2815                 values[i++] = 0;
2816                 assert(i == MaxCaptureAttributes);
2817             }
2818             return i;
2819
2820         case ALC_MAJOR_VERSION:
2821             values[0] = alcMajorVersion;
2822             return 1;
2823         case ALC_MINOR_VERSION:
2824             values[0] = alcMinorVersion;
2825             return 1;
2826
2827         case ALC_CAPTURE_SAMPLES:
2828             values[0] = static_cast<int>(device->Backend->availableSamples());
2829             return 1;
2830
2831         case ALC_CONNECTED:
2832             values[0] = device->Connected.load(std::memory_order_acquire);
2833             return 1;
2834
2835         default:
2836             alcSetError(device, ALC_INVALID_ENUM);
2837         }
2838         return 0;
2839     }
2840
2841     /* render device */
2842     auto NumAttrsForDevice = [](ALCdevice *aldev) noexcept
2843     {
2844         if(aldev->Type == DeviceType::Loopback && aldev->FmtChans == DevFmtAmbi3D)
2845             return 37;
2846         return 31;
2847     };
2848     switch(param)
2849     {
2850     case ALC_ATTRIBUTES_SIZE:
2851         values[0] = NumAttrsForDevice(device);
2852         return 1;
2853
2854     case ALC_ALL_ATTRIBUTES:
2855         i = 0;
2856         if(values.size() < static_cast<size_t>(NumAttrsForDevice(device)))
2857             alcSetError(device, ALC_INVALID_VALUE);
2858         else
2859         {
2860             values[i++] = ALC_MAJOR_VERSION;
2861             values[i++] = alcMajorVersion;
2862             values[i++] = ALC_MINOR_VERSION;
2863             values[i++] = alcMinorVersion;
2864             values[i++] = ALC_EFX_MAJOR_VERSION;
2865             values[i++] = alcEFXMajorVersion;
2866             values[i++] = ALC_EFX_MINOR_VERSION;
2867             values[i++] = alcEFXMinorVersion;
2868
2869             values[i++] = ALC_FREQUENCY;
2870             values[i++] = static_cast<int>(device->Frequency);
2871             if(device->Type != DeviceType::Loopback)
2872             {
2873                 values[i++] = ALC_REFRESH;
2874                 values[i++] = static_cast<int>(device->Frequency / device->UpdateSize);
2875
2876                 values[i++] = ALC_SYNC;
2877                 values[i++] = ALC_FALSE;
2878             }
2879             else
2880             {
2881                 if(device->FmtChans == DevFmtAmbi3D)
2882                 {
2883                     values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
2884                     values[i++] = EnumFromDevAmbi(device->mAmbiLayout);
2885
2886                     values[i++] = ALC_AMBISONIC_SCALING_SOFT;
2887                     values[i++] = EnumFromDevAmbi(device->mAmbiScale);
2888
2889                     values[i++] = ALC_AMBISONIC_ORDER_SOFT;
2890                     values[i++] = static_cast<int>(device->mAmbiOrder);
2891                 }
2892
2893                 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2894                 values[i++] = EnumFromDevFmt(device->FmtChans);
2895
2896                 values[i++] = ALC_FORMAT_TYPE_SOFT;
2897                 values[i++] = EnumFromDevFmt(device->FmtType);
2898             }
2899
2900             values[i++] = ALC_MONO_SOURCES;
2901             values[i++] = static_cast<int>(device->NumMonoSources);
2902
2903             values[i++] = ALC_STEREO_SOURCES;
2904             values[i++] = static_cast<int>(device->NumStereoSources);
2905
2906             values[i++] = ALC_MAX_AUXILIARY_SENDS;
2907             values[i++] = static_cast<int>(device->NumAuxSends);
2908
2909             values[i++] = ALC_HRTF_SOFT;
2910             values[i++] = (device->mHrtf ? ALC_TRUE : ALC_FALSE);
2911
2912             values[i++] = ALC_HRTF_STATUS_SOFT;
2913             values[i++] = device->mHrtfStatus;
2914
2915             values[i++] = ALC_OUTPUT_LIMITER_SOFT;
2916             values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
2917
2918             values[i++] = ALC_MAX_AMBISONIC_ORDER_SOFT;
2919             values[i++] = MaxAmbiOrder;
2920
2921             values[i++] = ALC_OUTPUT_MODE_SOFT;
2922             values[i++] = static_cast<ALCenum>(device->getOutputMode1());
2923
2924             values[i++] = 0;
2925         }
2926         return i;
2927
2928     case ALC_MAJOR_VERSION:
2929         values[0] = alcMajorVersion;
2930         return 1;
2931
2932     case ALC_MINOR_VERSION:
2933         values[0] = alcMinorVersion;
2934         return 1;
2935
2936     case ALC_EFX_MAJOR_VERSION:
2937         values[0] = alcEFXMajorVersion;
2938         return 1;
2939
2940     case ALC_EFX_MINOR_VERSION:
2941         values[0] = alcEFXMinorVersion;
2942         return 1;
2943
2944     case ALC_FREQUENCY:
2945         values[0] = static_cast<int>(device->Frequency);
2946         return 1;
2947
2948     case ALC_REFRESH:
2949         if(device->Type == DeviceType::Loopback)
2950         {
2951             alcSetError(device, ALC_INVALID_DEVICE);
2952             return 0;
2953         }
2954         values[0] = static_cast<int>(device->Frequency / device->UpdateSize);
2955         return 1;
2956
2957     case ALC_SYNC:
2958         if(device->Type == DeviceType::Loopback)
2959         {
2960             alcSetError(device, ALC_INVALID_DEVICE);
2961             return 0;
2962         }
2963         values[0] = ALC_FALSE;
2964         return 1;
2965
2966     case ALC_FORMAT_CHANNELS_SOFT:
2967         if(device->Type != DeviceType::Loopback)
2968         {
2969             alcSetError(device, ALC_INVALID_DEVICE);
2970             return 0;
2971         }
2972         values[0] = EnumFromDevFmt(device->FmtChans);
2973         return 1;
2974
2975     case ALC_FORMAT_TYPE_SOFT:
2976         if(device->Type != DeviceType::Loopback)
2977         {
2978             alcSetError(device, ALC_INVALID_DEVICE);
2979             return 0;
2980         }
2981         values[0] = EnumFromDevFmt(device->FmtType);
2982         return 1;
2983
2984     case ALC_AMBISONIC_LAYOUT_SOFT:
2985         if(device->Type != DeviceType::Loopback || device->FmtChans != DevFmtAmbi3D)
2986         {
2987             alcSetError(device, ALC_INVALID_DEVICE);
2988             return 0;
2989         }
2990         values[0] = EnumFromDevAmbi(device->mAmbiLayout);
2991         return 1;
2992
2993     case ALC_AMBISONIC_SCALING_SOFT:
2994         if(device->Type != DeviceType::Loopback || device->FmtChans != DevFmtAmbi3D)
2995         {
2996             alcSetError(device, ALC_INVALID_DEVICE);
2997             return 0;
2998         }
2999         values[0] = EnumFromDevAmbi(device->mAmbiScale);
3000         return 1;
3001
3002     case ALC_AMBISONIC_ORDER_SOFT:
3003         if(device->Type != DeviceType::Loopback || device->FmtChans != DevFmtAmbi3D)
3004         {
3005             alcSetError(device, ALC_INVALID_DEVICE);
3006             return 0;
3007         }
3008         values[0] = static_cast<int>(device->mAmbiOrder);
3009         return 1;
3010
3011     case ALC_MONO_SOURCES:
3012         values[0] = static_cast<int>(device->NumMonoSources);
3013         return 1;
3014
3015     case ALC_STEREO_SOURCES:
3016         values[0] = static_cast<int>(device->NumStereoSources);
3017         return 1;
3018
3019     case ALC_MAX_AUXILIARY_SENDS:
3020         values[0] = static_cast<int>(device->NumAuxSends);
3021         return 1;
3022
3023     case ALC_CONNECTED:
3024         values[0] = device->Connected.load(std::memory_order_acquire);
3025         return 1;
3026
3027     case ALC_HRTF_SOFT:
3028         values[0] = (device->mHrtf ? ALC_TRUE : ALC_FALSE);
3029         return 1;
3030
3031     case ALC_HRTF_STATUS_SOFT:
3032         values[0] = device->mHrtfStatus;
3033         return 1;
3034
3035     case ALC_NUM_HRTF_SPECIFIERS_SOFT:
3036         device->enumerateHrtfs();
3037         values[0] = static_cast<int>(minz(device->mHrtfList.size(),
3038             std::numeric_limits<int>::max()));
3039         return 1;
3040
3041     case ALC_OUTPUT_LIMITER_SOFT:
3042         values[0] = device->Limiter ? ALC_TRUE : ALC_FALSE;
3043         return 1;
3044
3045     case ALC_MAX_AMBISONIC_ORDER_SOFT:
3046         values[0] = MaxAmbiOrder;
3047         return 1;
3048
3049     case ALC_OUTPUT_MODE_SOFT:
3050         values[0] = static_cast<ALCenum>(device->getOutputMode1());
3051         return 1;
3052
3053     default:
3054         alcSetError(device, ALC_INVALID_ENUM);
3055     }
3056     return 0;
3057 }
3058
3059 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
3060 START_API_FUNC
3061 {
3062     DeviceRef dev{VerifyDevice(device)};
3063     if(size <= 0 || values == nullptr)
3064         alcSetError(dev.get(), ALC_INVALID_VALUE);
3065     else
3066         GetIntegerv(dev.get(), param, {values, static_cast<uint>(size)});
3067 }
3068 END_API_FUNC
3069
3070 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
3071 START_API_FUNC
3072 {
3073     DeviceRef dev{VerifyDevice(device)};
3074     if(size <= 0 || values == nullptr)
3075     {
3076         alcSetError(dev.get(), ALC_INVALID_VALUE);
3077         return;
3078     }
3079     if(!dev || dev->Type == DeviceType::Capture)
3080     {
3081         auto ivals = al::vector<int>(static_cast<uint>(size));
3082         if(size_t got{GetIntegerv(dev.get(), pname, ivals)})
3083             std::copy_n(ivals.begin(), got, values);
3084         return;
3085     }
3086     /* render device */
3087     auto NumAttrsForDevice = [](ALCdevice *aldev) noexcept
3088     {
3089         if(aldev->Type == DeviceType::Loopback && aldev->FmtChans == DevFmtAmbi3D)
3090             return 41;
3091         return 35;
3092     };
3093     std::lock_guard<std::mutex> _{dev->StateLock};
3094     switch(pname)
3095     {
3096     case ALC_ATTRIBUTES_SIZE:
3097         *values = NumAttrsForDevice(dev.get());
3098         break;
3099
3100     case ALC_ALL_ATTRIBUTES:
3101         if(size < NumAttrsForDevice(dev.get()))
3102             alcSetError(dev.get(), ALC_INVALID_VALUE);
3103         else
3104         {
3105             size_t i{0};
3106             values[i++] = ALC_FREQUENCY;
3107             values[i++] = dev->Frequency;
3108
3109             if(dev->Type != DeviceType::Loopback)
3110             {
3111                 values[i++] = ALC_REFRESH;
3112                 values[i++] = dev->Frequency / dev->UpdateSize;
3113
3114                 values[i++] = ALC_SYNC;
3115                 values[i++] = ALC_FALSE;
3116             }
3117             else
3118             {
3119                 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
3120                 values[i++] = EnumFromDevFmt(dev->FmtChans);
3121
3122                 values[i++] = ALC_FORMAT_TYPE_SOFT;
3123                 values[i++] = EnumFromDevFmt(dev->FmtType);
3124
3125                 if(dev->FmtChans == DevFmtAmbi3D)
3126                 {
3127                     values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
3128                     values[i++] = EnumFromDevAmbi(dev->mAmbiLayout);
3129
3130                     values[i++] = ALC_AMBISONIC_SCALING_SOFT;
3131                     values[i++] = EnumFromDevAmbi(dev->mAmbiScale);
3132
3133                     values[i++] = ALC_AMBISONIC_ORDER_SOFT;
3134                     values[i++] = dev->mAmbiOrder;
3135                 }
3136             }
3137
3138             values[i++] = ALC_MONO_SOURCES;
3139             values[i++] = dev->NumMonoSources;
3140
3141             values[i++] = ALC_STEREO_SOURCES;
3142             values[i++] = dev->NumStereoSources;
3143
3144             values[i++] = ALC_MAX_AUXILIARY_SENDS;
3145             values[i++] = dev->NumAuxSends;
3146
3147             values[i++] = ALC_HRTF_SOFT;
3148             values[i++] = (dev->mHrtf ? ALC_TRUE : ALC_FALSE);
3149
3150             values[i++] = ALC_HRTF_STATUS_SOFT;
3151             values[i++] = dev->mHrtfStatus;
3152
3153             values[i++] = ALC_OUTPUT_LIMITER_SOFT;
3154             values[i++] = dev->Limiter ? ALC_TRUE : ALC_FALSE;
3155
3156             ClockLatency clock{GetClockLatency(dev.get(), dev->Backend.get())};
3157             values[i++] = ALC_DEVICE_CLOCK_SOFT;
3158             values[i++] = clock.ClockTime.count();
3159
3160             values[i++] = ALC_DEVICE_LATENCY_SOFT;
3161             values[i++] = clock.Latency.count();
3162
3163             values[i++] = ALC_OUTPUT_MODE_SOFT;
3164             values[i++] = static_cast<ALCenum>(device->getOutputMode1());
3165
3166             values[i++] = 0;
3167         }
3168         break;
3169
3170     case ALC_DEVICE_CLOCK_SOFT:
3171         {
3172             uint samplecount, refcount;
3173             nanoseconds basecount;
3174             do {
3175                 refcount = dev->waitForMix();
3176                 basecount = dev->ClockBase;
3177                 samplecount = dev->SamplesDone;
3178             } while(refcount != ReadRef(dev->MixCount));
3179             basecount += nanoseconds{seconds{samplecount}} / dev->Frequency;
3180             *values = basecount.count();
3181         }
3182         break;
3183
3184     case ALC_DEVICE_LATENCY_SOFT:
3185         *values = GetClockLatency(dev.get(), dev->Backend.get()).Latency.count();
3186         break;
3187
3188     case ALC_DEVICE_CLOCK_LATENCY_SOFT:
3189         if(size < 2)
3190             alcSetError(dev.get(), ALC_INVALID_VALUE);
3191         else
3192         {
3193             ClockLatency clock{GetClockLatency(dev.get(), dev->Backend.get())};
3194             values[0] = clock.ClockTime.count();
3195             values[1] = clock.Latency.count();
3196         }
3197         break;
3198
3199     default:
3200         auto ivals = al::vector<int>(static_cast<uint>(size));
3201         if(size_t got{GetIntegerv(dev.get(), pname, ivals)})
3202             std::copy_n(ivals.begin(), got, values);
3203         break;
3204     }
3205 }
3206 END_API_FUNC
3207
3208
3209 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
3210 START_API_FUNC
3211 {
3212     DeviceRef dev{VerifyDevice(device)};
3213     if(!extName)
3214         alcSetError(dev.get(), ALC_INVALID_VALUE);
3215     else
3216     {
3217         size_t len = strlen(extName);
3218         const char *ptr = (dev ? alcExtensionList : alcNoDeviceExtList);
3219         while(ptr && *ptr)
3220         {
3221             if(al::strncasecmp(ptr, extName, len) == 0 && (ptr[len] == '\0' || isspace(ptr[len])))
3222                 return ALC_TRUE;
3223
3224             if((ptr=strchr(ptr, ' ')) != nullptr)
3225             {
3226                 do {
3227                     ++ptr;
3228                 } while(isspace(*ptr));
3229             }
3230         }
3231     }
3232     return ALC_FALSE;
3233 }
3234 END_API_FUNC
3235
3236
3237 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
3238 START_API_FUNC
3239 {
3240     if(!funcName)
3241     {
3242         DeviceRef dev{VerifyDevice(device)};
3243         alcSetError(dev.get(), ALC_INVALID_VALUE);
3244         return nullptr;
3245     }
3246 #ifdef ALSOFT_EAX
3247     if(eax_g_is_enabled)
3248     {
3249         for(const auto &func : eaxFunctions)
3250         {
3251             if(strcmp(func.funcName, funcName) == 0)
3252                 return func.address;
3253         }
3254     }
3255 #endif
3256     for(const auto &func : alcFunctions)
3257     {
3258         if(strcmp(func.funcName, funcName) == 0)
3259             return func.address;
3260     }
3261     return nullptr;
3262 }
3263 END_API_FUNC
3264
3265
3266 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
3267 START_API_FUNC
3268 {
3269     if(!enumName)
3270     {
3271         DeviceRef dev{VerifyDevice(device)};
3272         alcSetError(dev.get(), ALC_INVALID_VALUE);
3273         return 0;
3274     }
3275 #ifdef ALSOFT_EAX
3276     if(eax_g_is_enabled)
3277     {
3278         for(const auto &enm : eaxEnumerations)
3279         {
3280             if(strcmp(enm.enumName, enumName) == 0)
3281                 return enm.value;
3282         }
3283     }
3284 #endif
3285     for(const auto &enm : alcEnumerations)
3286     {
3287         if(strcmp(enm.enumName, enumName) == 0)
3288             return enm.value;
3289     }
3290
3291     return 0;
3292 }
3293 END_API_FUNC
3294
3295
3296 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
3297 START_API_FUNC
3298 {
3299     /* Explicitly hold the list lock while taking the StateLock in case the
3300      * device is asynchronously destroyed, to ensure this new context is
3301      * properly cleaned up after being made.
3302      */
3303     std::unique_lock<std::recursive_mutex> listlock{ListLock};
3304     DeviceRef dev{VerifyDevice(device)};
3305     if(!dev || dev->Type == DeviceType::Capture || !dev->Connected.load(std::memory_order_relaxed))
3306     {
3307         listlock.unlock();
3308         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3309         return nullptr;
3310     }
3311     std::unique_lock<std::mutex> statelock{dev->StateLock};
3312     listlock.unlock();
3313
3314     dev->LastError.store(ALC_NO_ERROR);
3315
3316     ALCenum err{UpdateDeviceParams(dev.get(), attrList)};
3317     if(err != ALC_NO_ERROR)
3318     {
3319         alcSetError(dev.get(), err);
3320         return nullptr;
3321     }
3322
3323     ContextRef context{new ALCcontext{dev}};
3324     context->init();
3325
3326     if(auto volopt = dev->configValue<float>(nullptr, "volume-adjust"))
3327     {
3328         const float valf{*volopt};
3329         if(!std::isfinite(valf))
3330             ERR("volume-adjust must be finite: %f\n", valf);
3331         else
3332         {
3333             const float db{clampf(valf, -24.0f, 24.0f)};
3334             if(db != valf)
3335                 WARN("volume-adjust clamped: %f, range: +/-%f\n", valf, 24.0f);
3336             context->mGainBoost = std::pow(10.0f, db/20.0f);
3337             TRACE("volume-adjust gain: %f\n", context->mGainBoost);
3338         }
3339     }
3340
3341     {
3342         using ContextArray = al::FlexArray<ContextBase*>;
3343
3344         /* Allocate a new context array, which holds 1 more than the current/
3345          * old array.
3346          */
3347         auto *oldarray = device->mContexts.load();
3348         const size_t newcount{oldarray->size()+1};
3349         std::unique_ptr<ContextArray> newarray{ContextArray::Create(newcount)};
3350
3351         /* Copy the current/old context handles to the new array, appending the
3352          * new context.
3353          */
3354         auto iter = std::copy(oldarray->begin(), oldarray->end(), newarray->begin());
3355         *iter = context.get();
3356
3357         /* Store the new context array in the device. Wait for any current mix
3358          * to finish before deleting the old array.
3359          */
3360         dev->mContexts.store(newarray.release());
3361         if(oldarray != &DeviceBase::sEmptyContextArray)
3362         {
3363             dev->waitForMix();
3364             delete oldarray;
3365         }
3366     }
3367     statelock.unlock();
3368
3369     {
3370         std::lock_guard<std::recursive_mutex> _{ListLock};
3371         auto iter = std::lower_bound(ContextList.cbegin(), ContextList.cend(), context.get());
3372         ContextList.emplace(iter, context.get());
3373     }
3374
3375     if(ALeffectslot *slot{context->mDefaultSlot.get()})
3376     {
3377         ALenum sloterr{slot->initEffect(ALCcontext::sDefaultEffect.type,
3378             ALCcontext::sDefaultEffect.Props, context.get())};
3379         if(sloterr == AL_NO_ERROR)
3380             slot->updateProps(context.get());
3381         else
3382             ERR("Failed to initialize the default effect\n");
3383     }
3384
3385     TRACE("Created context %p\n", voidp{context.get()});
3386     return context.release();
3387 }
3388 END_API_FUNC
3389
3390 ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context)
3391 START_API_FUNC
3392 {
3393     std::unique_lock<std::recursive_mutex> listlock{ListLock};
3394     auto iter = std::lower_bound(ContextList.begin(), ContextList.end(), context);
3395     if(iter == ContextList.end() || *iter != context)
3396     {
3397         listlock.unlock();
3398         alcSetError(nullptr, ALC_INVALID_CONTEXT);
3399         return;
3400     }
3401
3402     /* Hold a reference to this context so it remains valid until the ListLock
3403      * is released.
3404      */
3405     ContextRef ctx{*iter};
3406     ContextList.erase(iter);
3407
3408     ALCdevice *Device{ctx->mALDevice.get()};
3409
3410     std::lock_guard<std::mutex> _{Device->StateLock};
3411     if(!ctx->deinit() && Device->Flags.test(DeviceRunning))
3412     {
3413         Device->Backend->stop();
3414         Device->Flags.reset(DeviceRunning);
3415     }
3416 }
3417 END_API_FUNC
3418
3419
3420 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
3421 START_API_FUNC
3422 {
3423     ALCcontext *Context{ALCcontext::getThreadContext()};
3424     if(!Context) Context = ALCcontext::sGlobalContext.load();
3425     return Context;
3426 }
3427 END_API_FUNC
3428
3429 /** Returns the currently active thread-local context. */
3430 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
3431 START_API_FUNC
3432 { return ALCcontext::getThreadContext(); }
3433 END_API_FUNC
3434
3435 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
3436 START_API_FUNC
3437 {
3438     /* context must be valid or nullptr */
3439     ContextRef ctx;
3440     if(context)
3441     {
3442         ctx = VerifyContext(context);
3443         if(!ctx)
3444         {
3445             alcSetError(nullptr, ALC_INVALID_CONTEXT);
3446             return ALC_FALSE;
3447         }
3448     }
3449     /* Release this reference (if any) to store it in the GlobalContext
3450      * pointer. Take ownership of the reference (if any) that was previously
3451      * stored there, and let the reference go.
3452      */
3453     while(ALCcontext::sGlobalContextLock.exchange(true, std::memory_order_acquire)) {
3454         /* Wait to make sure another thread isn't getting or trying to change
3455          * the current context as its refcount is decremented.
3456          */
3457     }
3458     ContextRef{ALCcontext::sGlobalContext.exchange(ctx.release())};
3459     ALCcontext::sGlobalContextLock.store(false, std::memory_order_release);
3460
3461     /* Take ownership of the thread-local context reference (if any), clearing
3462      * the storage to null.
3463      */
3464     ctx = ContextRef{ALCcontext::getThreadContext()};
3465     if(ctx) ALCcontext::setThreadContext(nullptr);
3466     /* Reset (decrement) the previous thread-local reference. */
3467
3468     return ALC_TRUE;
3469 }
3470 END_API_FUNC
3471
3472 /** Makes the given context the active context for the current thread. */
3473 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3474 START_API_FUNC
3475 {
3476     /* context must be valid or nullptr */
3477     ContextRef ctx;
3478     if(context)
3479     {
3480         ctx = VerifyContext(context);
3481         if(!ctx)
3482         {
3483             alcSetError(nullptr, ALC_INVALID_CONTEXT);
3484             return ALC_FALSE;
3485         }
3486     }
3487     /* context's reference count is already incremented */
3488     ContextRef old{ALCcontext::getThreadContext()};
3489     ALCcontext::setThreadContext(ctx.release());
3490
3491     return ALC_TRUE;
3492 }
3493 END_API_FUNC
3494
3495
3496 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3497 START_API_FUNC
3498 {
3499     ContextRef ctx{VerifyContext(Context)};
3500     if(!ctx)
3501     {
3502         alcSetError(nullptr, ALC_INVALID_CONTEXT);
3503         return nullptr;
3504     }
3505     return ctx->mALDevice.get();
3506 }
3507 END_API_FUNC
3508
3509
3510 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3511 START_API_FUNC
3512 {
3513     InitConfig();
3514
3515     if(!PlaybackFactory)
3516     {
3517         alcSetError(nullptr, ALC_INVALID_VALUE);
3518         return nullptr;
3519     }
3520
3521     if(deviceName)
3522     {
3523         TRACE("Opening playback device \"%s\"\n", deviceName);
3524         if(!deviceName[0] || al::strcasecmp(deviceName, alcDefaultName) == 0
3525 #ifdef _WIN32
3526             /* Some old Windows apps hardcode these expecting OpenAL to use a
3527              * specific audio API, even when they're not enumerated. Creative's
3528              * router effectively ignores them too.
3529              */
3530             || al::strcasecmp(deviceName, "DirectSound3D") == 0
3531             || al::strcasecmp(deviceName, "DirectSound") == 0
3532             || al::strcasecmp(deviceName, "MMSYSTEM") == 0
3533 #endif
3534             /* Some old Linux apps hardcode configuration strings that were
3535              * supported by the OpenAL SI. We can't really do anything useful
3536              * with them, so just ignore.
3537              */
3538             || (deviceName[0] == '\'' && deviceName[1] == '(')
3539             || al::strcasecmp(deviceName, "openal-soft") == 0)
3540             deviceName = nullptr;
3541     }
3542     else
3543         TRACE("Opening default playback device\n");
3544
3545     const uint DefaultSends{
3546 #ifdef ALSOFT_EAX
3547         eax_g_is_enabled ? uint{EAX_MAX_FXSLOTS} :
3548 #endif // ALSOFT_EAX
3549         DEFAULT_SENDS
3550     };
3551
3552     DeviceRef device{new ALCdevice{DeviceType::Playback}};
3553
3554     /* Set output format */
3555     device->FmtChans = DevFmtChannelsDefault;
3556     device->FmtType = DevFmtTypeDefault;
3557     device->Frequency = DEFAULT_OUTPUT_RATE;
3558     device->UpdateSize = DEFAULT_UPDATE_SIZE;
3559     device->BufferSize = DEFAULT_UPDATE_SIZE * DEFAULT_NUM_UPDATES;
3560
3561     device->SourcesMax = 256;
3562     device->NumStereoSources = 1;
3563     device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
3564     device->AuxiliaryEffectSlotMax = 64;
3565     device->NumAuxSends = DefaultSends;
3566
3567     try {
3568         auto backend = PlaybackFactory->createBackend(device.get(), BackendType::Playback);
3569         std::lock_guard<std::recursive_mutex> _{ListLock};
3570         backend->open(deviceName);
3571         device->Backend = std::move(backend);
3572     }
3573     catch(al::backend_exception &e) {
3574         WARN("Failed to open playback device: %s\n", e.what());
3575         alcSetError(nullptr, (e.errorCode() == al::backend_error::OutOfMemory)
3576             ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE);
3577         return nullptr;
3578     }
3579
3580     {
3581         std::lock_guard<std::recursive_mutex> _{ListLock};
3582         auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
3583         DeviceList.emplace(iter, device.get());
3584     }
3585
3586     TRACE("Created device %p, \"%s\"\n", voidp{device.get()}, device->DeviceName.c_str());
3587     return device.release();
3588 }
3589 END_API_FUNC
3590
3591 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
3592 START_API_FUNC
3593 {
3594     std::unique_lock<std::recursive_mutex> listlock{ListLock};
3595     auto iter = std::lower_bound(DeviceList.begin(), DeviceList.end(), device);
3596     if(iter == DeviceList.end() || *iter != device)
3597     {
3598         alcSetError(nullptr, ALC_INVALID_DEVICE);
3599         return ALC_FALSE;
3600     }
3601     if((*iter)->Type == DeviceType::Capture)
3602     {
3603         alcSetError(*iter, ALC_INVALID_DEVICE);
3604         return ALC_FALSE;
3605     }
3606
3607     /* Erase the device, and any remaining contexts left on it, from their
3608      * respective lists.
3609      */
3610     DeviceRef dev{*iter};
3611     DeviceList.erase(iter);
3612
3613     std::unique_lock<std::mutex> statelock{dev->StateLock};
3614     al::vector<ContextRef> orphanctxs;
3615     for(ContextBase *ctx : *dev->mContexts.load())
3616     {
3617         auto ctxiter = std::lower_bound(ContextList.begin(), ContextList.end(), ctx);
3618         if(ctxiter != ContextList.end() && *ctxiter == ctx)
3619         {
3620             orphanctxs.emplace_back(ContextRef{*ctxiter});
3621             ContextList.erase(ctxiter);
3622         }
3623     }
3624     listlock.unlock();
3625
3626     for(ContextRef &context : orphanctxs)
3627     {
3628         WARN("Releasing orphaned context %p\n", voidp{context.get()});
3629         context->deinit();
3630     }
3631     orphanctxs.clear();
3632
3633     if(dev->Flags.test(DeviceRunning))
3634         dev->Backend->stop();
3635     dev->Flags.reset(DeviceRunning);
3636
3637     return ALC_TRUE;
3638 }
3639 END_API_FUNC
3640
3641
3642 /************************************************
3643  * ALC capture functions
3644  ************************************************/
3645 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3646 START_API_FUNC
3647 {
3648     InitConfig();
3649
3650     if(!CaptureFactory)
3651     {
3652         alcSetError(nullptr, ALC_INVALID_VALUE);
3653         return nullptr;
3654     }
3655
3656     if(samples <= 0)
3657     {
3658         alcSetError(nullptr, ALC_INVALID_VALUE);
3659         return nullptr;
3660     }
3661
3662     if(deviceName)
3663     {
3664         TRACE("Opening capture device \"%s\"\n", deviceName);
3665         if(!deviceName[0] || al::strcasecmp(deviceName, alcDefaultName) == 0
3666             || al::strcasecmp(deviceName, "openal-soft") == 0)
3667             deviceName = nullptr;
3668     }
3669     else
3670         TRACE("Opening default capture device\n");
3671
3672     DeviceRef device{new ALCdevice{DeviceType::Capture}};
3673
3674     auto decompfmt = DecomposeDevFormat(format);
3675     if(!decompfmt)
3676     {
3677         alcSetError(nullptr, ALC_INVALID_ENUM);
3678         return nullptr;
3679     }
3680
3681     device->Frequency = frequency;
3682     device->FmtChans = decompfmt->chans;
3683     device->FmtType = decompfmt->type;
3684     device->Flags.set(FrequencyRequest);
3685     device->Flags.set(ChannelsRequest);
3686     device->Flags.set(SampleTypeRequest);
3687
3688     device->UpdateSize = static_cast<uint>(samples);
3689     device->BufferSize = static_cast<uint>(samples);
3690
3691     try {
3692         TRACE("Capture format: %s, %s, %uhz, %u / %u buffer\n",
3693             DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
3694             device->Frequency, device->UpdateSize, device->BufferSize);
3695
3696         auto backend = CaptureFactory->createBackend(device.get(), BackendType::Capture);
3697         std::lock_guard<std::recursive_mutex> _{ListLock};
3698         backend->open(deviceName);
3699         device->Backend = std::move(backend);
3700     }
3701     catch(al::backend_exception &e) {
3702         WARN("Failed to open capture device: %s\n", e.what());
3703         alcSetError(nullptr, (e.errorCode() == al::backend_error::OutOfMemory)
3704             ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE);
3705         return nullptr;
3706     }
3707
3708     {
3709         std::lock_guard<std::recursive_mutex> _{ListLock};
3710         auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
3711         DeviceList.emplace(iter, device.get());
3712     }
3713
3714     TRACE("Created capture device %p, \"%s\"\n", voidp{device.get()}, device->DeviceName.c_str());
3715     return device.release();
3716 }
3717 END_API_FUNC
3718
3719 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
3720 START_API_FUNC
3721 {
3722     std::unique_lock<std::recursive_mutex> listlock{ListLock};
3723     auto iter = std::lower_bound(DeviceList.begin(), DeviceList.end(), device);
3724     if(iter == DeviceList.end() || *iter != device)
3725     {
3726         alcSetError(nullptr, ALC_INVALID_DEVICE);
3727         return ALC_FALSE;
3728     }
3729     if((*iter)->Type != DeviceType::Capture)
3730     {
3731         alcSetError(*iter, ALC_INVALID_DEVICE);
3732         return ALC_FALSE;
3733     }
3734
3735     DeviceRef dev{*iter};
3736     DeviceList.erase(iter);
3737     listlock.unlock();
3738
3739     std::lock_guard<std::mutex> _{dev->StateLock};
3740     if(dev->Flags.test(DeviceRunning))
3741         dev->Backend->stop();
3742     dev->Flags.reset(DeviceRunning);
3743
3744     return ALC_TRUE;
3745 }
3746 END_API_FUNC
3747
3748 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3749 START_API_FUNC
3750 {
3751     DeviceRef dev{VerifyDevice(device)};
3752     if(!dev || dev->Type != DeviceType::Capture)
3753     {
3754         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3755         return;
3756     }
3757
3758     std::lock_guard<std::mutex> _{dev->StateLock};
3759     if(!dev->Connected.load(std::memory_order_acquire))
3760         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3761     else if(!dev->Flags.test(DeviceRunning))
3762     {
3763         try {
3764             auto backend = dev->Backend.get();
3765             backend->start();
3766             dev->Flags.set(DeviceRunning);
3767         }
3768         catch(al::backend_exception& e) {
3769             ERR("%s\n", e.what());
3770             dev->handleDisconnect("%s", e.what());
3771             alcSetError(dev.get(), ALC_INVALID_DEVICE);
3772         }
3773     }
3774 }
3775 END_API_FUNC
3776
3777 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3778 START_API_FUNC
3779 {
3780     DeviceRef dev{VerifyDevice(device)};
3781     if(!dev || dev->Type != DeviceType::Capture)
3782         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3783     else
3784     {
3785         std::lock_guard<std::mutex> _{dev->StateLock};
3786         if(dev->Flags.test(DeviceRunning))
3787             dev->Backend->stop();
3788         dev->Flags.reset(DeviceRunning);
3789     }
3790 }
3791 END_API_FUNC
3792
3793 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3794 START_API_FUNC
3795 {
3796     DeviceRef dev{VerifyDevice(device)};
3797     if(!dev || dev->Type != DeviceType::Capture)
3798     {
3799         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3800         return;
3801     }
3802
3803     if(samples < 0 || (samples > 0 && buffer == nullptr))
3804     {
3805         alcSetError(dev.get(), ALC_INVALID_VALUE);
3806         return;
3807     }
3808     if(samples < 1)
3809         return;
3810
3811     std::lock_guard<std::mutex> _{dev->StateLock};
3812     BackendBase *backend{dev->Backend.get()};
3813
3814     const auto usamples = static_cast<uint>(samples);
3815     if(usamples > backend->availableSamples())
3816     {
3817         alcSetError(dev.get(), ALC_INVALID_VALUE);
3818         return;
3819     }
3820
3821     backend->captureSamples(static_cast<al::byte*>(buffer), usamples);
3822 }
3823 END_API_FUNC
3824
3825
3826 /************************************************
3827  * ALC loopback functions
3828  ************************************************/
3829
3830 /** Open a loopback device, for manual rendering. */
3831 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3832 START_API_FUNC
3833 {
3834     InitConfig();
3835
3836     /* Make sure the device name, if specified, is us. */
3837     if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3838     {
3839         alcSetError(nullptr, ALC_INVALID_VALUE);
3840         return nullptr;
3841     }
3842
3843     const uint DefaultSends{
3844 #ifdef ALSOFT_EAX
3845         eax_g_is_enabled ? uint{EAX_MAX_FXSLOTS} :
3846 #endif // ALSOFT_EAX
3847         DEFAULT_SENDS
3848     };
3849
3850     DeviceRef device{new ALCdevice{DeviceType::Loopback}};
3851
3852     device->SourcesMax = 256;
3853     device->AuxiliaryEffectSlotMax = 64;
3854     device->NumAuxSends = DefaultSends;
3855
3856     //Set output format
3857     device->BufferSize = 0;
3858     device->UpdateSize = 0;
3859
3860     device->Frequency = DEFAULT_OUTPUT_RATE;
3861     device->FmtChans = DevFmtChannelsDefault;
3862     device->FmtType = DevFmtTypeDefault;
3863
3864     device->NumStereoSources = 1;
3865     device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
3866
3867     try {
3868         auto backend = LoopbackBackendFactory::getFactory().createBackend(device.get(),
3869             BackendType::Playback);
3870         backend->open("Loopback");
3871         device->Backend = std::move(backend);
3872     }
3873     catch(al::backend_exception &e) {
3874         WARN("Failed to open loopback device: %s\n", e.what());
3875         alcSetError(nullptr, (e.errorCode() == al::backend_error::OutOfMemory)
3876             ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE);
3877         return nullptr;
3878     }
3879
3880     {
3881         std::lock_guard<std::recursive_mutex> _{ListLock};
3882         auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
3883         DeviceList.emplace(iter, device.get());
3884     }
3885
3886     TRACE("Created loopback device %p\n", voidp{device.get()});
3887     return device.release();
3888 }
3889 END_API_FUNC
3890
3891 /**
3892  * Determines if the loopback device supports the given format for rendering.
3893  */
3894 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3895 START_API_FUNC
3896 {
3897     DeviceRef dev{VerifyDevice(device)};
3898     if(!dev || dev->Type != DeviceType::Loopback)
3899         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3900     else if(freq <= 0)
3901         alcSetError(dev.get(), ALC_INVALID_VALUE);
3902     else
3903     {
3904         if(DevFmtTypeFromEnum(type).has_value() && DevFmtChannelsFromEnum(channels).has_value()
3905             && freq >= MIN_OUTPUT_RATE && freq <= MAX_OUTPUT_RATE)
3906             return ALC_TRUE;
3907     }
3908
3909     return ALC_FALSE;
3910 }
3911 END_API_FUNC
3912
3913 /**
3914  * Renders some samples into a buffer, using the format last set by the
3915  * attributes given to alcCreateContext.
3916  */
3917 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3918 START_API_FUNC
3919 {
3920     if(!device || device->Type != DeviceType::Loopback)
3921         alcSetError(device, ALC_INVALID_DEVICE);
3922     else if(samples < 0 || (samples > 0 && buffer == nullptr))
3923         alcSetError(device, ALC_INVALID_VALUE);
3924     else
3925         device->renderSamples(buffer, static_cast<uint>(samples), device->channelsFromFmt());
3926 }
3927 END_API_FUNC
3928
3929
3930 /************************************************
3931  * ALC DSP pause/resume functions
3932  ************************************************/
3933
3934 /** Pause the DSP to stop audio processing. */
3935 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3936 START_API_FUNC
3937 {
3938     DeviceRef dev{VerifyDevice(device)};
3939     if(!dev || dev->Type != DeviceType::Playback)
3940         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3941     else
3942     {
3943         std::lock_guard<std::mutex> _{dev->StateLock};
3944         if(dev->Flags.test(DeviceRunning))
3945             dev->Backend->stop();
3946         dev->Flags.reset(DeviceRunning);
3947         dev->Flags.set(DevicePaused);
3948     }
3949 }
3950 END_API_FUNC
3951
3952 /** Resume the DSP to restart audio processing. */
3953 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3954 START_API_FUNC
3955 {
3956     DeviceRef dev{VerifyDevice(device)};
3957     if(!dev || dev->Type != DeviceType::Playback)
3958     {
3959         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3960         return;
3961     }
3962
3963     std::lock_guard<std::mutex> _{dev->StateLock};
3964     if(!dev->Flags.test(DevicePaused))
3965         return;
3966     dev->Flags.reset(DevicePaused);
3967     if(dev->mContexts.load()->empty())
3968         return;
3969
3970     try {
3971         auto backend = dev->Backend.get();
3972         backend->start();
3973         dev->Flags.set(DeviceRunning);
3974     }
3975     catch(al::backend_exception& e) {
3976         ERR("%s\n", e.what());
3977         dev->handleDisconnect("%s", e.what());
3978         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3979         return;
3980     }
3981     TRACE("Post-resume: %s, %s, %uhz, %u / %u buffer\n",
3982         DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
3983         device->Frequency, device->UpdateSize, device->BufferSize);
3984 }
3985 END_API_FUNC
3986
3987
3988 /************************************************
3989  * ALC HRTF functions
3990  ************************************************/
3991
3992 /** Gets a string parameter at the given index. */
3993 ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
3994 START_API_FUNC
3995 {
3996     DeviceRef dev{VerifyDevice(device)};
3997     if(!dev || dev->Type == DeviceType::Capture)
3998         alcSetError(dev.get(), ALC_INVALID_DEVICE);
3999     else switch(paramName)
4000     {
4001         case ALC_HRTF_SPECIFIER_SOFT:
4002             if(index >= 0 && static_cast<uint>(index) < dev->mHrtfList.size())
4003                 return dev->mHrtfList[static_cast<uint>(index)].c_str();
4004             alcSetError(dev.get(), ALC_INVALID_VALUE);
4005             break;
4006
4007         default:
4008             alcSetError(dev.get(), ALC_INVALID_ENUM);
4009             break;
4010     }
4011
4012     return nullptr;
4013 }
4014 END_API_FUNC
4015
4016 /** Resets the given device output, using the specified attribute list. */
4017 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
4018 START_API_FUNC
4019 {
4020     std::unique_lock<std::recursive_mutex> listlock{ListLock};
4021     DeviceRef dev{VerifyDevice(device)};
4022     if(!dev || dev->Type == DeviceType::Capture)
4023     {
4024         listlock.unlock();
4025         alcSetError(dev.get(), ALC_INVALID_DEVICE);
4026         return ALC_FALSE;
4027     }
4028     std::lock_guard<std::mutex> _{dev->StateLock};
4029     listlock.unlock();
4030
4031     /* Force the backend to stop mixing first since we're resetting. Also reset
4032      * the connected state so lost devices can attempt recover.
4033      */
4034     if(dev->Flags.test(DeviceRunning))
4035         dev->Backend->stop();
4036     dev->Flags.reset(DeviceRunning);
4037
4038     return ResetDeviceParams(dev.get(), attribs) ? ALC_TRUE : ALC_FALSE;
4039 }
4040 END_API_FUNC
4041
4042
4043 /************************************************
4044  * ALC device reopen functions
4045  ************************************************/
4046
4047 /** Reopens the given device output, using the specified name and attribute list. */
4048 FORCE_ALIGN ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device,
4049     const ALCchar *deviceName, const ALCint *attribs)
4050 START_API_FUNC
4051 {
4052     if(deviceName)
4053     {
4054         if(!deviceName[0] || al::strcasecmp(deviceName, alcDefaultName) == 0)
4055             deviceName = nullptr;
4056     }
4057
4058     std::unique_lock<std::recursive_mutex> listlock{ListLock};
4059     DeviceRef dev{VerifyDevice(device)};
4060     if(!dev || dev->Type != DeviceType::Playback)
4061     {
4062         listlock.unlock();
4063         alcSetError(dev.get(), ALC_INVALID_DEVICE);
4064         return ALC_FALSE;
4065     }
4066     std::lock_guard<std::mutex> _{dev->StateLock};
4067
4068     /* Force the backend to stop mixing first since we're reopening. */
4069     if(dev->Flags.test(DeviceRunning))
4070     {
4071         auto backend = dev->Backend.get();
4072         backend->stop();
4073         dev->Flags.reset(DeviceRunning);
4074     }
4075
4076     BackendPtr newbackend;
4077     try {
4078         newbackend = PlaybackFactory->createBackend(dev.get(), BackendType::Playback);
4079         newbackend->open(deviceName);
4080     }
4081     catch(al::backend_exception &e) {
4082         listlock.unlock();
4083         newbackend = nullptr;
4084
4085         WARN("Failed to reopen playback device: %s\n", e.what());
4086         alcSetError(dev.get(), (e.errorCode() == al::backend_error::OutOfMemory)
4087             ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE);
4088
4089         /* If the device is connected, not paused, and has contexts, ensure it
4090          * continues playing.
4091          */
4092         if(dev->Connected.load(std::memory_order_relaxed) && !dev->Flags.test(DevicePaused)
4093             && !dev->mContexts.load(std::memory_order_relaxed)->empty())
4094         {
4095             try {
4096                 auto backend = dev->Backend.get();
4097                 backend->start();
4098                 dev->Flags.set(DeviceRunning);
4099             }
4100             catch(al::backend_exception &be) {
4101                 ERR("%s\n", be.what());
4102                 dev->handleDisconnect("%s", be.what());
4103             }
4104         }
4105         return ALC_FALSE;
4106     }
4107     listlock.unlock();
4108     dev->Backend = std::move(newbackend);
4109     TRACE("Reopened device %p, \"%s\"\n", voidp{dev.get()}, dev->DeviceName.c_str());
4110
4111     /* Always return true even if resetting fails. It shouldn't fail, but this
4112      * is primarily to avoid confusion by the app seeing the function return
4113      * false while the device is on the new output anyway. We could try to
4114      * restore the old backend if this fails, but the configuration would be
4115      * changed with the new backend and would need to be reset again with the
4116      * old one, and the provided attributes may not be appropriate or desirable
4117      * for the old device.
4118      *
4119      * In this way, we essentially act as if the function succeeded, but
4120      * immediately disconnects following it.
4121      */
4122     ResetDeviceParams(dev.get(), attribs);
4123     return ALC_TRUE;
4124 }
4125 END_API_FUNC