🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4001 lines
122 KiB

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